将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 scipy.signal import argrelmax
from skimage.metrics import structural_similarity from skimage.metrics import structural_similarity
from mower.models import Digtal
from mower.solvers.navigation import NavigationSolver from mower.solvers.navigation import NavigationSolver
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp 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: def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别" "数字识别"
img = cropimg(config.recog.gray, scope) return config.recog.num.number_int("secret_front", scope, height, thres)
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
def cost(self) -> int: def cost(self) -> int:
"获取部署费用" "获取部署费用"

View file

@ -3,7 +3,6 @@ from scipy.signal import argrelmin
from skimage.metrics import structural_similarity from skimage.metrics import structural_similarity
from mower.data import agent_list from mower.data import agent_list
from mower.models import Digtal
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.character_recognize import match_portrait 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: def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别" "数字识别"
img = cropimg(config.recog.gray, scope) return config.recog.num.number_int("secret_front", scope, height, thres)
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
def get_agent_progression(self, scope: tp.Scope) -> int: def get_agent_progression(self, scope: tp.Scope) -> int:
"获取干员练度" "获取干员练度"

View file

@ -1,15 +1,11 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.digit_reader import DigitReader from mower.utils.digit_reader import DigitReader
from mower.utils.graph import SceneGraphSolver from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.log import logger from mower.utils.log import logger
from mower.utils.recognize import Scene 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: def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别" "数字识别"
img = cropimg(config.recog.gray, scope) return config.recog.num.number_int("riic_base", scope, height, thres)
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
def timeout(self) -> bool: def timeout(self) -> bool:
return datetime.now() > self.start_time + timedelta(seconds=20) return datetime.now() > self.start_time + timedelta(seconds=20)

View file

@ -2,7 +2,6 @@ from datetime import datetime, timedelta
import cv2 import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config from mower.utils import config
@ -55,26 +54,10 @@ class GetAgentFromRoomSolver(SceneGraphSolver, BaseMixin):
img = cv2.resize(img, None, None, scale, scale) img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres) img = thres2(img, thres)
img = cv2.bitwise_not(img) img = cv2.bitwise_not(img)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) return (
rect = [cv2.boundingRect(c) for c in contours] config.recog.num.number_int("riic_base", img=img, target_range=range(1, 6))
rect.sort(key=lambda c: c[0]) + 1
)
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
@staticmethod @staticmethod
def is_power_station() -> bool: def is_power_station() -> bool:

View file

@ -1,14 +1,10 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.graph import SceneGraphSolver from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.log import logger from mower.utils.log import logger
from mower.utils.recognize import Scene 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: def number(self, scope: tp.Scope, height: int, thres: int) -> str:
"数字识别" "数字识别"
img = cropimg(config.recog.gray, scope) rect_limits = [{"w": 10, "h": 10, "char": ":"}]
default_height = 25 return config.recog.num.number(
if height != default_height: "riic_base", scope, height, thres, rect_limits=rect_limits
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
def read_remain_time(self, pos) -> int: def read_remain_time(self, pos) -> int:
h, m, s = self.number(pos, 19, 115).split("::") h, m, s = self.number(pos, 19, 115).split("::")

View file

@ -1,15 +1,11 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.email import send_message from mower.utils.email import send_message
from mower.utils.graph import SceneGraphSolver from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.log import logger from mower.utils.log import logger
from mower.utils.recognize import Scene 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: def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别" "数字识别"
img = cropimg(config.recog.gray, scope) return config.recog.num.number_int("riic_base", scope, height, thres)
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
def transition(self) -> bool: def transition(self) -> bool:
if (scene := self.scene()) == Scene.INFRA_DETAILS: 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.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from mower.models import Digtal
from mower.utils import config from mower.utils import config
from mower.utils.digit_reader import DigitReader from mower.utils.digit_reader import DigitReader
from mower.utils.email import report_template, send_message from mower.utils.email import report_template, send_message
@ -183,25 +182,7 @@ class ReportSolver(SceneGraphSolver):
scale = default_height / height scale = default_height / height
img = cv2.resize(img, None, None, scale, scale) img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres) img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) return config.recog.num.number_int("noto", img=img)
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
def get_report_data(self): 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.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.graph import SceneGraphSolver from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.recognize import Scene 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: def number(self, scope: tp.Scope, height: int, thres: int) -> str:
"数字识别" "数字识别"
img = cropimg(config.recog.gray, scope) rect_limits = [{"w": 7, "h": 7, "char": ":"}]
default_height = 25 return config.recog.num.number(
if height != default_height: "riic_base", scope, height, thres, rect_limits=rect_limits
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
def read_remain_time(self) -> int: def read_remain_time(self) -> int:
h, m, s = self.number(((758, 670), (960, 705)), 30, 100).split("::") 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.fight.battle_choose.battle_fill_choose import BattleFillChooseSolver
from mower.solvers.infra.base_mixin import BaseMixin from mower.solvers.infra.base_mixin import BaseMixin
from mower.utils import config 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.character_recognize import match_portrait
from mower.utils.email import assistants_template, send_message from mower.utils.email import assistants_template, send_message
from mower.utils.graph import SceneGraphSolver from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.log import logger from mower.utils.log import logger
from mower.utils.recognize import Scene 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: def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别" "数字识别"
try: return config.recog.num.number_int("noto", scope, height, thres, rect_ed=-3)
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
def transition(self) -> bool: def transition(self) -> bool:
if (scene := self.scene()) == Scene.RIIC_REPORT: if (scene := self.scene()) == Scene.RIIC_REPORT:

View file

@ -2,7 +2,6 @@ from datetime import datetime
import cv2 import cv2
from mower.models import Digtal
from mower.solvers.infra.base_mixin import BaseMixin from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.drone import DroneSolver from mower.solvers.infra.drone import DroneSolver
from mower.solvers.infra.enter_room import EnterRoomSolver 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 = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres) img = thres2(img, thres)
img = cv2.bitwise_not(img) img = cv2.bitwise_not(img)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) rect_limits = [{"w": 20, "h": 20, "char": ""}, {"w": 8, "h": 8, "char": "."}]
rect = [cv2.boundingRect(c) for c in contours] return config.recog.num.number("riic_base", img=img, rect_limits=rect_limits)
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
def read_speed(self) -> float: def read_speed(self) -> float:
speed1 = self.number(((1185, 955), (1255, 977)), 17, 120) speed1 = self.number(((1185, 955), (1255, 977)), 17, 120)

