mirror of
https://github.com/283375/arcaea-offline-ocr.git
synced 2025-07-01 20:36:27 +00:00
Compare commits
2 Commits
0d8e4dea8e
...
c009a28f92
Author | SHA1 | Date | |
---|---|---|---|
c009a28f92
|
|||
d5ccbd5a01
|
@ -1,3 +0,0 @@
|
||||
from .common import DeviceAutoRoiSizes
|
||||
from .t1 import DeviceAutoRoiSizesT1
|
||||
from .t2 import DeviceAutoRoiSizesT2
|
@ -1,7 +0,0 @@
|
||||
from ..common import DeviceRoiSizes
|
||||
|
||||
|
||||
class DeviceAutoRoiSizes(DeviceRoiSizes):
|
||||
def __init__(self, w: int, h: int):
|
||||
self.w = w
|
||||
self.h = h
|
@ -1,123 +0,0 @@
|
||||
from .common import DeviceAutoRoiSizes
|
||||
|
||||
|
||||
class DeviceAutoRoiSizesT1(DeviceAutoRoiSizes):
|
||||
@property
|
||||
def factor(self):
|
||||
return (
|
||||
((self.w / 16) * 9) / 720 if (self.w / self.h) < (16 / 9) else self.h / 720
|
||||
)
|
||||
|
||||
@property
|
||||
def w_mid(self):
|
||||
return self.w / 2
|
||||
|
||||
@property
|
||||
def h_mid(self):
|
||||
return self.h / 2
|
||||
|
||||
@property
|
||||
def top_bar(self):
|
||||
return (0, 0, self.w, 50 * self.factor)
|
||||
|
||||
@property
|
||||
def layout_area_h_mid(self):
|
||||
return self.h / 2 + self.top_bar[3]
|
||||
|
||||
@property
|
||||
def pfl_left_from_w_mid(self):
|
||||
return 5 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_x(self):
|
||||
return self.w_mid + self.pfl_left_from_w_mid
|
||||
|
||||
@property
|
||||
def pfl_w(self):
|
||||
return 76 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_h(self):
|
||||
return 26 * self.factor
|
||||
|
||||
@property
|
||||
def pure(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.layout_area_h_mid + 110 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def far(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.pure[1] + self.pure[3] + 12 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def lost(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.far[1] + self.far[3] + 10 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def score(self):
|
||||
w = 280 * self.factor
|
||||
h = 45 * self.factor
|
||||
return (
|
||||
self.w_mid - w / 2,
|
||||
self.layout_area_h_mid - 75 * self.factor - h,
|
||||
w,
|
||||
h,
|
||||
)
|
||||
|
||||
@property
|
||||
def rating_class(self):
|
||||
return (
|
||||
self.w_mid - 610 * self.factor,
|
||||
self.layout_area_h_mid - 180 * self.factor,
|
||||
265 * self.factor,
|
||||
35 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def max_recall(self):
|
||||
return (
|
||||
self.w_mid - 465 * self.factor,
|
||||
self.layout_area_h_mid - 215 * self.factor,
|
||||
150 * self.factor,
|
||||
35 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def jacket(self):
|
||||
return (
|
||||
self.w_mid - 610 * self.factor,
|
||||
self.layout_area_h_mid - 143 * self.factor,
|
||||
375 * self.factor,
|
||||
375 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def clear_status(self):
|
||||
w = 550 * self.factor
|
||||
h = 60 * self.factor
|
||||
return (
|
||||
self.w_mid - w / 2,
|
||||
self.layout_area_h_mid - 155 * self.factor - h,
|
||||
w,
|
||||
h,
|
||||
)
|
||||
|
||||
@property
|
||||
def partner_icon(self):
|
||||
w = 90 * self.factor
|
||||
h = 75 * self.factor
|
||||
return (self.w_mid - w / 2, 0, w, h)
|
@ -1,125 +0,0 @@
|
||||
from .common import DeviceAutoRoiSizes
|
||||
|
||||
|
||||
class DeviceAutoRoiSizesT2(DeviceAutoRoiSizes):
|
||||
@property
|
||||
def factor(self):
|
||||
return (
|
||||
((self.w / 16) * 9) / 1080
|
||||
if (self.w / self.h) < (16 / 9)
|
||||
else self.h / 1080
|
||||
)
|
||||
|
||||
@property
|
||||
def w_mid(self):
|
||||
return self.w / 2
|
||||
|
||||
@property
|
||||
def h_mid(self):
|
||||
return self.h / 2
|
||||
|
||||
@property
|
||||
def top_bar(self):
|
||||
return (0, 0, self.w, 75 * self.factor)
|
||||
|
||||
@property
|
||||
def layout_area_h_mid(self):
|
||||
return self.h / 2 + self.top_bar[3]
|
||||
|
||||
@property
|
||||
def pfl_mid_from_w_mid(self):
|
||||
return 60 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_x(self):
|
||||
return self.w_mid + 10 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_w(self):
|
||||
return 100 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_h(self):
|
||||
return 24 * self.factor
|
||||
|
||||
@property
|
||||
def pure(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.layout_area_h_mid + 175 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def far(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.pure[1] + self.pure[3] + 30 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def lost(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.far[1] + self.far[3] + 35 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def score(self):
|
||||
w = 420 * self.factor
|
||||
h = 70 * self.factor
|
||||
return (
|
||||
self.w_mid - w / 2,
|
||||
self.layout_area_h_mid - 110 * self.factor - h,
|
||||
w,
|
||||
h,
|
||||
)
|
||||
|
||||
@property
|
||||
def rating_class(self):
|
||||
return (
|
||||
max(0, self.w_mid - 965 * self.factor),
|
||||
self.layout_area_h_mid - 330 * self.factor,
|
||||
350 * self.factor,
|
||||
110 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def max_recall(self):
|
||||
return (
|
||||
self.w_mid - 625 * self.factor,
|
||||
self.layout_area_h_mid - 275 * self.factor,
|
||||
150 * self.factor,
|
||||
50 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def jacket(self):
|
||||
return (
|
||||
self.w_mid - 915 * self.factor,
|
||||
self.layout_area_h_mid - 215 * self.factor,
|
||||
565 * self.factor,
|
||||
565 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def clear_status(self):
|
||||
w = 825 * self.factor
|
||||
h = 90 * self.factor
|
||||
return (
|
||||
self.w_mid - w / 2,
|
||||
self.layout_area_h_mid - 235 * self.factor - h,
|
||||
w,
|
||||
h,
|
||||
)
|
||||
|
||||
@property
|
||||
def partner_icon(self):
|
||||
w = 135 * self.factor
|
||||
h = 110 * self.factor
|
||||
return (self.w_mid - w / 2, 0, w, h)
|
@ -1 +0,0 @@
|
||||
from .common import DeviceRoiExtractor
|
@ -1,2 +0,0 @@
|
||||
from .auto import *
|
||||
from .common import DeviceRoiMasker
|
@ -1,3 +0,0 @@
|
||||
from .common import DeviceAutoRoiMasker
|
||||
from .t1 import DeviceAutoRoiMaskerT1
|
||||
from .t2 import DeviceAutoRoiMaskerT2
|
@ -1,5 +0,0 @@
|
||||
from ..common import DeviceRoiMasker
|
||||
|
||||
|
||||
class DeviceAutoRoiMasker(DeviceRoiMasker):
|
||||
...
|
@ -1,123 +0,0 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from .common import DeviceAutoRoiMasker
|
||||
|
||||
GRAY_BGR_MIN = np.array([50] * 3, np.uint8)
|
||||
GRAY_BGR_MAX = np.array([160] * 3, np.uint8)
|
||||
|
||||
WHITE_HSV_MIN = np.array([0, 0, 240], np.uint8)
|
||||
WHITE_HSV_MAX = np.array([179, 10, 255], np.uint8)
|
||||
|
||||
PST_HSV_MIN = np.array([100, 50, 80], np.uint8)
|
||||
PST_HSV_MAX = np.array([100, 255, 255], np.uint8)
|
||||
|
||||
PRS_HSV_MIN = np.array([43, 40, 75], np.uint8)
|
||||
PRS_HSV_MAX = np.array([50, 155, 190], np.uint8)
|
||||
|
||||
FTR_HSV_MIN = np.array([149, 30, 0], np.uint8)
|
||||
FTR_HSV_MAX = np.array([155, 181, 150], np.uint8)
|
||||
|
||||
BYD_HSV_MIN = np.array([170, 50, 50], np.uint8)
|
||||
BYD_HSV_MAX = np.array([179, 210, 198], np.uint8)
|
||||
|
||||
TRACK_LOST_HSV_MIN = np.array([170, 75, 90], np.uint8)
|
||||
TRACK_LOST_HSV_MAX = np.array([175, 170, 160], np.uint8)
|
||||
|
||||
TRACK_COMPLETE_HSV_MIN = np.array([140, 0, 50], np.uint8)
|
||||
TRACK_COMPLETE_HSV_MAX = np.array([145, 50, 130], np.uint8)
|
||||
|
||||
FULL_RECALL_HSV_MIN = np.array([140, 60, 80], np.uint8)
|
||||
FULL_RECALL_HSV_MAX = np.array([150, 130, 145], np.uint8)
|
||||
|
||||
PURE_MEMORY_HSV_MIN = np.array([90, 70, 80], np.uint8)
|
||||
PURE_MEMORY_HSV_MAX = np.array([110, 200, 175], np.uint8)
|
||||
|
||||
|
||||
class DeviceAutoRoiMaskerT1(DeviceAutoRoiMasker):
|
||||
@classmethod
|
||||
def gray(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
bgr_value_equal_mask = np.max(roi_bgr, axis=2) - np.min(roi_bgr, axis=2) <= 5
|
||||
img_bgr = roi_bgr.copy()
|
||||
img_bgr[~bgr_value_equal_mask] = np.array([0, 0, 0], roi_bgr.dtype)
|
||||
img_bgr = cv2.erode(img_bgr, cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)))
|
||||
img_bgr = cv2.dilate(img_bgr, cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1)))
|
||||
return cv2.inRange(img_bgr, GRAY_BGR_MIN, GRAY_BGR_MAX)
|
||||
|
||||
@classmethod
|
||||
def pure(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.gray(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def far(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.gray(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def lost(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.gray(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def score(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), WHITE_HSV_MIN, WHITE_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_pst(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), PST_HSV_MIN, PST_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_prs(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), PRS_HSV_MIN, PRS_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_ftr(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), FTR_HSV_MIN, FTR_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_byd(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), BYD_HSV_MIN, BYD_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def max_recall(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.gray(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def clear_status_track_lost(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
TRACK_LOST_HSV_MIN,
|
||||
TRACK_LOST_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_track_complete(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
TRACK_COMPLETE_HSV_MIN,
|
||||
TRACK_COMPLETE_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_full_recall(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
FULL_RECALL_HSV_MIN,
|
||||
FULL_RECALL_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_pure_memory(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
PURE_MEMORY_HSV_MIN,
|
||||
PURE_MEMORY_HSV_MAX,
|
||||
)
|
@ -1,128 +0,0 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from .common import DeviceAutoRoiMasker
|
||||
|
||||
PFL_HSV_MIN = np.array([0, 0, 248], np.uint8)
|
||||
PFL_HSV_MAX = np.array([179, 10, 255], np.uint8)
|
||||
|
||||
WHITE_HSV_MIN = np.array([0, 0, 240], np.uint8)
|
||||
WHITE_HSV_MAX = np.array([179, 10, 255], np.uint8)
|
||||
|
||||
|
||||
PST_HSV_MIN = np.array([100, 50, 80], np.uint8)
|
||||
PST_HSV_MAX = np.array([100, 255, 255], np.uint8)
|
||||
|
||||
PRS_HSV_MIN = np.array([43, 40, 75], np.uint8)
|
||||
PRS_HSV_MAX = np.array([50, 155, 190], np.uint8)
|
||||
|
||||
FTR_HSV_MIN = np.array([149, 30, 0], np.uint8)
|
||||
FTR_HSV_MAX = np.array([155, 181, 150], np.uint8)
|
||||
|
||||
BYD_HSV_MIN = np.array([170, 50, 50], np.uint8)
|
||||
BYD_HSV_MAX = np.array([179, 210, 198], np.uint8)
|
||||
|
||||
MAX_RECALL_HSV_MIN = np.array([125, 0, 0], np.uint8)
|
||||
MAX_RECALL_HSV_MAX = np.array([130, 100, 150], np.uint8)
|
||||
|
||||
TRACK_LOST_HSV_MIN = np.array([170, 75, 90], np.uint8)
|
||||
TRACK_LOST_HSV_MAX = np.array([175, 170, 160], np.uint8)
|
||||
|
||||
TRACK_COMPLETE_HSV_MIN = np.array([140, 0, 50], np.uint8)
|
||||
TRACK_COMPLETE_HSV_MAX = np.array([145, 50, 130], np.uint8)
|
||||
|
||||
FULL_RECALL_HSV_MIN = np.array([140, 60, 80], np.uint8)
|
||||
FULL_RECALL_HSV_MAX = np.array([150, 130, 145], np.uint8)
|
||||
|
||||
PURE_MEMORY_HSV_MIN = np.array([90, 70, 80], np.uint8)
|
||||
PURE_MEMORY_HSV_MAX = np.array([110, 200, 175], np.uint8)
|
||||
|
||||
|
||||
class DeviceAutoRoiMaskerT2(DeviceAutoRoiMasker):
|
||||
@classmethod
|
||||
def pfl(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), PFL_HSV_MIN, PFL_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def pure(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.pfl(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def far(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.pfl(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def lost(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.pfl(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def score(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), WHITE_HSV_MIN, WHITE_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_pst(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), PST_HSV_MIN, PST_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_prs(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), PRS_HSV_MIN, PRS_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_ftr(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), FTR_HSV_MIN, FTR_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_byd(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), BYD_HSV_MIN, BYD_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def max_recall(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
MAX_RECALL_HSV_MIN,
|
||||
MAX_RECALL_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_track_lost(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
TRACK_LOST_HSV_MIN,
|
||||
TRACK_LOST_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_track_complete(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
TRACK_COMPLETE_HSV_MIN,
|
||||
TRACK_COMPLETE_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_full_recall(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
FULL_RECALL_HSV_MIN,
|
||||
FULL_RECALL_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_pure_memory(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
PURE_MEMORY_HSV_MIN,
|
||||
PURE_MEMORY_HSV_MAX,
|
||||
)
|
255
src/arcaea_offline_ocr/device/rois/definition/auto.py
Normal file
255
src/arcaea_offline_ocr/device/rois/definition/auto.py
Normal file
@ -0,0 +1,255 @@
|
||||
from .common import DeviceRois
|
||||
|
||||
__all__ = ["DeviceRoisAuto", "DeviceRoisAutoT1", "DeviceRoisAutoT2"]
|
||||
|
||||
|
||||
class DeviceRoisAuto(DeviceRois):
|
||||
def __init__(self, w: int, h: int):
|
||||
self.w = w
|
||||
self.h = h
|
||||
|
||||
|
||||
class DeviceRoisAutoT1(DeviceRoisAuto):
|
||||
@property
|
||||
def factor(self):
|
||||
return (
|
||||
((self.w / 16) * 9) / 720 if (self.w / self.h) < (16 / 9) else self.h / 720
|
||||
)
|
||||
|
||||
@property
|
||||
def w_mid(self):
|
||||
return self.w / 2
|
||||
|
||||
@property
|
||||
def h_mid(self):
|
||||
return self.h / 2
|
||||
|
||||
@property
|
||||
def top_bar(self):
|
||||
return (0, 0, self.w, 50 * self.factor)
|
||||
|
||||
@property
|
||||
def layout_area_h_mid(self):
|
||||
return self.h / 2 + self.top_bar[3]
|
||||
|
||||
@property
|
||||
def pfl_left_from_w_mid(self):
|
||||
return 5 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_x(self):
|
||||
return self.w_mid + self.pfl_left_from_w_mid
|
||||
|
||||
@property
|
||||
def pfl_w(self):
|
||||
return 76 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_h(self):
|
||||
return 26 * self.factor
|
||||
|
||||
@property
|
||||
def pure(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.layout_area_h_mid + 110 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def far(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.pure[1] + self.pure[3] + 12 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def lost(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.far[1] + self.far[3] + 10 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def score(self):
|
||||
w = 280 * self.factor
|
||||
h = 45 * self.factor
|
||||
return (
|
||||
self.w_mid - w / 2,
|
||||
self.layout_area_h_mid - 75 * self.factor - h,
|
||||
w,
|
||||
h,
|
||||
)
|
||||
|
||||
@property
|
||||
def rating_class(self):
|
||||
return (
|
||||
self.w_mid - 610 * self.factor,
|
||||
self.layout_area_h_mid - 180 * self.factor,
|
||||
265 * self.factor,
|
||||
35 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def max_recall(self):
|
||||
return (
|
||||
self.w_mid - 465 * self.factor,
|
||||
self.layout_area_h_mid - 215 * self.factor,
|
||||
150 * self.factor,
|
||||
35 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def jacket(self):
|
||||
return (
|
||||
self.w_mid - 610 * self.factor,
|
||||
self.layout_area_h_mid - 143 * self.factor,
|
||||
375 * self.factor,
|
||||
375 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def clear_status(self):
|
||||
w = 550 * self.factor
|
||||
h = 60 * self.factor
|
||||
return (
|
||||
self.w_mid - w / 2,
|
||||
self.layout_area_h_mid - 155 * self.factor - h,
|
||||
w,
|
||||
h,
|
||||
)
|
||||
|
||||
@property
|
||||
def partner_icon(self):
|
||||
w = 90 * self.factor
|
||||
h = 75 * self.factor
|
||||
return (self.w_mid - w / 2, 0, w, h)
|
||||
|
||||
|
||||
class DeviceRoisAutoT2(DeviceRoisAuto):
|
||||
@property
|
||||
def factor(self):
|
||||
return (
|
||||
((self.w / 16) * 9) / 1080
|
||||
if (self.w / self.h) < (16 / 9)
|
||||
else self.h / 1080
|
||||
)
|
||||
|
||||
@property
|
||||
def w_mid(self):
|
||||
return self.w / 2
|
||||
|
||||
@property
|
||||
def h_mid(self):
|
||||
return self.h / 2
|
||||
|
||||
@property
|
||||
def top_bar(self):
|
||||
return (0, 0, self.w, 75 * self.factor)
|
||||
|
||||
@property
|
||||
def layout_area_h_mid(self):
|
||||
return self.h / 2 + self.top_bar[3]
|
||||
|
||||
@property
|
||||
def pfl_mid_from_w_mid(self):
|
||||
return 60 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_x(self):
|
||||
return self.w_mid + 10 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_w(self):
|
||||
return 100 * self.factor
|
||||
|
||||
@property
|
||||
def pfl_h(self):
|
||||
return 24 * self.factor
|
||||
|
||||
@property
|
||||
def pure(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.layout_area_h_mid + 175 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def far(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.pure[1] + self.pure[3] + 30 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def lost(self):
|
||||
return (
|
||||
self.pfl_x,
|
||||
self.far[1] + self.far[3] + 35 * self.factor,
|
||||
self.pfl_w,
|
||||
self.pfl_h,
|
||||
)
|
||||
|
||||
@property
|
||||
def score(self):
|
||||
w = 420 * self.factor
|
||||
h = 70 * self.factor
|
||||
return (
|
||||
self.w_mid - w / 2,
|
||||
self.layout_area_h_mid - 110 * self.factor - h,
|
||||
w,
|
||||
h,
|
||||
)
|
||||
|
||||
@property
|
||||
def rating_class(self):
|
||||
return (
|
||||
max(0, self.w_mid - 965 * self.factor),
|
||||
self.layout_area_h_mid - 330 * self.factor,
|
||||
350 * self.factor,
|
||||
110 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def max_recall(self):
|
||||
return (
|
||||
self.w_mid - 625 * self.factor,
|
||||
self.layout_area_h_mid - 275 * self.factor,
|
||||
150 * self.factor,
|
||||
50 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def jacket(self):
|
||||
return (
|
||||
self.w_mid - 915 * self.factor,
|
||||
self.layout_area_h_mid - 215 * self.factor,
|
||||
565 * self.factor,
|
||||
565 * self.factor,
|
||||
)
|
||||
|
||||
@property
|
||||
def clear_status(self):
|
||||
w = 825 * self.factor
|
||||
h = 90 * self.factor
|
||||
return (
|
||||
self.w_mid - w / 2,
|
||||
self.layout_area_h_mid - 235 * self.factor - h,
|
||||
w,
|
||||
h,
|
||||
)
|
||||
|
||||
@property
|
||||
def partner_icon(self):
|
||||
w = 135 * self.factor
|
||||
h = 110 * self.factor
|
||||
return (self.w_mid - w / 2, 0, w, h)
|
@ -3,7 +3,7 @@ from typing import Tuple
|
||||
Rect = Tuple[int, int, int, int]
|
||||
|
||||
|
||||
class DeviceRoiSizes:
|
||||
class DeviceRois:
|
||||
pure: Rect
|
||||
far: Rect
|
||||
lost: Rect
|
1
src/arcaea_offline_ocr/device/rois/extractor/__init__.py
Normal file
1
src/arcaea_offline_ocr/device/rois/extractor/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .common import DeviceRoisExtractor
|
@ -1,11 +1,11 @@
|
||||
import cv2
|
||||
|
||||
from ....crop import crop_xywh
|
||||
from ..definitions.common import DeviceRoiSizes
|
||||
from ..definition.common import DeviceRois
|
||||
|
||||
|
||||
class DeviceRoiExtractor:
|
||||
def __init__(self, img: cv2.Mat, sizes: DeviceRoiSizes):
|
||||
class DeviceRoisExtractor:
|
||||
def __init__(self, img: cv2.Mat, sizes: DeviceRois):
|
||||
self.img = img
|
||||
self.sizes = sizes
|
||||
|
2
src/arcaea_offline_ocr/device/rois/masker/__init__.py
Normal file
2
src/arcaea_offline_ocr/device/rois/masker/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from .auto import *
|
||||
from .common import DeviceRoisMasker
|
254
src/arcaea_offline_ocr/device/rois/masker/auto.py
Normal file
254
src/arcaea_offline_ocr/device/rois/masker/auto.py
Normal file
@ -0,0 +1,254 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from .common import DeviceRoisMasker
|
||||
|
||||
|
||||
class DeviceRoisMaskerAuto(DeviceRoisMasker):
|
||||
...
|
||||
|
||||
|
||||
class DeviceRoisMaskerAutoT1(DeviceRoisMaskerAuto):
|
||||
GRAY_BGR_MIN = np.array([50] * 3, np.uint8)
|
||||
GRAY_BGR_MAX = np.array([160] * 3, np.uint8)
|
||||
|
||||
WHITE_HSV_MIN = np.array([0, 0, 240], np.uint8)
|
||||
WHITE_HSV_MAX = np.array([179, 10, 255], np.uint8)
|
||||
|
||||
PST_HSV_MIN = np.array([100, 50, 80], np.uint8)
|
||||
PST_HSV_MAX = np.array([100, 255, 255], np.uint8)
|
||||
|
||||
PRS_HSV_MIN = np.array([43, 40, 75], np.uint8)
|
||||
PRS_HSV_MAX = np.array([50, 155, 190], np.uint8)
|
||||
|
||||
FTR_HSV_MIN = np.array([149, 30, 0], np.uint8)
|
||||
FTR_HSV_MAX = np.array([155, 181, 150], np.uint8)
|
||||
|
||||
BYD_HSV_MIN = np.array([170, 50, 50], np.uint8)
|
||||
BYD_HSV_MAX = np.array([179, 210, 198], np.uint8)
|
||||
|
||||
TRACK_LOST_HSV_MIN = np.array([170, 75, 90], np.uint8)
|
||||
TRACK_LOST_HSV_MAX = np.array([175, 170, 160], np.uint8)
|
||||
|
||||
TRACK_COMPLETE_HSV_MIN = np.array([140, 0, 50], np.uint8)
|
||||
TRACK_COMPLETE_HSV_MAX = np.array([145, 50, 130], np.uint8)
|
||||
|
||||
FULL_RECALL_HSV_MIN = np.array([140, 60, 80], np.uint8)
|
||||
FULL_RECALL_HSV_MAX = np.array([150, 130, 145], np.uint8)
|
||||
|
||||
PURE_MEMORY_HSV_MIN = np.array([90, 70, 80], np.uint8)
|
||||
PURE_MEMORY_HSV_MAX = np.array([110, 200, 175], np.uint8)
|
||||
|
||||
@classmethod
|
||||
def gray(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
bgr_value_equal_mask = np.max(roi_bgr, axis=2) - np.min(roi_bgr, axis=2) <= 5
|
||||
img_bgr = roi_bgr.copy()
|
||||
img_bgr[~bgr_value_equal_mask] = np.array([0, 0, 0], roi_bgr.dtype)
|
||||
img_bgr = cv2.erode(img_bgr, cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)))
|
||||
img_bgr = cv2.dilate(img_bgr, cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1)))
|
||||
return cv2.inRange(img_bgr, cls.GRAY_BGR_MIN, cls.GRAY_BGR_MAX)
|
||||
|
||||
@classmethod
|
||||
def pure(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.gray(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def far(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.gray(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def lost(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.gray(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def score(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.WHITE_HSV_MIN,
|
||||
cls.WHITE_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_pst(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), cls.PST_HSV_MIN, cls.PST_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_prs(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), cls.PRS_HSV_MIN, cls.PRS_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_ftr(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), cls.FTR_HSV_MIN, cls.FTR_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_byd(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), cls.BYD_HSV_MIN, cls.BYD_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def max_recall(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.gray(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def clear_status_track_lost(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.TRACK_LOST_HSV_MIN,
|
||||
cls.TRACK_LOST_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_track_complete(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.TRACK_COMPLETE_HSV_MIN,
|
||||
cls.TRACK_COMPLETE_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_full_recall(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.FULL_RECALL_HSV_MIN,
|
||||
cls.FULL_RECALL_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_pure_memory(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.PURE_MEMORY_HSV_MIN,
|
||||
cls.PURE_MEMORY_HSV_MAX,
|
||||
)
|
||||
|
||||
|
||||
class DeviceRoisMaskerAutoT2(DeviceRoisMaskerAuto):
|
||||
PFL_HSV_MIN = np.array([0, 0, 248], np.uint8)
|
||||
PFL_HSV_MAX = np.array([179, 10, 255], np.uint8)
|
||||
|
||||
WHITE_HSV_MIN = np.array([0, 0, 240], np.uint8)
|
||||
WHITE_HSV_MAX = np.array([179, 10, 255], np.uint8)
|
||||
|
||||
PST_HSV_MIN = np.array([100, 50, 80], np.uint8)
|
||||
PST_HSV_MAX = np.array([100, 255, 255], np.uint8)
|
||||
|
||||
PRS_HSV_MIN = np.array([43, 40, 75], np.uint8)
|
||||
PRS_HSV_MAX = np.array([50, 155, 190], np.uint8)
|
||||
|
||||
FTR_HSV_MIN = np.array([149, 30, 0], np.uint8)
|
||||
FTR_HSV_MAX = np.array([155, 181, 150], np.uint8)
|
||||
|
||||
BYD_HSV_MIN = np.array([170, 50, 50], np.uint8)
|
||||
BYD_HSV_MAX = np.array([179, 210, 198], np.uint8)
|
||||
|
||||
MAX_RECALL_HSV_MIN = np.array([125, 0, 0], np.uint8)
|
||||
MAX_RECALL_HSV_MAX = np.array([130, 100, 150], np.uint8)
|
||||
|
||||
TRACK_LOST_HSV_MIN = np.array([170, 75, 90], np.uint8)
|
||||
TRACK_LOST_HSV_MAX = np.array([175, 170, 160], np.uint8)
|
||||
|
||||
TRACK_COMPLETE_HSV_MIN = np.array([140, 0, 50], np.uint8)
|
||||
TRACK_COMPLETE_HSV_MAX = np.array([145, 50, 130], np.uint8)
|
||||
|
||||
FULL_RECALL_HSV_MIN = np.array([140, 60, 80], np.uint8)
|
||||
FULL_RECALL_HSV_MAX = np.array([150, 130, 145], np.uint8)
|
||||
|
||||
PURE_MEMORY_HSV_MIN = np.array([90, 70, 80], np.uint8)
|
||||
PURE_MEMORY_HSV_MAX = np.array([110, 200, 175], np.uint8)
|
||||
|
||||
@classmethod
|
||||
def pfl(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), cls.PFL_HSV_MIN, cls.PFL_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def pure(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.pfl(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def far(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.pfl(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def lost(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cls.pfl(roi_bgr)
|
||||
|
||||
@classmethod
|
||||
def score(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.WHITE_HSV_MIN,
|
||||
cls.WHITE_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_pst(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), cls.PST_HSV_MIN, cls.PST_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_prs(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), cls.PRS_HSV_MIN, cls.PRS_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_ftr(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), cls.FTR_HSV_MIN, cls.FTR_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def rating_class_byd(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV), cls.BYD_HSV_MIN, cls.BYD_HSV_MAX
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def max_recall(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.MAX_RECALL_HSV_MIN,
|
||||
cls.MAX_RECALL_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_track_lost(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.TRACK_LOST_HSV_MIN,
|
||||
cls.TRACK_LOST_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_track_complete(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.TRACK_COMPLETE_HSV_MIN,
|
||||
cls.TRACK_COMPLETE_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_full_recall(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.FULL_RECALL_HSV_MIN,
|
||||
cls.FULL_RECALL_HSV_MAX,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_status_pure_memory(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
return cv2.inRange(
|
||||
cv2.cvtColor(roi_bgr, cv2.COLOR_BGR2HSV),
|
||||
cls.PURE_MEMORY_HSV_MIN,
|
||||
cls.PURE_MEMORY_HSV_MAX,
|
||||
)
|
@ -1,7 +1,7 @@
|
||||
import cv2
|
||||
|
||||
|
||||
class DeviceRoiMasker:
|
||||
class DeviceRoisMasker:
|
||||
@classmethod
|
||||
def pure(cls, roi_bgr: cv2.Mat) -> cv2.Mat:
|
||||
raise NotImplementedError()
|
@ -1,8 +1,32 @@
|
||||
import sqlite3
|
||||
|
||||
import imagehash
|
||||
import cv2
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
|
||||
|
||||
def phash_opencv(img_gray, hash_size=8, highfreq_factor=4):
|
||||
# type: (cv2.Mat | np.ndarray, int, int) -> np.ndarray
|
||||
"""
|
||||
Perceptual Hash computation.
|
||||
|
||||
Implementation follows http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html
|
||||
|
||||
Adapted from `imagehash.phash`, pure opencv implementation
|
||||
|
||||
The result is slightly different from `imagehash.phash`.
|
||||
"""
|
||||
if hash_size < 2:
|
||||
raise ValueError("Hash size must be greater than or equal to 2")
|
||||
|
||||
img_size = hash_size * highfreq_factor
|
||||
image = cv2.resize(img_gray, (img_size, img_size), interpolation=cv2.INTER_LANCZOS4)
|
||||
image = np.float32(image)
|
||||
dct = cv2.dct(image, flags=cv2.DCT_ROWS)
|
||||
dct = cv2.dct(image)
|
||||
dctlowfreq = dct[:hash_size, :hash_size]
|
||||
med = np.median(dctlowfreq)
|
||||
diff = dctlowfreq > med
|
||||
return diff
|
||||
|
||||
|
||||
def hamming_distance_sql_function(user_input, db_entry) -> int:
|
||||
@ -46,8 +70,8 @@ class ImagePHashDatabase:
|
||||
self.hashes_head = [h[: self.hashes_slice_size] for h in self.hashes]
|
||||
self.hashes_tail = [h[-self.hashes_slice_size :] for h in self.hashes]
|
||||
|
||||
def lookup_hash(self, image_hash: imagehash.ImageHash, *, limit: int = 5):
|
||||
image_hash = image_hash.hash.flatten()
|
||||
def lookup_hash(self, image_hash: np.ndarray, *, limit: int = 5):
|
||||
image_hash = image_hash.flatten()
|
||||
# image_hash_head = image_hash[: self.hashes_slice_size]
|
||||
# image_hash_tail = image_hash[-self.hashes_slice_size :]
|
||||
# head_xor_results = [image_hash_head ^ h for h in self.hashes]
|
||||
@ -58,8 +82,8 @@ class ImagePHashDatabase:
|
||||
]
|
||||
return sorted(xor_results, key=lambda r: r[1])[:limit]
|
||||
|
||||
def lookup_image(self, pil_image: Image.Image):
|
||||
image_hash = imagehash.phash(
|
||||
pil_image, hash_size=self.hash_size, highfreq_factor=self.highfreq_factor
|
||||
def lookup_image(self, img_gray: cv2.Mat):
|
||||
image_hash = phash_opencv(
|
||||
img_gray, hash_size=self.hash_size, highfreq_factor=self.highfreq_factor
|
||||
)
|
||||
return self.lookup_hash(image_hash)[0]
|
||||
|
Reference in New Issue
Block a user