我有各种类型的图像:
如您所见,它们都有些相似,但是我无法正确提取它们上的数字。
到目前为止,我的代码包括以下内容:
lower = np.array([250,200,90], dtype="uint8")
upper = np.array([255,204,99], dtype="uint8")
mask = cv2.inRange(img, lower, upper)
res = cv2.bitwise_and(img, img, mask=mask)
data = image_to_string(res, lang="eng", config='--psm 13 --oem 3 -c tessedit_char_whitelist=0123456789')
numbers = int(''.join(re.findall(r'\d+', data)))
我尝试修改 psm 参数 6,8 和 13,它们都适用于其中一些示例,但根本没有,而且我不知道如何规避我的问题。
提出的另一个解决方案是:
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
(h, w) = gry.shape[:2]
gry = cv2.resize(gry, (w*2, h*2))
erd = cv2.erode(gry, None, iterations=1)
thr = cv2.threshold(erd, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
bnt = cv2.bitwise_not(thr)
然而,在第一张图片上,bnt 给出:
然后 pytesseract 看到 460..
有什么想法吗?
答案 0 :(得分:1)
我的方法:
上采样是准确识别所必需的。调整大小两次将使图像可读。
侵蚀操作是一种形态学操作,有助于去除像素的边界。侵蚀去除数字上的笔画,使其更容易检测。
阈值(二进制和逆二进制)有助于揭示特征。
按位非是一种对提取图像的一部分非常有用的算术运算。
您可以从Improving the quality of the output
了解更多方法简单阅读更新
第一张图片很容易阅读,因为它不需要任何预处理技术。请阅读How to Improve Quality of Tesseract
1460
720
3250
3146
2681
1470
代码:
import cv2
import pytesseract
img_lst = ["oqWjd.png", "YZDt1.png", "MUShJ.png", "kbK4m.png", "POIK2.png", "4W3R4.png"]
for i, img_nm in enumerate(img_lst):
img = cv2.imread(img_nm)
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
(h, w) = gry.shape[:2]
if i == 0:
thr = gry
else:
gry = cv2.resize(gry, (w * 2, h * 2))
erd = cv2.erode(gry, None, iterations=1)
if i == len(img_lst)-1:
thr = cv2.threshold(erd, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
else:
thr = cv2.threshold(erd, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
bnt = cv2.bitwise_not(thr)
txt = pytesseract.image_to_string(bnt, config="--psm 6 digits")
print("".join([t for t in txt if t.isalnum()]))
cv2.imshow("bnt", bnt)
cv2.waitKey(0)
如果要在结果中显示逗号,请将 print("".join([t for t in txt if t.isalnum()]))
行更改为 print(txt)
。
并非在第四张图像上,阈值方法从二进制变为逆二进制。二进制阈值不能在所有图像上准确工作。所以你需要改变。