From a8a243052fcd3f1deb2adf6aea7075533d4db7ec Mon Sep 17 00:00:00 2001 From: LmeSzinc Date: Sat, 18 Apr 2020 21:19:15 +0800 Subject: [PATCH] =?UTF-8?q?Add:=20=E5=A2=9E=E5=8A=A0=E4=BA=86=E6=9C=AA?= =?UTF-8?q?=E9=80=9A=E5=85=B3=E7=9A=84=E7=AB=A0=E8=8A=82=E5=90=8D=E7=9A=84?= =?UTF-8?q?=E8=AF=86=E5=88=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ocr预处理时会将图片左对齐 --- assets/handler/MAP_CLEAR_PERCENTAGE.png | Bin 0 -> 5589 bytes assets/template/TEMPLATE_STAGE_PERCENT.png | Bin 0 -> 3246 bytes module/base/ocr.py | 8 ++++ module/campaign/campaign_base.py | 1 + module/campaign/campaign_ocr.py | 42 +++++++++++---------- module/handler/assets.py | 1 + module/template/assets.py | 1 + 7 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 assets/handler/MAP_CLEAR_PERCENTAGE.png create mode 100644 assets/template/TEMPLATE_STAGE_PERCENT.png diff --git a/assets/handler/MAP_CLEAR_PERCENTAGE.png b/assets/handler/MAP_CLEAR_PERCENTAGE.png new file mode 100644 index 0000000000000000000000000000000000000000..600f6103c9820efb4bc3b02162d2af0dee4f1ae1 GIT binary patch literal 5589 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 literal 0 HcmV?d00001 diff --git a/module/base/ocr.py b/module/base/ocr.py index 358b35bbd..fd05965c5 100644 --- a/module/base/ocr.py +++ b/module/base/ocr.py @@ -90,6 +90,14 @@ class Ocr: # Resize to input size. size = (int(image.shape[1] / image.shape[0] * image_shape[1]), image_shape[1]) image = cv2.resize(image, size, interpolation=cv2.INTER_LINEAR) + + # Left align + x = np.where(np.mean(image, axis=0) < 220)[0] + if len(x): + x = x[0] - 2 if x[0] - 2 >= 2 else 0 + image = image[:, x:] + + # Pad to image_shape=(280, 32) diff_x = image_shape[0] - image.shape[1] if diff_x > 0: image = np.pad(image, ((0, 0), (0, diff_x)), mode='constant', constant_values=255) diff --git a/module/campaign/campaign_base.py b/module/campaign/campaign_base.py index 71cc4752e..b8f7c1a72 100644 --- a/module/campaign/campaign_base.py +++ b/module/campaign/campaign_base.py @@ -39,6 +39,7 @@ class CampaignBase(Map): def run(self): logger.hr(self.ENTRANCE, level=2) self.handle_spare_fleet() + self.ENTRANCE.area = self.ENTRANCE.button self.enter_map(self.ENTRANCE, mode=self.config.CAMPAIGN_MODE) self.handle_map_fleet_lock() self.handle_fleet_reverse() diff --git a/module/campaign/campaign_ocr.py b/module/campaign/campaign_ocr.py index 905ffc534..9263c60e7 100644 --- a/module/campaign/campaign_ocr.py +++ b/module/campaign/campaign_ocr.py @@ -5,9 +5,10 @@ import numpy as np from module.base.ocr import Ocr from module.base.utils import extract_letters, area_offset from module.logger import logger -from module.template.assets import TEMPLATE_STAGE_CLEAR, Button +from module.template.assets import TEMPLATE_STAGE_CLEAR, TEMPLATE_STAGE_PERCENT, Button -stage_clear_color = np.mean(np.mean(TEMPLATE_STAGE_CLEAR.image, axis=0), axis=0) +stage_clear_color = tuple(np.mean(np.mean(TEMPLATE_STAGE_CLEAR.image, axis=0), axis=0)) +stage_percentage_color = tuple(np.mean(np.mean(TEMPLATE_STAGE_PERCENT.image, axis=0), axis=0)) def ensure_chapter_index(name): @@ -56,33 +57,40 @@ class CampaignOcr: # 0.8705039 , 0.99954903, 0.99983317, 0.99996626, 1. ], # dtype=float32) - if result is None or len(result) == 0: - logger.warning('No stage clear image found.') - - name_offset = (77, 9) + name_offset = (75, 9) name_size = (60, 16) name_letter = (255, 255, 255) name_back = (102, 102, 102) digits = [] for point in result: point = point[::-1] - button = tuple(np.append(point, point + TEMPLATE_STAGE_CLEAR.image.shape[:2])) + button = tuple(np.append(point, point + TEMPLATE_STAGE_CLEAR.image.shape[:2][::-1])) point = point + name_offset name = image.crop(np.append(point, point + name_size)) name = extract_letters(name, letter=name_letter, back=name_back) stage = self.extract_stage_name(name) digits.append(Button(area=area_offset(stage, point), color=stage_clear_color, button=button, name='stage')) - # chapter, stage = self.name_separate(name) - # color = TEMPLATE_STAGE_CLEAR.color - # digits.append(Button(area=area_offset(chapter, point), color=color, button=button, name='chapter')) - # digits.append(Button(area=area_offset(stage, point), color=color, button=button, name='stage')) + result = TEMPLATE_STAGE_PERCENT.match_multi(image, similarity=0.95) + name_offset = (50, 0) + for point in result: + point = point[::-1] + button = tuple(np.append(point, point + TEMPLATE_STAGE_PERCENT.image.shape[:2][::-1])) + point = point + name_offset + name = image.crop(np.append(point, point + name_size)) + name = extract_letters(name, letter=name_letter, back=name_back) + stage = self.extract_stage_name(name) + digits.append( + Button(area=area_offset(stage, point), color=stage_percentage_color, button=button, name='stage')) + + if len(digits) == 0: + logger.warning('No stage found.') return digits @staticmethod def extract_stage_name(image): - x_skip = 2 + x_skip = 7 interval = 5 x_color = np.convolve(np.mean(image, axis=0), np.ones(interval), 'valid') / interval x_list = np.where(x_color[x_skip:] > 235)[0] @@ -128,9 +136,11 @@ class CampaignOcr: def get_stage_name(self, image): self.stage = {} buttons = self.extract_campaign_name_image(image) - # ocr = Digit(buttons) + ocr = Ocr(buttons, lang='stage') result = ocr.ocr(image) + if not isinstance(result, list): + result = [result] result = [res.lower().replace('--', '-') for res in result] chapter = [separate_name(res)[0] for res in result] @@ -142,12 +152,6 @@ class CampaignOcr: button.name = name self.stage[name] = button - # self.chapter = np.argmax(np.bincount(result[::2])) - # for stage, button in zip(result[1::2], buttons[1::2]): - # button.area = button.button - # button.name = f'STAGE_{self.chapter}_{stage}' - # self.stage[f'{self.chapter}-{stage}'] = button - logger.attr('Chapter', self.chapter) logger.attr('Stage', ', '.join(self.stage.keys())) diff --git a/module/handler/assets.py b/module/handler/assets.py index 405a498ea..f1ff4cec7 100644 --- a/module/handler/assets.py +++ b/module/handler/assets.py @@ -29,6 +29,7 @@ MAP_AIR_RAID = Button(area=(350, 447, 1280, 472), color=(154, 43, 46), button=(3 MAP_AMBUSH = Button(area=(261, 433, 1280, 449), color=(161, 41, 43), button=(261, 433, 1280, 449), file='./assets/handler/MAP_AMBUSH.png') MAP_AMBUSH_EVADE = Button(area=(325, 393, 1280, 395), color=(255, 255, 255), button=(979, 444, 1152, 502), file='./assets/handler/MAP_AMBUSH_EVADE.png') MAP_BUFF = Button(area=(145, 115, 437, 159), color=(103, 118, 118), button=(145, 115, 437, 159), file='./assets/handler/MAP_BUFF.png') +MAP_CLEAR_PERCENTAGE = Button(area=(626, 185, 970, 190), color=(245, 213, 88), button=(626, 185, 970, 190), file='./assets/handler/MAP_CLEAR_PERCENTAGE.png') MAP_ENEMY_SEARCHING = Button(area=(531, 320, 864, 382), color=(200, 99, 91), button=(531, 320, 864, 382), file='./assets/handler/MAP_ENEMY_SEARCHING.png') MAP_GREEN = Button(area=(195, 260, 349, 292), color=(125, 190, 84), button=(195, 260, 349, 292), file='./assets/handler/MAP_GREEN.png') MAP_STAR_1 = Button(area=(245, 377, 254, 384), color=(251, 233, 143), button=(245, 377, 254, 384), file='./assets/handler/MAP_STAR_1.png') diff --git a/module/template/assets.py b/module/template/assets.py index 4f4dd3b70..4fbb536b4 100644 --- a/module/template/assets.py +++ b/module/template/assets.py @@ -15,3 +15,4 @@ TEMPLATE_FORMATION_1 = Template(file='./assets/template/TEMPLATE_FORMATION_1.png TEMPLATE_FORMATION_2 = Template(file='./assets/template/TEMPLATE_FORMATION_2.png') TEMPLATE_FORMATION_3 = Template(file='./assets/template/TEMPLATE_FORMATION_3.png') TEMPLATE_STAGE_CLEAR = Template(file='./assets/template/TEMPLATE_STAGE_CLEAR.png') +TEMPLATE_STAGE_PERCENT = Template(file='./assets/template/TEMPLATE_STAGE_PERCENT.png')