mirror of
https://github.com/283375/arcaea-offline-ocr.git
synced 2025-04-11 09:30:17 +00:00
refactor: module structure
This commit is contained in:
parent
0d8e4dea8e
commit
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()
|
Loading…
x
Reference in New Issue
Block a user