mirror of
https://github.com/sui-feng-cb/AzurLaneAutoScript1.git
synced 2026-06-30 01:44:12 +08:00
Bug fix (#5752)
* Opt: using template matching for commission suffix recognition (#5731)
* Opt: using pHash and template matching for commission suffix recognition
* Refactor: improve suffix image processing and hash calculation
* Revert "Upd: [JP] asset GET_ITEMS_X (#5718)" (#5751)
This reverts commit c852cff758.
* Chore: move hashlib to local import
* Upd: [TW] Event entrance of Revelations of Dust Rerun (event_20230223_cn)
---------
Co-authored-by: guoh064 <50830808+guoh064@users.noreply.github.com>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 8.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 10 KiB |
@@ -301,3 +301,4 @@ To add a new event, add a new row in here, and run `python -m module.config.conf
|
|||||||
| 20260528 | event 20220818 cn | Operation Convergence | - | - | - | 復刻遠匯點作戰 |
|
| 20260528 | event 20220818 cn | Operation Convergence | - | - | - | 復刻遠匯點作戰 |
|
||||||
| 20260605 | event 20260520 cn | Alliance Before the Hagiobull | - | - | - | 聖印前的同盟 |
|
| 20260605 | event 20260520 cn | Alliance Before the Hagiobull | - | - | - | 聖印前的同盟 |
|
||||||
| 20260618 | event 20240521 cn | Light of the Martyrium Rerun | 复刻绽放于辉光之城 | Light of the Martyrium Rerun | 赫輝のマルティリウム(復刻) | - |
|
| 20260618 | event 20240521 cn | Light of the Martyrium Rerun | 复刻绽放于辉光之城 | Light of the Martyrium Rerun | 赫輝のマルティリウム(復刻) | - |
|
||||||
|
| 20260625 | event 20230223 cn | Revelations of Dust | - | - | - | 復刻湮燼塵墟 |
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ EXP_INFO_B = Button(area={'cn': (332, 107, 387, 118), 'en': (332, 107, 387, 118)
|
|||||||
EXP_INFO_C = Button(area={'cn': (332, 56, 345, 107), 'en': (332, 56, 345, 107), 'jp': (332, 56, 345, 107), 'tw': (332, 56, 345, 107)}, color={'cn': (198, 208, 198), 'en': (198, 208, 198), 'jp': (198, 208, 198), 'tw': (198, 208, 198)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_C.png', 'en': './assets/en/combat/EXP_INFO_C.png', 'jp': './assets/jp/combat/EXP_INFO_C.png', 'tw': './assets/tw/combat/EXP_INFO_C.png'})
|
EXP_INFO_C = Button(area={'cn': (332, 56, 345, 107), 'en': (332, 56, 345, 107), 'jp': (332, 56, 345, 107), 'tw': (332, 56, 345, 107)}, color={'cn': (198, 208, 198), 'en': (198, 208, 198), 'jp': (198, 208, 198), 'tw': (198, 208, 198)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_C.png', 'en': './assets/en/combat/EXP_INFO_C.png', 'jp': './assets/jp/combat/EXP_INFO_C.png', 'tw': './assets/tw/combat/EXP_INFO_C.png'})
|
||||||
EXP_INFO_D = Button(area={'cn': (328, 45, 341, 119), 'en': (328, 45, 341, 119), 'jp': (328, 45, 341, 119), 'tw': (328, 45, 341, 119)}, color={'cn': (199, 208, 199), 'en': (199, 208, 199), 'jp': (199, 208, 199), 'tw': (199, 208, 199)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_D.png', 'en': './assets/en/combat/EXP_INFO_D.png', 'jp': './assets/jp/combat/EXP_INFO_D.png', 'tw': './assets/tw/combat/EXP_INFO_D.png'})
|
EXP_INFO_D = Button(area={'cn': (328, 45, 341, 119), 'en': (328, 45, 341, 119), 'jp': (328, 45, 341, 119), 'tw': (328, 45, 341, 119)}, color={'cn': (199, 208, 199), 'en': (199, 208, 199), 'jp': (199, 208, 199), 'tw': (199, 208, 199)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_D.png', 'en': './assets/en/combat/EXP_INFO_D.png', 'jp': './assets/jp/combat/EXP_INFO_D.png', 'tw': './assets/tw/combat/EXP_INFO_D.png'})
|
||||||
EXP_INFO_S = Button(area={'cn': (342, 107, 389, 119), 'en': (342, 107, 389, 119), 'jp': (342, 107, 389, 119), 'tw': (342, 107, 389, 119)}, color={'cn': (233, 242, 127), 'en': (233, 242, 127), 'jp': (233, 242, 127), 'tw': (233, 242, 127)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_S.png', 'en': './assets/en/combat/EXP_INFO_S.png', 'jp': './assets/jp/combat/EXP_INFO_S.png', 'tw': './assets/tw/combat/EXP_INFO_S.png'})
|
EXP_INFO_S = Button(area={'cn': (342, 107, 389, 119), 'en': (342, 107, 389, 119), 'jp': (342, 107, 389, 119), 'tw': (342, 107, 389, 119)}, color={'cn': (233, 242, 127), 'en': (233, 242, 127), 'jp': (233, 242, 127), 'tw': (233, 242, 127)}, button={'cn': (1133, 634, 1262, 650), 'en': (1133, 634, 1262, 650), 'jp': (1133, 634, 1262, 650), 'tw': (1133, 634, 1262, 650)}, file={'cn': './assets/cn/combat/EXP_INFO_S.png', 'en': './assets/en/combat/EXP_INFO_S.png', 'jp': './assets/jp/combat/EXP_INFO_S.png', 'tw': './assets/tw/combat/EXP_INFO_S.png'})
|
||||||
GET_ITEMS_1 = Button(area={'cn': (538, 217, 741, 253), 'en': (551, 223, 736, 250), 'jp': (548, 217, 741, 253), 'tw': (539, 217, 742, 253)}, color={'cn': (160, 192, 248), 'en': (166, 194, 235), 'jp': (144, 183, 250), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1.png', 'en': './assets/en/combat/GET_ITEMS_1.png', 'jp': './assets/jp/combat/GET_ITEMS_1.png', 'tw': './assets/tw/combat/GET_ITEMS_1.png'})
|
GET_ITEMS_1 = Button(area={'cn': (538, 217, 741, 253), 'en': (551, 223, 736, 250), 'jp': (539, 220, 741, 252), 'tw': (539, 217, 742, 253)}, color={'cn': (160, 192, 248), 'en': (166, 194, 235), 'jp': (146, 184, 249), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1.png', 'en': './assets/en/combat/GET_ITEMS_1.png', 'jp': './assets/jp/combat/GET_ITEMS_1.png', 'tw': './assets/tw/combat/GET_ITEMS_1.png'})
|
||||||
GET_ITEMS_1_RYZA = Button(area={'cn': (564, 217, 721, 245), 'en': (577, 211, 704, 239), 'jp': (566, 217, 719, 244), 'tw': (564, 218, 723, 246)}, color={'cn': (176, 199, 243), 'en': (172, 199, 246), 'jp': (179, 201, 243), 'tw': (173, 197, 242)}, button={'cn': (1000, 631, 1055, 689), 'en': (1000, 631, 1055, 689), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1_RYZA.png', 'en': './assets/en/combat/GET_ITEMS_1_RYZA.png', 'jp': './assets/jp/combat/GET_ITEMS_1_RYZA.png', 'tw': './assets/tw/combat/GET_ITEMS_1_RYZA.png'})
|
GET_ITEMS_1_RYZA = Button(area={'cn': (564, 217, 721, 245), 'en': (577, 211, 704, 239), 'jp': (566, 217, 719, 244), 'tw': (564, 218, 723, 246)}, color={'cn': (176, 199, 243), 'en': (172, 199, 246), 'jp': (179, 201, 243), 'tw': (173, 197, 242)}, button={'cn': (1000, 631, 1055, 689), 'en': (1000, 631, 1055, 689), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_1_RYZA.png', 'en': './assets/en/combat/GET_ITEMS_1_RYZA.png', 'jp': './assets/jp/combat/GET_ITEMS_1_RYZA.png', 'tw': './assets/tw/combat/GET_ITEMS_1_RYZA.png'})
|
||||||
GET_ITEMS_2 = Button(area={'cn': (538, 146, 742, 182), 'en': (551, 149, 735, 175), 'jp': (547, 143, 742, 179), 'tw': (538, 148, 741, 182)}, color={'cn': (160, 192, 248), 'en': (167, 195, 235), 'jp': (145, 183, 250), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_2.png', 'en': './assets/en/combat/GET_ITEMS_2.png', 'jp': './assets/jp/combat/GET_ITEMS_2.png', 'tw': './assets/tw/combat/GET_ITEMS_2.png'})
|
GET_ITEMS_2 = Button(area={'cn': (538, 146, 742, 182), 'en': (551, 149, 735, 175), 'jp': (536, 146, 741, 182), 'tw': (538, 148, 741, 182)}, color={'cn': (160, 192, 248), 'en': (167, 195, 235), 'jp': (145, 182, 249), 'tw': (155, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_2.png', 'en': './assets/en/combat/GET_ITEMS_2.png', 'jp': './assets/jp/combat/GET_ITEMS_2.png', 'tw': './assets/tw/combat/GET_ITEMS_2.png'})
|
||||||
GET_ITEMS_3 = Button(area={'cn': (539, 143, 742, 179), 'en': (548, 136, 740, 172), 'jp': (547, 143, 742, 179), 'tw': (546, 145, 742, 178)}, color={'cn': (161, 193, 248), 'en': (152, 185, 237), 'jp': (145, 183, 250), 'tw': (156, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_3.png', 'en': './assets/en/combat/GET_ITEMS_3.png', 'jp': './assets/jp/combat/GET_ITEMS_3.png', 'tw': './assets/tw/combat/GET_ITEMS_3.png'})
|
GET_ITEMS_3 = Button(area={'cn': (539, 143, 742, 179), 'en': (548, 136, 740, 172), 'jp': (540, 143, 742, 179), 'tw': (546, 145, 742, 178)}, color={'cn': (161, 193, 248), 'en': (152, 185, 237), 'jp': (145, 182, 248), 'tw': (156, 190, 248)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_ITEMS_3.png', 'en': './assets/en/combat/GET_ITEMS_3.png', 'jp': './assets/jp/combat/GET_ITEMS_3.png', 'tw': './assets/tw/combat/GET_ITEMS_3.png'})
|
||||||
GET_ITEMS_3_CHECK = Button(area={'cn': (335, 184, 947, 203), 'en': (335, 184, 947, 203), 'jp': (335, 184, 947, 203), 'tw': (335, 184, 947, 203)}, color={'cn': (84, 95, 109), 'en': (84, 95, 109), 'jp': (84, 95, 109), 'tw': (84, 95, 109)}, button={'cn': (335, 184, 947, 203), 'en': (335, 184, 947, 203), 'jp': (335, 184, 947, 203), 'tw': (335, 184, 947, 203)}, file={'cn': './assets/cn/combat/GET_ITEMS_3_CHECK.png', 'en': './assets/en/combat/GET_ITEMS_3_CHECK.png', 'jp': './assets/jp/combat/GET_ITEMS_3_CHECK.png', 'tw': './assets/tw/combat/GET_ITEMS_3_CHECK.png'})
|
GET_ITEMS_3_CHECK = Button(area={'cn': (335, 184, 947, 203), 'en': (335, 184, 947, 203), 'jp': (335, 184, 947, 203), 'tw': (335, 184, 947, 203)}, color={'cn': (84, 95, 109), 'en': (84, 95, 109), 'jp': (84, 95, 109), 'tw': (84, 95, 109)}, button={'cn': (335, 184, 947, 203), 'en': (335, 184, 947, 203), 'jp': (335, 184, 947, 203), 'tw': (335, 184, 947, 203)}, file={'cn': './assets/cn/combat/GET_ITEMS_3_CHECK.png', 'en': './assets/en/combat/GET_ITEMS_3_CHECK.png', 'jp': './assets/jp/combat/GET_ITEMS_3_CHECK.png', 'tw': './assets/tw/combat/GET_ITEMS_3_CHECK.png'})
|
||||||
GET_SHIP = Button(area={'cn': (1104, 610, 1110, 630), 'en': (1104, 610, 1110, 630), 'jp': (1104, 610, 1110, 630), 'tw': (1104, 610, 1110, 630)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_SHIP.png', 'en': './assets/en/combat/GET_SHIP.png', 'jp': './assets/jp/combat/GET_SHIP.png', 'tw': './assets/tw/combat/GET_SHIP.png'})
|
GET_SHIP = Button(area={'cn': (1104, 610, 1110, 630), 'en': (1104, 610, 1110, 630), 'jp': (1104, 610, 1110, 630), 'tw': (1104, 610, 1110, 630)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (1000, 631, 1055, 689), 'en': (999, 630, 1047, 691), 'jp': (1000, 631, 1055, 689), 'tw': (1000, 631, 1055, 689)}, file={'cn': './assets/cn/combat/GET_SHIP.png', 'en': './assets/en/combat/GET_SHIP.png', 'jp': './assets/jp/combat/GET_SHIP.png', 'tw': './assets/tw/combat/GET_SHIP.png'})
|
||||||
LOADING_BAR = Button(area={'cn': (33, 676, 1247, 680), 'en': (33, 676, 1247, 680), 'jp': (33, 676, 1247, 680), 'tw': (33, 676, 1247, 680)}, color={'cn': (172, 205, 232), 'en': (172, 205, 232), 'jp': (172, 205, 232), 'tw': (172, 205, 232)}, button={'cn': (33, 676, 1247, 680), 'en': (33, 676, 1247, 680), 'jp': (33, 676, 1247, 680), 'tw': (33, 676, 1247, 680)}, file={'cn': './assets/cn/combat/LOADING_BAR.png', 'en': './assets/en/combat/LOADING_BAR.png', 'jp': './assets/jp/combat/LOADING_BAR.png', 'tw': './assets/tw/combat/LOADING_BAR.png'})
|
LOADING_BAR = Button(area={'cn': (33, 676, 1247, 680), 'en': (33, 676, 1247, 680), 'jp': (33, 676, 1247, 680), 'tw': (33, 676, 1247, 680)}, color={'cn': (172, 205, 232), 'en': (172, 205, 232), 'jp': (172, 205, 232), 'tw': (172, 205, 232)}, button={'cn': (33, 676, 1247, 680), 'en': (33, 676, 1247, 680), 'jp': (33, 676, 1247, 680), 'tw': (33, 676, 1247, 680)}, file={'cn': './assets/cn/combat/LOADING_BAR.png', 'en': './assets/en/combat/LOADING_BAR.png', 'jp': './assets/jp/combat/LOADING_BAR.png', 'tw': './assets/tw/combat/LOADING_BAR.png'})
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
import module.config.server as server
|
|
||||||
from module.base.decorator import Config
|
from module.base.decorator import Config
|
||||||
from module.base.filter import Filter
|
from module.base.filter import Filter
|
||||||
from module.base.utils import *
|
from module.base.utils import *
|
||||||
@@ -23,20 +22,54 @@ COMMISSION_FILTER = Filter(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class SuffixOcr(Ocr):
|
def crop_suffix_image(image, area):
|
||||||
def pre_process(self, image):
|
"""
|
||||||
image = super().pre_process(image)
|
Args:
|
||||||
|
image (np.ndarray):
|
||||||
|
area (tuple): Commission name area.
|
||||||
|
|
||||||
left = np.where(np.min(image[5:-5, :], axis=0) < 85)[0]
|
Returns:
|
||||||
# Look back several pixels
|
np.ndarray | None: Cropped suffix image, black letters on white background.
|
||||||
if server.server in ['jp']:
|
"""
|
||||||
look_back = 21
|
name_image = crop(image, area)
|
||||||
else:
|
name_image = extract_letters(name_image, letter=(255, 255, 255), threshold=128).astype(np.uint8)
|
||||||
look_back = 18
|
|
||||||
if len(left):
|
|
||||||
image = image[:, left[-1] - look_back:]
|
|
||||||
|
|
||||||
return image
|
line = cv2.reduce(name_image[5:-5, :], 0, cv2.REDUCE_AVG).flatten()
|
||||||
|
columns = np.where(line < 250)[0]
|
||||||
|
if not len(columns):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Look back several pixels from the rightmost letter to include Roman numerals.
|
||||||
|
threshold = 250
|
||||||
|
look_back = 10
|
||||||
|
for i in range(columns[-1], 0, -1):
|
||||||
|
if line[i] > threshold:
|
||||||
|
if columns[-1] - i > look_back:
|
||||||
|
look_back = columns[-1] - i
|
||||||
|
break
|
||||||
|
|
||||||
|
left = columns[-1] - look_back
|
||||||
|
right = columns[-1] + 1
|
||||||
|
x1, y1 = area[0:2]
|
||||||
|
suffix_area = area_offset((left - 3, -3, right + 3, name_image.shape[0] + 3), (x1, y1))
|
||||||
|
image = crop(image, suffix_area)
|
||||||
|
image = extract_letters(image, letter=(255, 255, 255), threshold=128).astype(np.uint8)
|
||||||
|
return image
|
||||||
|
|
||||||
|
|
||||||
|
def image_hash(image):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
image (np.ndarray):
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str:
|
||||||
|
"""
|
||||||
|
if image is None:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
return hashlib.md5(image.tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
class Commission:
|
class Commission:
|
||||||
@@ -46,10 +79,10 @@ class Commission:
|
|||||||
name: str
|
name: str
|
||||||
# If success to parse commission name
|
# If success to parse commission name
|
||||||
valid: bool
|
valid: bool
|
||||||
# Suffix in roman numerals
|
# Cropped suffix image, black letters on white background, or None
|
||||||
# May be wrong if commission does not have a suffix
|
suffix_image: np.ndarray
|
||||||
# Value: ⅠⅡⅢⅤⅣⅥ
|
# Hash of suffix image, used only for logging, or empty string if suffix_image is None
|
||||||
suffix: str
|
suffix_hash: str
|
||||||
# Genre name in project_data.py
|
# Genre name in project_data.py
|
||||||
# Value: major_comm, daily_resource, urgent_cube, ...
|
# Value: major_comm, daily_resource, urgent_cube, ...
|
||||||
genre: str
|
genre: str
|
||||||
@@ -113,8 +146,8 @@ class Commission:
|
|||||||
self.genre = self.commission_name_parse(self.name)
|
self.genre = self.commission_name_parse(self.name)
|
||||||
|
|
||||||
# Suffix
|
# Suffix
|
||||||
ocr = SuffixOcr(button, lang='azur_lane', letter=(255, 255, 255), threshold=128, alphabet='IV')
|
self.suffix_image = crop_suffix_image(self.image, self.button.area)
|
||||||
self.suffix = self.beautify_name(ocr.ocr(self.image))
|
self.suffix_hash = image_hash(self.suffix_image)
|
||||||
|
|
||||||
# Duration time
|
# Duration time
|
||||||
area = area_offset((290, 68, 390, 95), self.area[0:2])
|
area = area_offset((290, 68, 390, 95), self.area[0:2])
|
||||||
@@ -160,8 +193,8 @@ class Commission:
|
|||||||
self.genre = self.commission_name_parse(self.name)
|
self.genre = self.commission_name_parse(self.name)
|
||||||
|
|
||||||
# Suffix
|
# Suffix
|
||||||
ocr = SuffixOcr(button, lang='azur_lane', letter=(255, 255, 255), threshold=128, alphabet='IV')
|
self.suffix_image = crop_suffix_image(self.image, self.button.area)
|
||||||
self.suffix = self.beautify_name(ocr.ocr(self.image))
|
self.suffix_hash = image_hash(self.suffix_image)
|
||||||
|
|
||||||
# Duration time
|
# Duration time
|
||||||
area = area_offset((290, 68, 390, 95), self.area[0:2])
|
area = area_offset((290, 68, 390, 95), self.area[0:2])
|
||||||
@@ -209,8 +242,8 @@ class Commission:
|
|||||||
self.genre = self.commission_name_parse(self.name)
|
self.genre = self.commission_name_parse(self.name)
|
||||||
|
|
||||||
# Suffix
|
# Suffix
|
||||||
ocr = SuffixOcr(button, lang='azur_lane', letter=(255, 255, 255), threshold=128, alphabet='IV')
|
self.suffix_image = crop_suffix_image(self.image, self.button.area)
|
||||||
self.suffix = self.beautify_name(ocr.ocr(self.image))
|
self.suffix_hash = image_hash(self.suffix_image)
|
||||||
|
|
||||||
# Duration time
|
# Duration time
|
||||||
area = area_offset((290, 68, 390, 95), self.area[0:2])
|
area = area_offset((290, 68, 390, 95), self.area[0:2])
|
||||||
@@ -254,8 +287,8 @@ class Commission:
|
|||||||
self.genre = self.commission_name_parse(self.name)
|
self.genre = self.commission_name_parse(self.name)
|
||||||
|
|
||||||
# Suffix
|
# Suffix
|
||||||
ocr = SuffixOcr(button, lang='azur_lane', letter=(255, 255, 255), threshold=128, alphabet='IV')
|
self.suffix_image = crop_suffix_image(self.image, self.button.area)
|
||||||
self.suffix = self.beautify_name(ocr.ocr(self.image))
|
self.suffix_hash = image_hash(self.suffix_image)
|
||||||
|
|
||||||
# Duration time
|
# Duration time
|
||||||
area = area_offset((290, 68, 390, 95), self.area[0:2])
|
area = area_offset((290, 68, 390, 95), self.area[0:2])
|
||||||
@@ -288,7 +321,7 @@ class Commission:
|
|||||||
self.status = dic[int(np.argmax(color))]
|
self.status = dic[int(np.argmax(color))]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
name = f'{self.name} | {self.suffix}'
|
name = f'{self.name} | {self.suffix_hash}' if self.suffix_hash else self.name
|
||||||
if not self.valid:
|
if not self.valid:
|
||||||
return f'{name} (Invalid)'
|
return f'{name} (Invalid)'
|
||||||
info = {'Genre': self.genre, 'Status': self.status, 'Duration': self.duration}
|
info = {'Genre': self.genre, 'Status': self.status, 'Duration': self.duration}
|
||||||
@@ -315,7 +348,7 @@ class Commission:
|
|||||||
if self.genre != other.genre or self.status != other.status:
|
if self.genre != other.genre or self.status != other.status:
|
||||||
return False
|
return False
|
||||||
if self.category_str == 'daily':
|
if self.category_str == 'daily':
|
||||||
if self.suffix != other.suffix:
|
if not self.suffix_match(other):
|
||||||
return False
|
return False
|
||||||
if self.genre == 'urgent_box':
|
if self.genre == 'urgent_box':
|
||||||
for tag in ['NYB', 'BIW']:
|
for tag in ['NYB', 'BIW']:
|
||||||
@@ -332,7 +365,7 @@ class Commission:
|
|||||||
return False
|
return False
|
||||||
if self.repeat_count != other.repeat_count:
|
if self.repeat_count != other.repeat_count:
|
||||||
return False
|
return False
|
||||||
if self.genre in ['extra_oil', 'night_oil'] and self.suffix != other.suffix:
|
if self.genre in ['extra_oil', 'night_oil'] and not self.suffix_match(other):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@@ -340,6 +373,35 @@ class Commission:
|
|||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(f'{self.genre}_{self.name}')
|
return hash(f'{self.genre}_{self.name}')
|
||||||
|
|
||||||
|
def suffix_match(self, other, similarity=0.75):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
other (Commission):
|
||||||
|
similarity (float): 0-1. Similarity.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool:
|
||||||
|
"""
|
||||||
|
if self.suffix_image is None and other.suffix_image is None:
|
||||||
|
return True
|
||||||
|
if self.suffix_image is None or other.suffix_image is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def match(image, template):
|
||||||
|
template = crop(template, (3, 3, template.shape[1] - 3, template.shape[0] - 3), copy=False)
|
||||||
|
if image.shape[0] < template.shape[0] or image.shape[1] < template.shape[1]:
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
|
||||||
|
_, sim, _, _ = cv2.minMaxLoc(res)
|
||||||
|
return sim
|
||||||
|
|
||||||
|
sim = max(
|
||||||
|
match(self.suffix_image, other.suffix_image),
|
||||||
|
match(other.suffix_image, self.suffix_image)
|
||||||
|
)
|
||||||
|
return sim >= similarity
|
||||||
|
|
||||||
def parse_time(self, string):
|
def parse_time(self, string):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
@@ -1643,8 +1643,8 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
@@ -1656,11 +1656,11 @@
|
|||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20260520_cn"
|
"event_20230223_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Mode": {
|
"Mode": {
|
||||||
@@ -1925,8 +1925,8 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
@@ -1938,11 +1938,11 @@
|
|||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20260520_cn"
|
"event_20230223_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Mode": {
|
"Mode": {
|
||||||
@@ -2322,8 +2322,8 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
@@ -2335,11 +2335,11 @@
|
|||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20260520_cn"
|
"event_20230223_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Mode": {
|
"Mode": {
|
||||||
@@ -4069,8 +4069,8 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
@@ -4082,11 +4082,11 @@
|
|||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20260520_cn"
|
"event_20230223_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Mode": {
|
"Mode": {
|
||||||
@@ -4483,8 +4483,8 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
@@ -4496,11 +4496,11 @@
|
|||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20260520_cn"
|
"event_20230223_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Mode": {
|
"Mode": {
|
||||||
@@ -4897,8 +4897,8 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
@@ -4910,11 +4910,11 @@
|
|||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20260520_cn"
|
"event_20230223_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Mode": {
|
"Mode": {
|
||||||
@@ -5311,8 +5311,8 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
@@ -5324,11 +5324,11 @@
|
|||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20260520_cn"
|
"event_20230223_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Mode": {
|
"Mode": {
|
||||||
@@ -5715,8 +5715,8 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
@@ -5728,11 +5728,11 @@
|
|||||||
"event_20240521_cn"
|
"event_20240521_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20260520_cn"
|
"event_20230223_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20240521_cn",
|
"event_20230223_cn",
|
||||||
"event_20260520_cn"
|
"event_20240521_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Mode": {
|
"Mode": {
|
||||||
|
|||||||
@@ -742,7 +742,7 @@
|
|||||||
"event_20220915_cn": "復刻紫絳槿嵐",
|
"event_20220915_cn": "復刻紫絳槿嵐",
|
||||||
"event_20221124_cn": "復刻鍊金術士與秘密遺跡群島",
|
"event_20221124_cn": "復刻鍊金術士與秘密遺跡群島",
|
||||||
"event_20221222_cn": "復刻定向折疊",
|
"event_20221222_cn": "復刻定向折疊",
|
||||||
"event_20230223_cn": "湮燼塵墟",
|
"event_20230223_cn": "復刻湮燼塵墟",
|
||||||
"event_20230525_cn": "空相交會點",
|
"event_20230525_cn": "空相交會點",
|
||||||
"event_20230803_cn": "奏響鳶尾之歌",
|
"event_20230803_cn": "奏響鳶尾之歌",
|
||||||
"event_20230817_cn": "愚者的天平",
|
"event_20230817_cn": "愚者的天平",
|
||||||
|
|||||||
Reference in New Issue
Block a user