Pytesseract 和 OpenCV 无法检测数字

Pytesseract and OpenCV can't detect digits

提前感谢所有会回答的人。

我是 OpenCV、Pytesseract 的新手,总体上对图像处理和识别非常缺乏经验。

我正在尝试从 pdf 中检测数字,为了这段代码,我将直接提供图像: Initial image

我的objective是检测彩色方框内的数字,本例中是数字6。 我的预处理代码如下:

import numpy as np
import pytesseract
from PIL import Image
from PIL import ImageFilter, ImageEnhance

pytesseract.pytesseract.tesseract_cmd = 'Tesseract-OCR\tesseract.exe'


# -----Reading the image-----------------------------------------------------
img = cv2.imread('page_image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.resize(gray, (1028, 720))

thres_gray = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)[1]
gray_inv = cv2.bitwise_not(thres_gray)
gray_test = cv2.bitwise_not(gray_inv)

out2 = cv2.bitwise_or(gray, gray, mask=gray_inv)

thresh_end = cv2.threshold(out2, 254, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

imageObject = Image.fromarray(thresh_end)
enhancer = ImageEnhance.Sharpness(imageObject)


sharpened1 = imageObject.filter(ImageFilter.SHARPEN)
sharpened2 = sharpened1.filter(ImageFilter.SHARPEN)
# sharpened2.show()

由此我得到如下图: Preprocessed image

在这一点上,由于我仍在学习如何检测感兴趣区域并使用 OpenCV 裁剪它,为了测试代码,我决定手动裁剪图像以测试我的脚本是否足够正确。

因此,我传递给 pytesseract 的图像如下: Final image to read with pytesseract 我不确定图像是否足够好以供阅读,但这是我能得到的最好的图像。 由此我尝试 image_to_string:

trial = pytesseract.image_to_string(sharpened2, config='--psm 13 --oem 3 -c tessedit_char_whitelist=0123456789')

我已经为 tesseract 尝试了很多不同的配置,但是 none 它有效并且最终输出总是一个空字符串。

如果您能帮助我了解是图像不够好还是我在 tesseract 配置上做错了什么,我将不胜感激。 如果你也能帮我正确裁剪图像那就太棒了,但即使检测到数字对我来说也足够了。

抱歉这么久 post 再次感谢。

试试这个:

import cv2
import pytesseract
import numpy as np

pytesseract.pytesseract.tesseract_cmd = 'C:\Program Files\Tesseract-OCR\tesseract.exe'

img = cv2.imread("form.jpg")

# 
ORANGE_MIN = np.array([5, 50, 50], np.uint8)
ORANGE_MAX = np.array([15, 255, 255], np.uint8)

hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
frame_threshed = cv2.inRange(hsv_img, ORANGE_MIN, ORANGE_MAX)
# cv2.imshow("frame_threshed", frame_threshed)

thresh = cv2.threshold(frame_threshed, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# cv2.imshow("thresh", thresh)

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
# cv2.imshow("dilate", thresh)

for c in cnts:
    x, y, w, h = cv2.boundingRect(c)
    ROI = thresh[y:y + h, x:x + w]

    ratio = 100.0 / ROI.shape[1]
    dim = (100, int(ROI.shape[0] * ratio))

    resizedCubic = cv2.resize(ROI, dim, interpolation=cv2.INTER_CUBIC)
    threshGauss = cv2.adaptiveThreshold(resizedCubic, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 255, 17)

    cv2.imshow("ROI", threshGauss)

    text = int(pytesseract.image_to_string(threshGauss, lang='eng', config="--oem 3 --psm 13"))
    print(f"Detected text: {text}")


cv2.waitKey(0)

我先用HSV方法检测橙色。然后,一旦 ROI 清晰可见,我就应用了“经典”图像预处理步骤。 看看 this link 了解如何 select 除了橙色以外的其他颜色。

我还稍微调整了 ROI。