def get_map_shape(self): # For EN only from string import whitespace ocr = Ocr(MAP_NAME, lang='cnocr', letter=(214, 235, 235), threshold=96, name='OCR_OS_MAP_NAME') name = ocr.ocr(self.device.image) name = name.translate(dict.fromkeys(map(ord, whitespace))) if '-' in name: name = name.split('-')[0] if 'é' in name: # Méditerranée name maps name = name.replace('é', 'e') if 'nvcity' in name: # NY City Port read as 'V' rather than 'Y' name = 'nycity' name = name.lower() logger.info(f'Map name processed: {name}') for index, chapter in DIC_OS_MAP.items(): cmp_name = chapter['en'].translate(dict.fromkeys(map(ord, whitespace))) cmp_name = cmp_name.lower() if name == cmp_name: self.os_map_name = chapter['en'] logger.info( f"Current OS map: {chapter['en']}, " f"id: {index}, shape: {chapter['shape']}, hazard_level: {chapter['hazard_level']}" ) return chapter['shape'] logger.warning('Unknown OS map') exit(1)
def _get_stage_name(self, image): self.stage_entrance = {} buttons = self.campaign_extract_name_image(image) ocr = Ocr(buttons, name='campaign', letter=(255, 255, 255), threshold=128, alphabet='0123456789ABCDEFSP-') result = ocr.ocr(image) if not isinstance(result, list): result = [result] result = [ocr_result_process(res) for res in result] chapter = [separate_name(res)[0] for res in result] counter = collections.Counter(chapter) self.campaign_chapter = counter.most_common()[0][0] for name, button in zip(result, buttons): button.area = button.button button.name = name self.stage_entrance[name] = button logger.attr('Chapter', self.campaign_chapter) logger.attr('Stage', ', '.join(self.stage_entrance.keys()))
def _get_stage_name(self, image): self.stage_entrance = {} buttons = self.campaign_extract_name_image(image) if len(buttons) == 0: logger.warning('No stage found.') ocr = Ocr(buttons, name='campaign', letter=(255, 255, 255), threshold=128, alphabet='0123456789ABCDEFGHIJKLMNPQRSTUVWXYZ-') result = ocr.ocr(image) if not isinstance(result, list): result = [result] result = [self._campaign_ocr_result_process(res) for res in result] chapter = [self._campaign_separate_name(res)[0] for res in result] chapter = list(filter(('').__ne__, chapter)) if not chapter: raise CampaignNameError counter = collections.Counter(chapter) self.campaign_chapter = counter.most_common()[0][0] for name, button in zip(result, buttons): button.area = button.button button.name = name self.stage_entrance[name] = button logger.attr('Chapter', self.campaign_chapter) logger.attr('Stage', ', '.join(self.stage_entrance.keys()))
def get_zone_name(self): # For JP only ocr = Ocr(MAP_NAME, lang='jp', letter=(214, 231, 255), threshold=127, name='OCR_OS_MAP_NAME') name = ocr.ocr(self.device.image) # Use '安' to split because there's no char '-' in jp ocr. # Kanji '一' and '力' are not used, while Katakana 'ー' and 'カ' are misread as Kanji sometimes. # Katakana 'ペ' may be misread as Hiragana 'ぺ'. name = name.split('安')[0].rstrip('安全海域').replace('一', 'ー').replace('力', 'カ').replace('ぺ', 'ペ') return name
def get_zone_name(self): # For CN only ocr = Ocr(MAP_NAME, lang='cnocr', letter=(214, 231, 255), threshold=127, name='OCR_OS_MAP_NAME') name = ocr.ocr(self.device.image) if '-' in name: name = name.split('-')[0] else: name = name.rstrip('安全海域-') return name
def commission_parse(self): # Name area = area_offset((176, 23, 420, 53), self.area[0:2]) button = Button(area=area, color=(), button=area, name='COMMISSION') ocr = Ocr(button, lang='cnocr', threshold=256) self.button = button self.name = ocr.ocr(self.image) self.genre = self.commission_name_parse(self.name) # Duration time area = area_offset((290, 68, 390, 95), self.area[0:2]) button = Button(area=area, color=(), button=area, name='DURATION') ocr = Ocr(button, alphabet='0123456789:') self.duration = self.parse_time(ocr.ocr(self.image)) # Expire time area = area_offset((-49, 68, -45, 84), self.area[0:2]) button = Button(area=area, color=(189, 65, 66), button=area, name='IS_URGENT') if button.appear_on(self.image): area = area_offset((-49, 67, 45, 94), self.area[0:2]) button = Button(area=area, color=(), button=area, name='EXPIRE') ocr = Ocr(button, alphabet='0123456789:') self.expire = self.parse_time(ocr.ocr(self.image)) else: self.expire = None # Status area = area_offset((179, 71, 187, 93), self.area[0:2]) dic = {0: 'finished', 1: 'running', 2: 'pending'} self.status = dic[int(np.argmax(get_color(self.image, area)))]
def get_research_duration_jp(image): """ Args: image (PIL.Image.Image): Screenshot Returns: duration (int): number of seconds """ ocr = Ocr(DURATION_DETAIL, alphabet='0123456789:') duration = parse_time(ocr.ocr(image)).total_seconds() return duration
def get_zone_name(self): # For TW only ocr = Ocr(MAP_NAME, lang='tw', letter=(198, 215, 239), threshold=127, name='OCR_OS_MAP_NAME') name = ocr.ocr(self.device.image) self.is_zone_name_hidden = '安全' in name # Remove '塞壬要塞海域' if '塞' in name: name = name.split('塞')[0] # Remove '安全海域', '隱秘海域', '深淵海域' at the end of tw ocr. name = name.rstrip('安全隱秘塞壬要塞深淵海域一') return name
def get_zone_name(self): # For EN only from string import whitespace ocr = Ocr(MAP_NAME, lang='cnocr', letter=(214, 235, 235), threshold=96, name='OCR_OS_MAP_NAME') name = ocr.ocr(self.device.image) name = name.translate(dict.fromkeys(map(ord, whitespace))) name = name.lower() if '-' in name: name = name.split('-')[0] if 'é' in name: # Méditerranée name maps name = name.replace('é', 'e') if 'nvcity' in name: # NY City Port read as 'V' rather than 'Y' name = 'nycity' return name
def _get_stage_name(self, image): """ Parse stage names from a given image. Set attributes: self.campaign_chapter: str, Name of current chapter. self.stage_entrance: dict. Key, str, stage name. Value, Button, button to enter stage. Args: image (np.ndarray): """ self.stage_entrance = {} del_cached_property(self, '_stage_image') del_cached_property(self, '_stage_image_gray') buttons = self.campaign_extract_name_image(image) if len(buttons) == 0: logger.info('No stage found.') raise CampaignNameError ocr = Ocr(buttons, name='campaign', letter=(255, 255, 255), threshold=128, alphabet='0123456789ABCDEFGHIJKLMNPQRSTUVWXYZ-') result = ocr.ocr(image) if not isinstance(result, list): result = [result] result = [self._campaign_ocr_result_process(res) for res in result] chapter = [self._campaign_separate_name(res)[0] for res in result] chapter = list(filter(('').__ne__, chapter)) if not chapter: raise CampaignNameError counter = collections.Counter(chapter) self.campaign_chapter = counter.most_common()[0][0] # After OCR, recover button attributes. # These buttons are ready to be stage entrances for `MapOperation.enter_map()` # button.area: Area of stage name, such as 'CLEAR' and '%'. # button.color: Color of stage icon. # button.button: Area of stage icon. # button.name: Stage name, from OCR results. for name, button in zip(result, buttons): button.area = button.button button.name = name self.stage_entrance[name] = button logger.attr('Chapter', self.campaign_chapter) logger.attr('Stage', ', '.join(self.stage_entrance.keys()))
def get_zone_name(self): # For JP only ocr = Ocr(MAP_NAME, lang='jp', letter=(214, 231, 255), threshold=127, name='OCR_OS_MAP_NAME') name = ocr.ocr(self.device.image) self.is_zone_name_hidden = '安全' in name # Remove punctuations for char in '・': name = name.replace(char, '') # Remove '異常海域' and 'セイレーン要塞海域' if '異' in name: name = name.split('異')[0] if 'セ' in name: name = name.split('セ')[0] # Remove '安全海域' or '秘密海域' at the end of jp ocr. name = name.rstrip('安全秘密異常要塞海域') # Kanji '一' and '力' are not used, while Katakana 'ー' and 'カ' are misread as Kanji sometimes. # Katakana 'ペ' may be misread as Hiragana 'ぺ'. name = name.replace('一', 'ー').replace('力', 'カ').replace('ぺ', 'ペ') return name
def get_map_shape(self): # For JP only ocr = Ocr(MAP_NAME, lang='jp', letter=(214, 231, 255), threshold=127, name='OCR_OS_MAP_NAME') name = ocr.ocr(self.device.image) # Use '安' to split because there's no char '-' in jp ocr. # Kanji '一' and '力' are not used, while Katakana 'ー' and 'カ' are misread as Kanji sometimes. name = name.split('安')[0].rstrip('安全海域').replace('一', 'ー').replace('力', 'カ') logger.info(f'Map name processed: {name}') for index, chapter in DIC_OS_MAP.items(): if name == chapter['jp']: self.os_map_name = name logger.info( f"Current OS map: {chapter['jp']}, " f"id: {index}, shape: {chapter['shape']}, hazard_level: {chapter['hazard_level']}" ) return chapter['shape'] logger.warning('Unknown OS map') exit(1)
def get_map_shape(self): # For CN only ocr = Ocr(MAP_NAME, lang='cnocr', letter=(235, 235, 235), threshold=160, name='OCR_OS_MAP_NAME') name = ocr.ocr(self.device.image) if '-' in name: name = name.split('-')[0] else: name = name.rstrip('安全海域-') logger.info(f'Map name processed: {name}') for index, chapter in DIC_OS_MAP.items(): if name == chapter['cn']: self.os_map_name = name logger.info( f"Current OS map: {chapter['cn']}, " f"id: {index}, shape: {chapter['shape']}, hazard_level: {chapter['hazard_level']}" ) return chapter['shape'] logger.warning('Unknown OS map') exit(1)
def commission_parse(self): # Name # This is different from CN, EN has longer names area = area_offset((176, 23, 420, 53), self.area[0:2]) button = Button(area=area, color=(), button=area, name='COMMISSION') ocr = Ocr(button, lang='cnocr') self.button = button self.name = ocr.ocr(self.image) self.genre = self.commission_name_parse(self.name.upper()) # Suffix ocr = SuffixOcr(button, lang='azur_lane', letter=(255, 255, 255), threshold=128, alphabet='IV') self.suffix = self.beautify_name(ocr.ocr(self.image)) # Duration time area = area_offset((290, 68, 390, 95), self.area[0:2]) button = Button(area=area, color=(), button=area, name='DURATION') ocr = Duration(button) self.duration = ocr.ocr(self.image) # Expire time area = area_offset((-49, 68, -45, 84), self.area[0:2]) button = Button(area=area, color=(189, 65, 66), button=area, name='IS_URGENT') if button.appear_on(self.image, threshold=30): area = area_offset((-49, 67, 45, 94), self.area[0:2]) button = Button(area=area, color=(), button=area, name='EXPIRE') ocr = Duration(button) self.expire = ocr.ocr(self.image) else: self.expire = timedelta(seconds=0) # Status area = area_offset((179, 71, 187, 93), self.area[0:2]) dic = {0: 'finished', 1: 'running', 2: 'pending'} color = get_color(self.image, area) if self.genre == 'event_daily': color -= [50, 30, 20] self.status = dic[int(np.argmax(color))]
def commission_parse(self): # Name # This is different from CN, EN has longer names area = area_offset((176, 23, 420, 53), self.area[0:2]) button = Button(area=area, color=(), button=area, name='COMMISSION') ocr = Ocr(button, lang='cnocr') self.button = button self.name = ocr.ocr(self.image) self.genre = self.commission_name_parse(self.name.upper()) # Duration time area = area_offset((290, 68, 390, 95), self.area[0:2]) button = Button(area=area, color=(), button=area, name='DURATION') ocr = Ocr(button, alphabet='0123456789:') self.duration = self.parse_time(ocr.ocr(self.image)) # Expire time area = area_offset((-49, 68, -45, 84), self.area[0:2]) button = Button(area=area, color=(189, 65, 66), button=area, name='IS_URGENT') if button.appear_on(self.image): area = area_offset((-49, 67, 45, 94), self.area[0:2]) button = Button(area=area, color=(), button=area, name='EXPIRE') ocr = Ocr(button, alphabet='0123456789:') self.expire = self.parse_time(ocr.ocr(self.image)) else: self.expire = None # Status area = area_offset((179, 71, 187, 93), self.area[0:2]) dic = { 0: 'finished', 1: 'running', 2: 'pending' } color = get_color(self.image, area) # if self.genre == 'doa_daily': # color -= [50, 30, 20] self.status = dic[int(np.argmax(color))]
def after_process(self, raw): """ Returns: int: """ raw = super().after_process(raw) if not raw: result = 0 else: result = int(raw) return result AMOUNT_OCR = AmountOcr([], back=(-200, -200, -200), lang='digit', name='Amount_ocr') ENEMY_GENRE_OCR = Ocr(ENEMY_GENRE_BUTTON, lang='cnocr', use_binary=False, back=(127, 127, 127)) class ImageError(Exception): pass class ItemTemplate: def __init__(self, image): self.image = np.array(image) def match(self, image): res = cv2.matchTemplate(self.image, np.array(image), cv2.TM_CCOEFF_NORMED) _, similarity, _, _ = cv2.minMaxLoc(res) return similarity > TEMPLATE_THRESHOLD
from module.research.filter import Filter from module.research.preset import * from module.research.project_data import LIST_RESEARCH_PROJECT from module.statistics.utils import * from module.ui.ui import UI RESEARCH_ENTRANCE = [ ENTRANCE_1, ENTRANCE_2, ENTRANCE_3, ENTRANCE_4, ENTRANCE_5 ] RESEARCH_SERIES = [SERIES_1, SERIES_2, SERIES_3, SERIES_4, SERIES_5] OCR_RESEARCH = [ OCR_RESEARCH_1, OCR_RESEARCH_2, OCR_RESEARCH_3, OCR_RESEARCH_4, OCR_RESEARCH_5 ] OCR_RESEARCH = Ocr(OCR_RESEARCH, name='RESEARCH', threshold=64, alphabet='0123456789BCDEGHQTMIULRF-') RESEARCH_DETAIL_GENRE = [ DETAIL_GENRE_B, DETAIL_GENRE_C, DETAIL_GENRE_D, DETAIL_GENRE_E, DETAIL_GENRE_G, DETAIL_GENRE_H_0, DETAIL_GENRE_H_1, DETAIL_GENRE_Q, DETAIL_GENRE_T ] FILTER_REGEX = re.compile( '(s[123])?' '-?' '(neptune|monarch|ibuki|izumo|roon|saintlouis|seattle|georgia|kitakaze|azuma|friedrich|gascogne|champagne|cheshire|drake|mainz|odin)?' '(dr|pry)?' '([bcdeghqt])?' '-?' '(\d.\d|\d\d?)?') FILTER_ATTR = ('series', 'ship', 'ship_rarity', 'genre', 'duration')
def ocr_object(self): return Ocr(ENEMY_NAME, lang='cnocr', threshold=128, name='ENEMY_NAME')
def after_process(self, result): result = Ocr.after_process(self, result) # '100' detected as '00' on retrofit blueprint if result == '00': result = '100' return Digit.after_process(self, result.split())
from module.combat.assets import GET_ITEMS_1 from module.logger import logger from module.ocr.ocr import Ocr, Digit from module.reward.assets import * from module.ui.ui import UI, page_meowfficer, BACK_ARROW_DORM BUY_MAX = 15 BUY_PRIZE = 1500 MEOWFFICER = Ocr(OCR_MEOWFFICER, letter=(140, 113, 99), threshold=64, alphabet='0123456789/') MEOWFFICER_CHOOSE = Digit(OCR_MEOWFFICER_CHOOSE, letter=(140, 113, 99), threshold=64) MEOWDDICER_COINS = Digit(OCR_MEOWDDICER_COINS, letter=(99, 69, 41), threshold=64) class RewardMeowfficer(UI): def moew_choose(self, count): """ Pages: in: page_moewfficer out: MEOWFFICER_BUY Args: count (int): 0 to 15. Returns:
from module.ocr.ocr import Ocr from module.statistics.assets import ENEMY_NAME ENEMY_NAME_OCR = Ocr(ENEMY_NAME, lang='cnocr', threshold=128) class BattleStatusStatistics: def stats_battle_status(self, image): """ Args: image: Pillow image. Returns: str: Enemy name, such as '中型主力舰队'. """ result = ENEMY_NAME_OCR.ocr(image) # Delete wrong OCR result for letter in '-一个―~(': result = result.replace(letter, '') return result