View file

@ -1,14 +1,11 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
import cv2
from mower.models import Digtal
from mower.solvers.infra.enter_room import EnterRoomSolver from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.email import send_message from mower.utils.email import send_message
from mower.utils.graph import SceneGraphSolver 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.log import logger
from mower.utils.recognize import Scene from mower.utils.recognize import Scene
@ -55,32 +52,7 @@ class ChooseProductSolver(SceneGraphSolver):
def number(self, scope: tp.Scope, height: int, thres: int) -> int: def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别" "数字识别"
img = cropimg(config.recog.gray, scope) return config.recog.num.number_int("riic_base", scope, height, thres)
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
def transition(self) -> bool: def transition(self) -> bool:
if (scene := self.scene()) == Scene.INFRA_DETAILS: 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.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.graph import SceneGraphSolver from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, thres2
from mower.utils.recognize import Scene 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: def number(self, scope: tp.Scope, height: int, thres: int) -> str:
"数字识别" "数字识别"
img = cropimg(config.recog.gray, scope) rect_limits = [{"w": 7, "h": 7, "char": ":"}]
default_height = 25 return config.recog.num.number(
if height != default_height: "riic_base", scope, height, thres, rect_limits=rect_limits
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
def read_remain_time(self) -> int: def read_remain_time(self) -> int:
h, m, s = self.number(((758, 670), (960, 705)), 30, 100).split("::") h, m, s = self.number(((758, 670), (960, 705)), 30, 100).split("::")

View file

@ -4,13 +4,12 @@ from typing import Optional
import cv2 import cv2
from mower.models import Digtal
from mower.solvers.navigation.utils import generate_name from mower.solvers.navigation.utils import generate_name
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.datetime import get_server_weekday from mower.utils.datetime import get_server_weekday
from mower.utils.graph import SceneGraphSolver 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.log import logger
from mower.utils.path import get_path from mower.utils.path import get_path
from mower.utils.recognize import Scene from mower.utils.recognize import Scene
@ -27,33 +26,10 @@ class OperationSolver(SceneGraphSolver):
super().run() super().run()
def number(self, scope: tp.Scope, height: Optional[int] = None): def number(self, scope: tp.Scope, height: Optional[int] = None):
img = cropimg(config.recog.gray, scope) rect_limits = [{"w": 5, "h": 5, "char": ""}]
if height: return config.recog.num.number_int(
scale = 25 / height "secret_front", scope, height, rect_limits=rect_limits
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
def drop_animation(self) -> bool: def drop_animation(self) -> bool:
drop_scope = (100, 775), (1920, 945) drop_scope = (100, 775), (1920, 945)

View file

@ -99,24 +99,7 @@ class OperatorSolver(SceneGraphSolver):
img = cropimg(img, ((1334, 175), (1456, 249))) img = cropimg(img, ((1334, 175), (1456, 249)))
scale = 25 / 73 scale = 25 / 73
img = cv2.resize(img, None, None, scale, scale) img = cv2.resize(img, None, None, scale, scale)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) return config.recog.num.number_int("secret_front", img=img)
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
def elite(self): def elite(self):
img = cropimg(config.recog.gray, ((1320, 372), (1454, 451))) 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.csleep import MowerExit
from mower.utils.email import send_message from mower.utils.email import send_message
from mower.utils.graph import SceneGraphSolver 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.log import logger
from mower.utils.scene import Scene from mower.utils.scene import Scene
from mower.utils.vector import sa, va from mower.utils.vector import sa, va
@ -80,31 +80,7 @@ class SecretFront(SceneGraphSolver):
self.actions[page] = {} self.actions[page] = {}
def number(self, scope: tp.Scope, height: int | None = None): def number(self, scope: tp.Scope, height: int | None = None):
img = cropimg(config.recog.gray, scope) return config.recog.num.number_int("secret_front", scope, height)
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
def card_pos(self, total, idx): def card_pos(self, total, idx):
if total == 3: if total == 3:

View file

@ -1,6 +1,6 @@
import cv2 import cv2
from mower.models import Digtal, shop from mower.models import shop
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.graph import SceneGraphSolver from mower.utils.graph import SceneGraphSolver
@ -41,36 +41,15 @@ class CreditShop(SceneGraphSolver):
img = cropimg(config.recog.gray, scope) img = cropimg(config.recog.gray, scope)
if font == "riic_base": if font == "riic_base":
templates = Digtal().riic_base_digits
default_height = 28 default_height = 28
else: else:
templates = Digtal().noto_sans
default_height = 29 default_height = 29
if height and height != default_height: if height and height != default_height:
scale = default_height / height scale = default_height / height
img = cv2.resize(img, None, None, scale, scale) img = cv2.resize(img, None, None, scale, scale)
img = thres2(img, thres) img = thres2(img, thres)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) return config.recog.num.number_int(font, img=img)
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
def credit_remain(self): def credit_remain(self):
credits = self.number(((1700, 39), (1800, 75)), "riic_base", thres=180) 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 skimage.metrics import structural_similarity
from mower.data import agent_list from mower.data import agent_list
from mower.models import Digtal
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp from mower.utils import typealias as tp
from mower.utils.character_recognize import match_avatar 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: def number(self, scope: tp.Scope, height: int, thres: int) -> int:
"数字识别" "数字识别"
try: return config.recog.num.number_int("secret_front", scope, height, thres)
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
def cost(self) -> int: def cost(self) -> int:
"获取部署费用" "获取部署费用"

