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

Python pytesseract extract number from various images

我有各种类型的图像:

如您所见,它们有点相似,但我无法正确提取它们的编号。

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

    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 它们都适用于其中一些示例,但总的来说 none,我不知道如何解决我的问题。

提出的另一种解决方案是:

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

有什么想法吗?

我的做法:



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

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

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

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

更多方法简单阅读Improving the quality of the output


Erosion Threshold Bitwise-not

更新


第一张图片易于阅读,因为它不需要任何预处理技术。请阅读How to Improve Quality of Tesseract

Result:

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)

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