尝试统一NumberRecognizer(未替换各处number)
This commit is contained in:
parent
0e0e2328ba
commit
75710be051
1 changed files with 73 additions and 0 deletions
73
mower/utils/number.py
Normal file
73
mower/utils/number.py
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
|
||||||
|
from mower.models import Digtal
|
||||||
|
|
||||||
|
from . import typealias as tp
|
||||||
|
from .image import cropimg
|
||||||
|
|
||||||
|
|
||||||
|
class NumberRecognizer:
|
||||||
|
def segment(self, img: tp.GrayImage) -> list[tuple[int, int, int, int]]:
|
||||||
|
"""
|
||||||
|
传入二值化的图像,分割图像中的连通区域
|
||||||
|
"""
|
||||||
|
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]) # 按照x坐标排序
|
||||||
|
return rect
|
||||||
|
|
||||||
|
def filter_rectangles(
|
||||||
|
self,
|
||||||
|
rect: list[tuple[int, int, int, int]],
|
||||||
|
st: int | None = None,
|
||||||
|
ed: int | None = None,
|
||||||
|
limits: list[dict] = [],
|
||||||
|
) -> list:
|
||||||
|
"""
|
||||||
|
过滤并替换不满足条件的矩形
|
||||||
|
limits: **大的数字写前面**,如[{"w":20,"h":10,"char":"."},{"w":10,"h":3,"char":""}]则将w<10,h<3的矩形替换为".",w<20,h<10的矩形替换为""
|
||||||
|
"""
|
||||||
|
rect = rect[st:ed]
|
||||||
|
if limits:
|
||||||
|
for i in range(len(rect)):
|
||||||
|
x, y, w, h = rect[i]
|
||||||
|
for lim in limits:
|
||||||
|
if w < lim["w"] and h < lim["h"]:
|
||||||
|
rect[i] = lim["char"]
|
||||||
|
break
|
||||||
|
return rect
|
||||||
|
|
||||||
|
def number_match(
|
||||||
|
self,
|
||||||
|
img,
|
||||||
|
rect: list,
|
||||||
|
font: Literal["riic_base", "noto", "secret_front"] = "noto",
|
||||||
|
target_range: list = range(10),
|
||||||
|
) -> str:
|
||||||
|
if font == "riic_base":
|
||||||
|
templates = Digtal().riic_base_digits
|
||||||
|
elif font == "noto":
|
||||||
|
templates = Digtal().noto_sans
|
||||||
|
elif font == "secret_front":
|
||||||
|
templates = Digtal().secret_front
|
||||||
|
value = ""
|
||||||
|
for i in range(len(rect)):
|
||||||
|
if len(rect[i]) != 4:
|
||||||
|
value += rect[i]
|
||||||
|
continue
|
||||||
|
x, y, w, h = rect[i]
|
||||||
|
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 target_range:
|
||||||
|
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 += str(score.index(min(score)))
|
||||||
|
|
||||||
|
return value
|
Loading…
Add table
Add a link
Reference in a new issue