将NumberRecognizer移入recog,简化各处number写法

This commit is contained in:
Elaina 2024-10-27 16:26:58 +08:00
parent f084957e1e
commit 429f919d61
20 changed files with 101 additions and 501 deletions

View file

@ -4,7 +4,6 @@ import cv2
from scipy.signal import argrelmax
from skimage.metrics import structural_similarity
from mower.models import Digtal
from mower.solvers.navigation import NavigationSolver
from mower.utils import config
from mower.utils import typealias as tp
@ -70,32 +69,7 @@ class AutoFight(SceneGraphSolver):
def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别"
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().secret_front[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int("secret_front", scope, height, thres)
def cost(self) -> int:
"获取部署费用"

View file

@ -3,7 +3,6 @@ from scipy.signal import argrelmin
from skimage.metrics import structural_similarity
from mower.data import agent_list
from mower.models import Digtal
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.character_recognize import match_portrait
@ -115,32 +114,7 @@ class ChooseSupportSolver(SceneGraphSolver):
def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别"
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().secret_front[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int("secret_front", scope, height, thres)
def get_agent_progression(self, scope: tp.Scope) -> int:
"获取干员练度"

View file

@ -1,15 +1,11 @@
from datetime import datetime, timedelta
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.digit_reader import DigitReader
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.log import logger
from mower.utils.recognize import Scene
@ -59,32 +55,7 @@ class DroneSolver(SceneGraphSolver, BaseMixin):
def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别"
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().riic_base_digits[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int("riic_base", scope, height, thres)
def timeout(self) -> bool:
return datetime.now() > self.start_time + timedelta(seconds=20)

View file

@ -2,7 +2,6 @@ from datetime import datetime, timedelta
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config
@ -55,26 +54,10 @@ class GetAgentFromRoomSolver(SceneGraphSolver, BaseMixin):
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
img = cv2.bitwise_not(img)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(1, 6):
im = Digtal().riic_base_digits[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = score.index(min(score)) + 1
return value
return (
config.recog.num.number_int("riic_base", img=img, target_range=range(1, 6))
+ 1
)
@staticmethod
def is_power_station() -> bool:

View file

@ -1,14 +1,10 @@
from datetime import datetime, timedelta
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.log import logger
from mower.utils.recognize import Scene
@ -29,34 +25,10 @@ class GetOrderRemainingTimeSolver(SceneGraphSolver, BaseMixin):
def number(self, scope: tp.Scope, height: int, thres: int) -> str:
"数字识别"
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = ""
for x, y, w, h in rect:
if h < 10 and w < 10:
value += ":"
continue
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().riic_base_digits[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value += str(score.index(min(score)))
return value
rect_limits = [{"w": 10, "h": 10, "char": ":"}]
return config.recog.num.number(
"riic_base", scope, height, thres, rect_limits=rect_limits
)
def read_remain_time(self, pos) -> int:
h, m, s = self.number(pos, 19, 115).split("::")

View file

@ -1,15 +1,11 @@
from datetime import datetime, timedelta
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.email import send_message
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.log import logger
from mower.utils.recognize import Scene
@ -35,32 +31,7 @@ class ReloadSolver(SceneGraphSolver, BaseMixin):
def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别"
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().riic_base_digits[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int("riic_base", scope, height, thres)
def transition(self) -> bool:
if (scene := self.scene()) == Scene.INFRA_DETAILS:

View file

@ -5,7 +5,6 @@ from sqlalchemy import Column, Date, Integer, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from mower.models import Digtal
from mower.utils import config
from mower.utils.digit_reader import DigitReader
from mower.utils.email import report_template, send_message
@ -183,25 +182,7 @@ class ReportSolver(SceneGraphSolver):
scale = default_height / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().noto_sans[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int("noto", img=img)
def get_report_data(self):
# 连接数据库

View file

@ -1,12 +1,8 @@
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.recognize import Scene
@ -30,34 +26,10 @@ class ReadOriginalOrderRemainTimeSolver(SceneGraphSolver, BaseMixin):
def number(self, scope: tp.Scope, height: int, thres: int) -> str:
"数字识别"
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = ""
for x, y, w, h in rect:
if h < 7 and w < 7:
value += ":"
continue
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().riic_base_digits[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value += str(score.index(min(score)))
return value
rect_limits = [{"w": 7, "h": 7, "char": ":"}]
return config.recog.num.number(
"riic_base", scope, height, thres, rect_limits=rect_limits
)
def read_remain_time(self) -> int:
h, m, s = self.number(((758, 670), (960, 705)), 30, 100).split("::")

View file

@ -1,6 +1,3 @@
import cv2
from mower.models import Digtal
from mower.solvers.fight.battle_choose.battle_fill_choose import BattleFillChooseSolver
from mower.solvers.infra.base_mixin import BaseMixin
from mower.utils import config
@ -8,7 +5,6 @@ from mower.utils import typealias as tp
from mower.utils.character_recognize import match_portrait
from mower.utils.email import assistants_template, send_message
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.log import logger
from mower.utils.recognize import Scene
@ -65,38 +61,7 @@ class SwitchAssistantsSolver(SceneGraphSolver, BaseMixin):
def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别"
try:
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(
img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
rect = rect[:-3]
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().noto_sans[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
except Exception:
return 0
return config.recog.num.number_int("noto", scope, height, thres, rect_ed=-3)
def transition(self) -> bool:
if (scene := self.scene()) == Scene.RIIC_REPORT:

View file

@ -2,7 +2,6 @@ from datetime import datetime
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.drone import DroneSolver
from mower.solvers.infra.enter_room import EnterRoomSolver
@ -85,30 +84,8 @@ class SwitchProductSolver(SceneGraphSolver, BaseMixin):
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
img = cv2.bitwise_not(img)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = ""
for x, y, w, h in rect:
if h < 8 and w < 8:
value += "."
continue
elif h < 20 and w < 20:
continue
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().riic_base_digits[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value += str(score.index(min(score)))
return value
rect_limits = [{"w": 20, "h": 20, "char": ""}, {"w": 8, "h": 8, "char": "."}]
return config.recog.num.number("riic_base", img=img, rect_limits=rect_limits)
def read_speed(self) -> float:
speed1 = self.number(((1185, 955), (1255, 977)), 17, 120)

View file

@ -1,14 +1,11 @@
from datetime import datetime, timedelta
import cv2
from mower.models import Digtal
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.email import send_message
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cmatch, cropimg, loadres, thres2
from mower.utils.image import cmatch, cropimg, loadres
from mower.utils.log import logger
from mower.utils.recognize import Scene
@ -55,32 +52,7 @@ class ChooseProductSolver(SceneGraphSolver):
def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别"
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().riic_base_digits[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int("riic_base", scope, height, thres)
def transition(self) -> bool:
if (scene := self.scene()) == Scene.INFRA_DETAILS:

View file

@ -1,12 +1,8 @@
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.recognize import Scene
@ -30,34 +26,10 @@ class GetRemainTimeSolver(SceneGraphSolver, BaseMixin):
def number(self, scope: tp.Scope, height: int, thres: int) -> str:
"数字识别"
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = ""
for x, y, w, h in rect:
if h < 7 and w < 7:
value += ":"
continue
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().riic_base_digits[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value += str(score.index(min(score)))
return value
rect_limits = [{"w": 7, "h": 7, "char": ":"}]
return config.recog.num.number(
"riic_base", scope, height, thres, rect_limits=rect_limits
)
def read_remain_time(self) -> int:
h, m, s = self.number(((758, 670), (960, 705)), 30, 100).split("::")

View file

@ -4,13 +4,12 @@ from typing import Optional
import cv2
from mower.models import Digtal
from mower.solvers.navigation.utils import generate_name
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.datetime import get_server_weekday
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, diff_ratio, loadimg, thres2
from mower.utils.image import cropimg, diff_ratio, loadimg
from mower.utils.log import logger
from mower.utils.path import get_path
from mower.utils.recognize import Scene
@ -27,33 +26,10 @@ class OperationSolver(SceneGraphSolver):
super().run()
def number(self, scope: tp.Scope, height: Optional[int] = None):
img = cropimg(config.recog.gray, scope)
if height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, 127)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
if w < 5 or h < 5:
continue
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().secret_front[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
rect_limits = [{"w": 5, "h": 5, "char": ""}]
return config.recog.num.number_int(
"secret_front", scope, height, rect_limits=rect_limits
)
def drop_animation(self) -> bool:
drop_scope = (100, 775), (1920, 945)

View file

@ -99,24 +99,7 @@ class OperatorSolver(SceneGraphSolver):
img = cropimg(img, ((1334, 175), (1456, 249)))
scale = 25 / 73
img = cv2.resize(img, None, None, scale, scale)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().secret_front[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int("secret_front", img=img)
def elite(self):
img = cropimg(config.recog.gray, ((1320, 372), (1454, 451)))

View file

@ -8,7 +8,7 @@ from mower.utils import typealias as tp
from mower.utils.csleep import MowerExit
from mower.utils.email import send_message
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.image import cropimg
from mower.utils.log import logger
from mower.utils.scene import Scene
from mower.utils.vector import sa, va
@ -80,31 +80,7 @@ class SecretFront(SceneGraphSolver):
self.actions[page] = {}
def number(self, scope: tp.Scope, height: int | None = None):
img = cropimg(config.recog.gray, scope)
if height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, 127)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().secret_front[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int("secret_front", scope, height)
def card_pos(self, total, idx):
if total == 3:

View file

@ -1,6 +1,6 @@
import cv2
from mower.models import Digtal, shop
from mower.models import shop
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.graph import SceneGraphSolver
@ -41,36 +41,15 @@ class CreditShop(SceneGraphSolver):
img = cropimg(config.recog.gray, scope)
if font == "riic_base":
templates = Digtal().riic_base_digits
default_height = 28
else:
templates = Digtal().noto_sans
default_height = 29
if height and height != default_height:
scale = default_height / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = templates[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int(font, img=img)
def credit_remain(self):
credits = self.number(((1700, 39), (1800, 75)), "riic_base", thres=180)

View file

@ -7,7 +7,6 @@ from scipy.signal import argrelmax
from skimage.metrics import structural_similarity
from mower.data import agent_list
from mower.models import Digtal
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.character_recognize import match_avatar
@ -103,37 +102,7 @@ class SSSFightSolver(SceneGraphSolver):
def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别"
try:
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(
img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().secret_front[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
except Exception:
return 0
return config.recog.num.number_int("secret_front", scope, height, thres)
def cost(self) -> int:
"获取部署费用"

View file

@ -3,10 +3,9 @@ import numpy as np
from PIL import Image, ImageDraw, ImageFont
from mower import __rootdir__
from mower.models import Digtal
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.image import cropimg, thres2
from mower.utils.image import cropimg
def generate_image(text: str, font_size: int) -> tp.GrayImage:
@ -79,32 +78,7 @@ translate2 = {
def number(scope: tp.Scope, height: int, thres: int) -> int:
"数字识别"
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = [cv2.boundingRect(c) for c in contours]
rect.sort(key=lambda c: c[0])
rect = rect[:-3]
value = 0
for x, y, w, h in rect:
digit = cropimg(img, ((x, y), (x + w, y + h)))
digit = cv2.copyMakeBorder(
digit, 10, 10, 10, 10, cv2.BORDER_CONSTANT, None, (0,)
)
score = []
for i in range(10):
im = Digtal().secret_front[i]
result = cv2.matchTemplate(digit, im, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(min_val)
value = value * 10 + score.index(min(score))
return value
return config.recog.num.number_int("secret_front", scope, height, thres, rect_ed=-3)
def is_full() -> bool:

View file

@ -3,9 +3,9 @@ from typing import Literal
import cv2
from mower.models import Digtal
from . import typealias as tp
from .image import cropimg
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.image import cropimg, thres2
class NumberRecognizer:
@ -71,3 +71,54 @@ class NumberRecognizer:
value += str(score.index(min(score)))
return value
def number(
self,
font: Literal["riic_base", "noto", "secret_front"] = "noto",
scope: tp.Scope | None = None,
height: int = 25,
thres: int = 127,
img: tp.GrayImage | None = None,
rect_st: int | None = None,
rect_ed: int | None = None,
rect_limits: list[dict] = [],
target_range: list = range(10),
) -> str:
try:
if img is None:
img = cropimg(config.recog.gray, scope)
default_height = 25
if height != default_height:
scale = 25 / height
img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres)
rect = self.segment(img)
rect = self.filter_rectangles(rect, rect_st, rect_ed, rect_limits)
return self.number_match(img, rect, font, target_range)
except Exception:
return ""
def number_int(
self,
font: Literal["riic_base", "noto", "secret_front"] = "noto",
scope: tp.Scope | None = None,
height: int = 25,
thres: int = 127,
img: tp.GrayImage | None = None,
rect_st: int | None = None,
rect_ed: int | None = None,
rect_limits: list[dict] = [],
target_range: list = range(10),
) -> int:
res = self.number(
font,
scope,
height,
thres,
img,
rect_st,
rect_ed,
rect_limits,
target_range,
)
return int(res) if res else 0

View file

@ -12,6 +12,7 @@ from mower.utils.csleep import MowerExit
from mower.utils.image import bytes2img, cmatch, cropimg, loadres, thres2
from mower.utils.log import logger
from mower.utils.matcher import Matcher
from mower.utils.number import NumberRecognizer
from mower.utils.scene import Scene, SceneComment
from mower.utils.vector import va
@ -36,6 +37,7 @@ class Recognizer:
self._gray = None
self._hsv = None
self._matcher = None
self._num = None
self.scene = Scene.UNDEFINED
@property
@ -62,6 +64,12 @@ class Recognizer:
self._matcher = Matcher(self.gray)
return self._matcher
@property
def num(self):
if self._num is None:
self._num = NumberRecognizer()
return self._num
def start(self, screencap: Optional[bytes] = None) -> None:
"""init with screencap"""
retry_times = config.MAX_RETRYTIME