View file

@ -3,10 +3,9 @@ import numpy as np
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from mower import __rootdir__ from mower import __rootdir__
from mower.models import Digtal
from mower.utils import config from mower.utils import config
from mower.utils import typealias as tp 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: 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: def number(scope: tp.Scope, height: int, thres: int) -> int:
"数字识别" "数字识别"
img = cropimg(config.recog.gray, scope) return config.recog.num.number_int("secret_front", scope, height, thres, rect_ed=-3)
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
def is_full() -> bool: def is_full() -> bool:

View file

@ -3,9 +3,9 @@ from typing import Literal
import cv2 import cv2
from mower.models import Digtal from mower.models import Digtal
from mower.utils import config
from . import typealias as tp from mower.utils import typealias as tp
from .image import cropimg from mower.utils.image import cropimg, thres2
class NumberRecognizer: class NumberRecognizer:
@ -71,3 +71,54 @@ class NumberRecognizer:
value += str(score.index(min(score))) value += str(score.index(min(score)))
return value 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.image import bytes2img, cmatch, cropimg, loadres, thres2
from mower.utils.log import logger from mower.utils.log import logger
from mower.utils.matcher import Matcher from mower.utils.matcher import Matcher
from mower.utils.number import NumberRecognizer
from mower.utils.scene import Scene, SceneComment from mower.utils.scene import Scene, SceneComment
from mower.utils.vector import va from mower.utils.vector import va
@ -36,6 +37,7 @@ class Recognizer:
self._gray = None self._gray = None
self._hsv = None self._hsv = None
self._matcher = None self._matcher = None
self._num = None
self.scene = Scene.UNDEFINED self.scene = Scene.UNDEFINED
@property @property
@ -62,6 +64,12 @@ class Recognizer:
self._matcher = Matcher(self.gray) self._matcher = Matcher(self.gray)
return self._matcher 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: def start(self, screencap: Optional[bytes] = None) -> None:
"""init with screencap""" """init with screencap"""
retry_times = config.MAX_RETRYTIME retry_times = config.MAX_RETRYTIME