【问题标题】:tesseract ocr is not working on image which have text length of only 2 or less. Works fine for Image with text length greater than 3tesseract ocr 不适用于文本长度仅为 2 或更少的图像。适用于文本长度大于 3 的图像
【发布时间】:2018-08-09 13:00:05
【问题描述】:
import pytesseract  
from PIL import Image

def textFromTesseractOCR(croppedImage):
    for i in range(14):
        text = pytesseract.image_to_string(croppedImage, lang = 'eng', boxes = False  ,config = '--psm '+ str(i) +' --oem 3')     
        print("PSM Mode", i)
        print("Text detected: ",text)

imgPath = "ImagePath"   #you can use image I have uploaded 
img = Image.open(imgPath)

textFromTesseractOCR(img)

我正在从 PDF 中提取表格数据。为此,我将pdf转换为png。检测线条,逐行确定表格,然后裁剪单个单元格以获取其文本。

这一切都很好,但 tesseract 不适用于文本长度为 2 或更少的单元格图像。

适用于此图片

tesseract 的结果

不适用于此图片

tesseract 的结果:返回空字符串。 对于文本长度为 2 或更少的数字,它也会返回空。

我尝试调整图像大小(我知道这不起作用),还尝试将虚拟文本附加到图像,但结果很糟糕(仅对少数人有效,而且我没有添加虚拟文本的确切位置图片中的文字)

如果有人可以帮助我,那就太好了。

【问题讨论】:

  • 尝试使用不同的 PSM。
  • @nguyenq 试过了,结果一样。

标签: python-3.x ocr tesseract cv2


【解决方案1】:

所以我终于找到了解决这种情况的方法。当图像仅包含 1 或 2 个长度的字符串(例如“1”或“25”)时,tesseract-OCR 给出空字符串的情况。

为了在这种情况下获得输出,我在原始图像上多次附加了相同的图像,以使其长度大于 2。例如,如果原始图像仅包含“3”,我附加了“3”图像(相同的图像)4 次以上,从而使其成为包含文本“33333”的图像。然后,我们将此图像提供给 tesseract,它给出输出“33333”(大多数情况下)。然后我们只需将 Tesseract 输出的文本中的空格替换为空格,并将生成的字符串长度除以 5 即可得到索引我们希望从整个文本中输出文本。

请参阅代码以供参考,希望对您有所帮助:

import pytesseract   ## pip3 install pytesseract

如果我们从 tesseract 输出中获得空字符串,该方法调用 tesseract 进行 OCR 或调用我们的解决方法代码。

def textFromTesseractOCR(croppedImage):
    text = pytesseract.image_to_string(croppedImage)
    if text.strip() == '':    ### program that handles our problem
        if  0 not in croppedImage:
            return ""
        yDir = 3
        xDir = 3
        iterations = 4
        img = generate_blocks_dilation(croppedImage, yDir, xDir, iterations) 
        ## we dilation to get only the text portion of the image and not the whole image 
        kernelH = np.ones((1,5),np.uint8)
        kernelV = np.ones((5,1),np.uint8)
        img = cv2.dilate(img,kernelH,iterations = 1)
        img = cv2.dilate(img,kernelV,iterations = 1)
        image = cropOutMyImg(img, croppedImage)
        concateImg = np.concatenate((image, image), axis = 1)
        concateImg = np.concatenate((concateImg, image), axis = 1)
        concateImg = np.concatenate((concateImg, image), axis = 1)
        concateImg = np.concatenate((concateImg, image), axis = 1)
        textA = pytesseract.image_to_string(concateImg)
        textA = textA.strip()
        textA = textA.replace(" ","")
        textA = textA[0:int(len(textA)/5)]
        return textA
    return text

膨胀方法。该方法仅用于对图像的文本区域进行膨胀

def generate_blocks_dilation(img, yDir, xDir, iterations):
    kernel = np.ones((yDir,xDir),np.uint8)
    ret,img = cv2.threshold(img, 0, 1, cv2.THRESH_BINARY_INV)
    return cv2.dilate(img,kernel,iterations = iterations)

裁剪图片放大部分的方法

def cropOutMyImg(gray, OrigImg):
    mask = np.zeros(gray.shape,np.uint8) # mask image the final image without small pieces
    _ , contours, hierarchy = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)     
    for cnt in contours:
        if cv2.contourArea(cnt)!=0:

        cv2.drawContours(mask,[cnt],0,255,-1) # the [] around cnt and 3rd argument 0 mean only the particular contour is drawn
        # Build a ROI to crop the QR
        x,y,w,h = cv2.boundingRect(cnt)
        roi=mask[y:y+h,x:x+w]
        # crop the original QR based on the ROI
        QR_crop = OrigImg[y:y+h,x:x+w]
        # use cropped mask image (roi) to get rid of all small pieces
        QR_final = QR_crop * (roi/255)
return QR_final

【讨论】:

    【解决方案2】:

    我尝试在给定的 2 个图像上运行 tesseract,但它不会返回较短文本图像中的文本。

    您可以尝试的另一件事是“训练机器学习模型(可能是神经网络)来处理字母、数字和特殊字符,然后当您想从图像中获取文本时,将该图像提供给模型,它会预测文本/字符。”

    训练数据集如下所示:

    一对(字符的图像,'字符')。

    对的第一个元素是模型的自变量。 对的第二个元素是该图像中存在的相应字符。它将是模型的因变量。

    【讨论】:

      猜你喜欢
      • 2021-09-26
      • 1970-01-01
      • 2017-07-28
      • 2012-07-01
      • 1970-01-01
      • 2012-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多