Python pytesseract 从各种图像中提取数字

尼古拉斯·雷伊

我有各种类型的图像,例如:

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

如您所见,它们都有些相似,但是我无法正确提取它们上的数字。

到目前为止,我的代码包括以下内容:

    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..

请问有什么想法吗?

我的做法:



准确识别需要上采样调整大小两次将使图像可读。

侵蚀操作是一种形态学操作,有助于去除像素的边界。侵蚀去除数字上的笔划,使其更容易检测。

阈值(二进制和逆二进制)有助于揭示特征。

Bitwise-not是一种算术运算,对于提取图像的一部分非常有用。

您可以从提高输出质量中学习更多方法简单阅读


侵蚀 临界点 按位非
在此处输入图片说明 在此处输入图片说明 在此处输入图片说明
在此处输入图片说明 在此处输入图片说明 在此处输入图片说明
在此处输入图片说明 在此处输入图片说明 在此处输入图片说明
在此处输入图片说明 在此处输入图片说明 在此处输入图片说明
在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

更新


第一张图像很容易阅读,因为它不需要任何预处理技术。请阅读如何提高 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()]))line更改print(txt).

并不是在第四张图像上,阈值方法从二进制变为逆二进制。二进制阈值不能在所有图像上准确工作。因此你需要改变。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章