Search code examples
pythonpython-3.xopencvtesseractpdf-extraction

Python - OpenCV pytesseract not extracting string from cropped image


I have an image (attached) and want to extract certain fields from the form. For example the name 'Sarah', her email address etc. I have the region of interest, which is being highlighted, then cropped. For some reason my output from image to string is showing up as empty?

The desired output should extract the data. Please could someone point me in the right direction? I am following this great tutorial for context: https://www.youtube.com/watch?v=cUOcY9ZpKxw

['', '', '', '', '', '']

Code below:


import cv2
import numpy as np
import pytesseract
import os
pytesseract.pytesseract.tesseract_cmd = r'Tesseract-OCR\tesseract.exe'

imgQ = cv2.imread('sarah.png')

#cv2.imshow('output',imgQ)
#cv2.waitKey(0)

roi = [[(98, 984), (680, 1074), 'text', 'Name'],
       [(740, 980), (1320, 1078), 'text', 'Phone'],
       [(100, 1418), (686, 1518), 'text', 'Email'],
       [(740, 1416), (1318, 1512), 'text', 'ID'],
       [(110, 1598), (676, 1680), 'text', 'City'],
       [(748, 1592), (1328, 1686), 'text', 'Country']]

myData=[]
for x,r in enumerate(roi):
        #highlighted the regions
        cv2.rectangle(imgQ, (r[0][0],r[0][1]),(r[1][0],r[1][1]),(0,255,0),cv2.FILLED)
        imgShow = cv2.addWeighted(imgQ,0.99,imgQ,0.1,0)
        #crop regions
        imgCrop = imgShow[r[0][1]:r[1][1], r[0][0]:r[1][0]]
        cv2.imshow(str(x),imgCrop)
        if r[2] == 'text':

            print('{} :{}'.format(r[3],pytesseract.image_to_string(imgCrop)))
            myData.append(pytesseract.image_to_string(imgCrop))
print(myData)    
            

image example here (also used in tutorial)


Solution

  • The problem in your code is the below line:

    cv2.rectangle(img, (r[0][0], r[0][1]), (r[1][0], r[1][1]), (0, 255, 0), cv2.FILLED)
    
    • What does this line executes?

    Finds the roi in the given image and fills with green color. Like:

    enter image description here

    Then you are trying to read data from this green rectangle for enumerate(roi) times.


    • Second, why imgShow = cv2.addWeighted(img, 0.99, img, 0.1, 0)?

    • Third imgCrop = imgShow[r[0][1]:r[1][1], r[0][0]:r[1][0]]

    How about we crop from img?

    • enter image description here

    • enter image description here

    • enter image description here

    • ..

    and the output is

    Name :Sarah
    
    Phone :+ (00) 765-43-21
    
    Email :sarah@abc.com
    
    ID :1356856
    
    City :London
    
    Country :United Kingdom
    

    Code:


    import cv2
    from pytesseract import image_to_string
    
    img = cv2.imread("hzt5U.png")
    # gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # thr = cv2.adaptiveThreshold(gry, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 21, 21)
    # txt = image_to_string(thr, config="--psm 6")
    # print(txt)
    
    roi = [[(98, 984), (680, 1074), 'text', 'Name'],
           [(740, 980), (1320, 1078), 'text', 'Phone'],
           [(100, 1418), (686, 1518), 'text', 'Email'],
           [(740, 1416), (1318, 1512), 'text', 'ID'],
           [(110, 1598), (676, 1680), 'text', 'City'],
           [(748, 1592), (1328, 1686), 'text', 'Country']]
    
    my_data = []
    
    for x, r in enumerate(roi):
        # highlighted the regions
        # cv2.rectangle(img, (r[0][0], r[0][1]), (r[1][0], r[1][1]), (0, 255, 0), cv2.FILLED)
        # imgShow = cv2.addWeighted(img, 0.99, img, 0.1, 0)
    
        # crop regions
        # imgCrop = imgShow[r[0][1]:r[1][1], r[0][0]:r[1][0]]
        imgCrop = img[r[0][1]:r[1][1], r[0][0]:r[1][0]]
        cv2.imwrite("/Users/ahx/Desktop/res{}.png".format(x), imgCrop)
        cv2.imshow(str(x), imgCrop)
        cv2.waitKey(0)
    
        if r[2] == 'text':
            print('{} :{}'.format(r[3], image_to_string(imgCrop)))
            my_data.append(image_to_string(imgCrop))
    
    # print(my_data)