我试图识别以卡通字体写的数字,因此传统工具(例如pytesser)无法真正起作用。但是,我可以使用cv2.matchTemplate和10位数字的库来获得相当准确的一位数字识别。我基本上是将每个数字都当作符号,只是试图找到最佳匹配。

import cv2
import numpy as np

def match_char(im1, im2):
    result = cv2.matchTemplate(im1,im2,cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    return max_va

def process_image(im, i):
    try:
        gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
        a, t = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY_INV)
        return t
    except:
        print("Error while processing the image")
        pass

def process_lib(im, i):
    try:
        gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

        a, t = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY)
        return t
    except:
        print("Error while processing the image")
        pass

def process_num():
    test = cv2.imread('test.png')
    test = process_image(test, 11)
    test = cv2.resize(test, (0,0), fx=2.2, fy=2.2) #best
    scores = []

    for i in range(10):
        img = cv2.imread('char-{}.png'.format(i))
        img = process_lib(img, i)
        scores.append(match_char(img, test))

    win = scores.index(max(scores))
    print("The best match is {} with {}".format(win, scores[win]))

问题是我无法将其扩展为多个数字。即使生成两位数的数字并尝试匹配它们,程序也始终将一位数字标识为最佳匹配项。如果我将搜索限制在两位数的数字上,则有时它会得到一位数字的正确性,但不会同时获得两位数。当然,这不是最优雅的解决方案,但它似乎是最简单的,甚至是行不通的。

最佳答案

您应该定义一个阈值,并在此阈值以下过滤cv2.matchTemplate结果

我认为以下代码适合您:

import cv2 as cv
import numpy as np

img_rgb = cv.imread('image.png')
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
template = cv.imread('template.png',0)
w, h = template.shape[::-1]
res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
    cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
cv.imwrite('res.png',img_rgb)

有关更多信息see

关于python - OpenCV-识别符号系列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50412812/

10-16 21:04