mirror of
https://gitee.com/sui-feng-cb/AzurLaneAutoScript1
synced 2026-03-09 18:39:04 +08:00
Add: plane statistics method Upd: config MoveDownTime for 15-1 daemon and battle time in plane statistics Opt: StopCondition RunCount for daemon 15-1 Opt: save screenshot in quit menu Fix: use uiautomator2 long_click and pause retry
144 lines
5.0 KiB
Python
144 lines
5.0 KiB
Python
import csv
|
|
from tqdm import tqdm
|
|
|
|
from module.base.button import ButtonGrid
|
|
from module.base.decorator import cached_property, run_once
|
|
from module.base.utils import load_image
|
|
from module.combat.assets import BATTLE_TIME
|
|
from module.daemon.daemon_15_1 import BattleTime as BattleTime_
|
|
from module.logger import logger
|
|
from module.ocr.al_ocr import AlOcr
|
|
from module.ocr.ocr import Ocr, Digit
|
|
from module.statistics.utils import *
|
|
|
|
|
|
class BattleTime(BattleTime_):
|
|
@staticmethod
|
|
def parse_time(string):
|
|
return string
|
|
|
|
|
|
class PlaneOcr(Digit):
|
|
def __init__(self, buttons, lang='azur_lane', letter=(255, 251, 247), threshold=128, alphabet='0123456789IDSBX',
|
|
name=None):
|
|
super().__init__(buttons, lang=lang, letter=letter, threshold=threshold, alphabet=alphabet, name=name)
|
|
|
|
def after_process(self, result):
|
|
result = result.replace('X', '') if 'X' in result else '0'
|
|
result = super().after_process(result)
|
|
return result
|
|
|
|
|
|
class PlaneStatistics:
|
|
DROP_FOLDER = './screenshots'
|
|
CNOCR_CONTEXT = 'cpu'
|
|
CSV_FILE = 'drop_result.csv'
|
|
CSV_OVERWRITE = True
|
|
CSV_ENCODING = 'utf-8'
|
|
PLANE_ROWS = 7
|
|
PLANE_GRID = ButtonGrid(origin=(1230, 90), button_shape=(48, 30), grid_shape=(1, 7), delta=(0, 43))
|
|
|
|
def __init__(self):
|
|
AlOcr.CNOCR_CONTEXT = PlaneStatistics.CNOCR_CONTEXT
|
|
Ocr.SHOW_LOG = False
|
|
self.PLANE_GRID.grid_shape = (1, self.PLANE_ROWS)
|
|
self.place_ocr_model = PlaneOcr(self.PLANE_GRID.buttons)
|
|
self.time_ocr_model = BattleTime(BATTLE_TIME)
|
|
|
|
@property
|
|
def csv_file(self):
|
|
return os.path.join(PlaneStatistics.DROP_FOLDER, PlaneStatistics.CSV_FILE)
|
|
|
|
@staticmethod
|
|
def drop_folder(campaign):
|
|
return os.path.join(PlaneStatistics.DROP_FOLDER, campaign)
|
|
|
|
@cached_property
|
|
def csv_overwrite_check(self):
|
|
"""
|
|
Remove existing csv file. This method only run once.
|
|
"""
|
|
if PlaneStatistics.CSV_OVERWRITE:
|
|
if os.path.exists(self.csv_file):
|
|
logger.info(f'Remove existing csv file: {self.csv_file}')
|
|
os.remove(self.csv_file)
|
|
return True
|
|
|
|
@staticmethod
|
|
@run_once
|
|
def csv_write_column_name(writer, columns):
|
|
writer.writerows([columns])
|
|
|
|
def parse_plane(self, file):
|
|
ts = os.path.splitext(os.path.basename(file))[0]
|
|
campaign = os.path.basename(os.path.abspath(os.path.join(file, '../')))
|
|
campaign = campaign.replace('campaign_', '')
|
|
images = unpack(load_image(file))
|
|
image = images[0]
|
|
plane = self.place_ocr_model.ocr(image)
|
|
time = self.time_ocr_model.ocr(image)
|
|
yield ['\'' + ts, campaign, str(plane), sum(plane), time]
|
|
|
|
def extract_plane(self, campaign):
|
|
"""
|
|
Extract images from a given folder.
|
|
|
|
Args:
|
|
campaign (str):
|
|
"""
|
|
print('')
|
|
logger.hr(f'extract plane statistics from {campaign}', level=1)
|
|
_ = self.csv_overwrite_check
|
|
|
|
with open(self.csv_file, 'a', newline='', encoding=PlaneStatistics.CSV_ENCODING) as csv_file:
|
|
writer = csv.writer(csv_file)
|
|
self.csv_write_column_name(writer, ['截图文件名称', '关卡名称', 'ocr识别结果', '飞机总数', '右上角时间'])
|
|
for ts, file in tqdm(load_folder(self.drop_folder(campaign)).items()):
|
|
try:
|
|
rows = self.parse_plane(file)
|
|
writer.writerows(rows)
|
|
except ImageError as e:
|
|
logger.warning(e)
|
|
continue
|
|
except Exception as e:
|
|
logger.exception(e)
|
|
logger.warning(f'Error on image {ts}')
|
|
continue
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# Drop screenshot folder. Default to './screenshots'
|
|
# 截图文件夹名称
|
|
PlaneStatistics.DROP_FOLDER = './screenshots'
|
|
# 'cpu' or 'gpu', default to 'cpu'.
|
|
# Use 'gpu' for faster prediction, but you must have the gpu version of mxnet installed.
|
|
PlaneStatistics.CNOCR_CONTEXT = 'cpu'
|
|
# Name of the output csv file.
|
|
# This will write to {DROP_FOLDER}/{CSV_FILE}.
|
|
# 结果文件名称
|
|
PlaneStatistics.CSV_FILE = 'plane_result.csv'
|
|
# If True, remove existing file before extraction.
|
|
# 是否覆写csv
|
|
PlaneStatistics.CSV_OVERWRITE = True
|
|
# Usually to be 'utf-8'.
|
|
# For better Chinese export to Excel, use 'gbk'.
|
|
PlaneStatistics.CSV_ENCODING = 'gbk'
|
|
# Default to be 7.
|
|
# This will change the ocr of rows of plane.
|
|
# 飞机识别行数(最多有几行飞机)
|
|
PlaneStatistics.PLANE_ROWS = 9
|
|
# campaign names to export under DROP_FOLDER.
|
|
# This will load {DROP_FOLDER}/{CAMPAIGN}.
|
|
# Just a demonstration here, you should modify it to your own.
|
|
# 关卡名称(截图文件夹内的需要识别图片的文件夹的名称)
|
|
CAMPAIGNS = ['campaign_15_1']
|
|
|
|
stat = PlaneStatistics()
|
|
|
|
"""
|
|
Step 1:
|
|
Run this code.
|
|
"""
|
|
for i in CAMPAIGNS:
|
|
stat.extract_plane(i)
|