我试图识别以卡通字体写的数字,因此传统工具(例如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/