Skip to content

Commit

Permalink
Merge pull request #438 from EightyDollars/dev_shawn
Browse files Browse the repository at this point in the history
fix: 修复部分错误
  • Loading branch information
ZhaoZuohong authored Dec 12, 2023
2 parents adf6ad7 + 6ea2d15 commit c5dff67
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 50 deletions.
2 changes: 1 addition & 1 deletion arknights_mower/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .utils.param import ParamError, parse_operation_params


def mail(args: list[str] = [], device: Device = None):
def mail(device: Device = None):
"""
mail
自动收取邮件
Expand Down
6 changes: 5 additions & 1 deletion arknights_mower/data/ocr.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"新羊": "新手",
"技巧概要卷1": "技巧概要·卷1",
"技巧概要卷2": "技巧概要·卷2",
"龙门市": "龙门币",
"医疗千员": "医疗干员",
"医疗午员": "医疗干员",
"先锋千员": "先锋干员",
Expand All @@ -22,9 +23,12 @@
"资深千员": "资深干员",
"聚酸醋": "聚酸酯",
"醋原料": "酯原料",
"龙门市": "龙门币",
"酮爆集": "酮凝集",
"雨凝集": "酮凝集",
"米营": "",
"米唐": "",
"特唐": "",
"特惠": "",
"租击干员": "狙击干员",
"612F": "12F",
"S12F": "12F",
Expand Down
4 changes: 4 additions & 0 deletions arknights_mower/ocr/rectify.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ def ocr_rectify(img, pre, valid, text=''):
ocr_error[pre_res] = res
pre_res = res
return pre_res


def ocr_rectify_shop(pre):
return ocr_error[pre]
Binary file modified arknights_mower/resources/recruit_ticket/0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 6 additions & 4 deletions arknights_mower/solvers/base_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -2308,11 +2308,13 @@ def skland_plan_solover(self):
return SKLand(self.skland_config['skland_info']).start()
except(RuntimeError, ConnectionError, ConnectionAbortedError, AttributeError) as re:
self.send_message(f"森空岛签到失败: {re}")
logger.warning(f"森空岛签到失败:{re}")
except Exception as e:
self.send_message(f"森空岛签到失败: {e}")
logger.warning(f"森空岛签到失败:{e}")
except:
self.send_message(f"森空岛签到失败")
logger.warning("森空岛签到失败")
logger.warning("森空岛签到失败:{unknown reason}")
# 仅尝试一次 不再尝试
return (datetime.now() - timedelta(hours=4)).date()

Expand All @@ -2321,15 +2323,15 @@ def recruit_plan_solver(self):
or self.recruit_config['last_execution'] is None
or self.recruit_config['last_execution'] <= (
datetime.now() - timedelta(seconds=self.recruit_config['recruit_execution_gap'] * 3600))):
recruit([], self.send_message_config, self.recruit_config)
recruit([], self.send_message_config, self.recruit_config, self.device)
self.recruit_config['last_execution'] = datetime.now()
logger.info("下一次公开招募执行时间在{}小时之后".format(self.recruit_config['recruit_execution_gap']))

def mail_plan_solver(self):
if self.check_mail_enable:
mail()
mail(self.device)
return True

def report_plan_solver(self):
if self.report_enable:
return daily_report()
return daily_report(self.device)
114 changes: 76 additions & 38 deletions arknights_mower/solvers/shop.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from ..data import shop_items
from ..ocr import ocr_rectify, ocrhandle
from ..utils import segment
from ..utils import segment, rapidocr
from ..utils.device import Device
from ..utils.digit_reader import DigitReader
from ..utils.image import scope2slice, loadimg
Expand All @@ -26,6 +26,7 @@ class ShopSolver(BaseSolver):
def __init__(self, device: Device = None, recog: Recognizer = None) -> None:
super().__init__(device, recog)
self.item_list = {}
rapidocr.initialize_ocr()
self.sold_template = loadimg(f"{__rootdir__}/resources/sold_out.png")
self.credit_icon = loadimg(f"{__rootdir__}/resources/credit_icon.png")
self.spent_credit = loadimg(f"{__rootdir__}/resources/spent_credit.png")
Expand All @@ -46,6 +47,11 @@ def __init__(self, device: Device = None, recog: Recognizer = None) -> None:
self.sold_price_number[item.replace(".png", "")] = loadimg(
f"{__rootdir__}/resources/sold_price_number/{item}")

self.left_credit_template = {}
for item in os.listdir(f"{__rootdir__}//resources/recruit_ticket"):
self.left_credit_template[item.replace(".png", "")] = loadimg(
f"{__rootdir__}/resources/recruit_ticket/{item}")

self.shop_data = {}

def run(self, priority: list[str] = None) -> None:
Expand Down Expand Up @@ -101,57 +107,60 @@ def shop_credit(self) -> bool:
self.shop_data["credit"] = self.get_credits()
for i in range(len(segments)):
scope = (
segments[i][0], (segments[i][1][0], segments[i][0][1] + (segments[i][1][1] - segments[i][0][1]) // 4))
segments[i][0], (segments[i][1][0], segments[i][0][1] + (segments[i][1][1] - segments[i][0][1]) // 5))
ocr = ocrhandle.predict(self.recog.img[scope2slice(scope)])
# cv2.imshow("ocr",self.recog.img[scope2slice(scope)])
# cv2.waitKey()
if len(ocr) == 0:
raise RecognizeError
ocr = ocr[0]

if ocr[1] not in list(shop_items.keys()):
ocr[1] = ocr_rectify(self.recog.img[scope2slice(scope)], ocr, shop_items, '物品名称')
rapid_res = rapidocr.engine(self.recog.img[scope2slice(scope)], use_det=False, use_cls=False, use_rec=True)[0][0][0]
if rapid_res in list(shop_items.keys()):
ocr[1] = rapid_res
else:
ocr[1] = ocr_rectify(self.recog.img[scope2slice(scope)], ocr, shop_items, '物品名称')

shop_sold, discount = self.get_discount(
self.recog.img[segments[i][0][1]:segments[i][1][1], segments[i][0][0]:segments[i][1][0]])

item_name = ocr[1]
# if item_name == '龙门币':
# price = self.get_item_price(
# self.recog.img[segments[i][0][1]:segments[i][1][1], segments[i][0][0]:segments[i][1][0]], shop_sold)
# price = round(price / (1 - discount * 0.01), 0)
# if price == 200:
# item_name = "龙门币(大)"
# elif price == 100:
# item_name = "龙门币(小)"
# elif item_name == '家具零件':
# price = self.get_item_price(
# self.recog.img[segments[i][0][1]:segments[i][1][1], segments[i][0][0]:segments[i][1][0]], shop_sold)
# price = round(price / (1 - discount * 0.01), 0)
# if price == 200:
# item_name = "家具零件(大)"
# elif price == 160:
# item_name = "家具零件(小)"
if not shop_sold:
self.item_list[i] = {
'index': i,
'name': item_name,
'discount': discount,
'shop_sold': shop_sold,
'position': segments[i],
'price': round(float(shop_items[item_name]) / (1 - discount * 0.01), 0)
}

if item_name == '龙门币':
price = self.get_item_price(
self.recog.img[segments[i][0][1]:segments[i][1][1], segments[i][0][0]:segments[i][1][0]], shop_sold)
price = round(price / (1 - discount * 0.01), 0)
if price == 200:
item_name = "龙门币(大)"
elif price == 100:
item_name = "龙门币(小)"
elif item_name == '家具零件':
price = self.get_item_price(
self.recog.img[segments[i][0][1]:segments[i][1][1], segments[i][0][0]:segments[i][1][0]], shop_sold)
price = round(price / (1 - discount * 0.01), 0)
if price == 200:
item_name = "家具零件(大)"
elif price == 160:
item_name = "家具零件(小)"
self.item_list[i] = {
'index': i,
'name': item_name,
'discount': discount,
'shop_sold': shop_sold,
'position': segments[i],
'price': round(float(shop_items[item_name]) / (1 - discount * 0.01), 0)
}
self.shop_data["item"] = sorted(self.item_list.values(), key=lambda x: x['price'], reverse=True)
logger.info("购买顺序:{}".format([f"{item['index']+1}:{item['name']}" for item in self.shop_data["item"]]))

logger.info("购买顺序:{}".format([f"{item['index'] + 1}:{item['name']}" for item in self.shop_data["item"]]))
return True
# self.tap_element("agent_unlock")

def get_discount(self, item_img: np.ndarray):
if self.is_sold(item_img):
for key in self.discount:
res = cv2.matchTemplate(item_img,
self.discount_sold[key], cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
if max_val > 0.95:
if max_val > 0.85:
return True, int(key)
return True, 0
else:
Expand All @@ -160,6 +169,7 @@ def get_discount(self, item_img: np.ndarray):
self.discount[key], cv2.TM_CCOEFF_NORMED)

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

if max_val > 0.8:
return False, int(key)
return False, 0
Expand All @@ -177,18 +187,21 @@ def get_credits(self):
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
h, w = self.credit_icon.shape[:-1]
p0 = [max_loc[0] + w, max_loc[1]]
p1 = [p0[0] + 80, p0[1] + 40]
p1 = [p0[0] + 120, p0[1] + 50]

return self.digitReader.get_recruit_ticket(self.recog.img[p0[1]:p1[1], p0[0]:p1[0]])
res = self.digitReader.get_recruit_ticket(self.recog.img[p0[1]:p1[1], p0[0]:p1[0]])
cv2.putText(self.recog.img,
"{}".format(self.digitReader.get_recruit_ticket(self.recog.img[p0[1]:p1[1], p0[0]:p1[0]])),
(p0[0], p0[1]), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
return res

def get_spent_credits(self):
res = cv2.matchTemplate(self.recog.img, self.spent_credit, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
h, w = self.spent_credit.shape[:-1]
p0 = [max_loc[0] + w, max_loc[1]]
p1 = [p0[0] + 200, p0[1] + 60]
self.shop_data["spent_credits"] = self.digitReader.get_creidt_number(self.recog.img[p0[1]:p1[1], p0[0]:p1[0]])
logger.info(self.shop_data)
self.shop_data["spent_credits"] = self.digitReader.get_credict_number(self.recog.img[p0[1]:p1[1], p0[0]:p1[0]])
return True

def get_item_price(self, item_img: np.ndarray, is_sold: False):
Expand All @@ -199,14 +212,15 @@ def get_item_price(self, item_img: np.ndarray, is_sold: False):
h, w = self.item_credit_icon.shape[:-1]
p0 = [max_loc[0] + w, max_loc[1]]
p1 = [p0[0] + 140, p0[1] + 40]

return self.get_sold_number(item_img[p0[1]:p1[1], p0[0]:p1[0]])
else:
res = cv2.matchTemplate(item_img, self.item_credit_icon, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
h, w = self.item_credit_icon.shape[:-1]
p0 = [max_loc[0] + w, max_loc[1]]
p1 = [p0[0] + 140, p0[1] + 40]
return self.digitReader.get_creidt_number(item_img[p0[1]:p1[1], p0[0]:p1[0]])
return self.digitReader.get_credict_number(item_img[p0[1]:p1[1], p0[0]:p1[0]])

def get_sold_number(self, digit_part: np.ndarray):
result = {}
Expand All @@ -232,6 +246,30 @@ def get_sold_number(self, digit_part: np.ndarray):

return int("".join(l))

def get_left_credit(self, digit_part):
result = {}
digit_part = cv2.cvtColor(digit_part, cv2.COLOR_RGB2GRAY)

for j in range(10):
res = cv2.matchTemplate(
digit_part,
self.left_credit_template[j],
cv2.TM_CCORR_NORMED,
)
threshold = 0.94
loc = np.where(res >= threshold)
for i in range(len(loc[0])):
x = loc[1][i]
accept = True
for o in result:
if abs(o - x) < 5:
accept = False
break
if accept:
result[loc[1][i]] = j

l = [str(result[k]) for k in sorted(result)]
return int("".join(l))
# def shop_credit(self) -> bool:
# """ 购买物品逻辑 """
# segments = segment.credit(self.recog.img)
Expand Down
4 changes: 2 additions & 2 deletions arknights_mower/solvers/skland.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def test_connect(self):
for i in self.get_binding_list():
if i['uid']:
res.append("{}连接成功".format(i['nickName'] + "({})".format(i['channelName'])))
except:
res.append("{}无法连接".format(item['account']))
except Exception as e:
res.append("{}无法连接-{}".format(item['account'],e))

return res
4 changes: 3 additions & 1 deletion arknights_mower/utils/digit_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ def get_recruit_ticket(self, digit_part):
l = [str(result[k]) for k in sorted(result)]
return int("".join(l))

def get_creidt_number(self, digit_part):


def get_credict_number(self, digit_part):
result = {}
digit_part = cv2.cvtColor(digit_part, cv2.COLOR_RGB2GRAY)

Expand Down
4 changes: 2 additions & 2 deletions arknights_mower/utils/rapidocr.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
engine = None


def initialize_ocr():
def initialize_ocr(score=0.3):
global engine
if not engine:
from rapidocr_onnxruntime import RapidOCR

engine = RapidOCR(text_score=0.3)
engine = RapidOCR(text_score=score)
2 changes: 1 addition & 1 deletion arknights_mower/utils/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def ptp(j: int) -> int:
up_2 += 1

down = height - 1
while average(down) < 180:
while average(down) < 150:
down -= 1

right = width - 1
Expand Down

0 comments on commit c5dff67

Please sign in to comment.