Search code examples
pythonopencvocrtesseractpython-tesseract

PyTesseract unable to recognize text on a green background


I have been playing around with the image while preprocessing but tesseract is unable to detect the text on the LCD screen. It does create a bounding box around it which, I guess, means it found something in there but does not give any text as output.

Image I am working with:

1

Here is my code:

import cv2
import pytesseract
import numpy as np

img = cv2.imread("test-python2.jpg")

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, thresh1 = cv2.threshold(gray, 50, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)

rect_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (18, 18))
kernel = np.ones((5, 5), np.uint8)
#closin = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)

dilation = cv2.dilate(thresh1, rect_kernel, iterations = 1)

contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
im2 = img.copy()
for cnt in contours:
    x, y, w, h = cv2.boundingRect(cnt)
    im2 = cv2.rectangle(im2, (x, y), (x + w, y + h), (0, 255, 0), 2)
    
    cropped = img[y:y + h, x:x + w]
    text = pytesseract.image_to_string(cropped)
    im2 = cv2.putText(im2, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 3)
    text2 = text.encode('latin-1', 'replace').decode('latin-1')
    print (text2)


cv2.imshow("", im2)
cv2.waitKey(0)

And the output I get from the cv2.imshow() is here:

2

The text I did get is accurate enough but it just does not read off of the LCD screen. I have tried playing around with different kinds of binarization/thresholding but the LCD never seems to get picked up. The recognization of the LCD is very important to my project but I have been stuck at this hurdle for a while now.


Solution

  • I cut out the interessting part:

    import subprocess
    import cv2
    import pytesseract
    
    # Image manipulation
    # Commands https://imagemagick.org/script/convert.php
    mag_img = r'D:\Programme\ImageMagic\magick.exe'
    con_bw = r"D:\Programme\ImageMagic\convert.exe"
    
    in_file = r'green_red.jpg'
    out_file = r'green_bw.jpg'
    
    # Play with black and white and contrast for better results
    process = subprocess.run([con_bw, in_file, "-resize", "100%","-threshold","28%", out_file])
    
    # Text ptocessing
    pytesseract.pytesseract.tesseract_cmd=r'C:\Program Files\Tesseract-OCR\tesseract.exe'
    img = cv2.imread(out_file)
    
    # Parameters see tesseract doc 
    custom_config = r'--psm 6 --oem 3 -c tessedit_char_whitelist=ABCDEFTGHIJKLMNOPQRSTUVWXYZkh' 
    
    tex = pytesseract.image_to_string(img, config=custom_config)
    print(tex)
    
    with open("number.txt", 'w') as f:
        f.writelines(tex)
    
    cv2.imshow('image',img)
    cv2.waitKey(12000)
    cv2.destroyAllWindows()
    

    Output:

    CTEP
    

    Image: enter image description here enter image description here

    Option 2 with CV2 instead of imagemagick. I cropped the interessting area and set it to blach&white, before ocr the text:

    import cv2
    import numpy as np
    import pytesseract
     
    img = cv2.imread('green.jpg',cv2.IMREAD_UNCHANGED)
    print(img.shape) # Print image shape
    cv2.imshow("Original", img)
     
    # Cropping an image and set color to B&W
    cropped_image = img[370:600, 603:1360] # img[y:y+h, x:x+w]
    grayImage = cv2.cvtColor(cropped_image, cv2.COLOR_BGR2GRAY)
    (thresh, blackAndWhiteImage) = cv2.threshold(grayImage, 65, 255, cv2.THRESH_BINARY) # | cv2.THRESH_OTSU => 90
    print(thresh)
    
    # resize image
    scale_percent = 43 # percent of original size
    width = int(blackAndWhiteImage.shape[1] * scale_percent / 100)
    height = int(blackAndWhiteImage.shape[0] * scale_percent / 100)
    dim = (width, height)
    resized = cv2.resize(blackAndWhiteImage, dim, interpolation = cv2.INTER_AREA)
    
    # OCR resized Black & White image
    pytesseract.pytesseract.tesseract_cmd=r'C:\Program Files\Tesseract-OCR\tesseract.exe'
    custom_config = r'--psm 6 --oem 3 -c tessedit_char_whitelist=ABCDEFTGHIJKLMNOPQRSTUVWXYZkh' 
    tex = pytesseract.image_to_string(resized, config=custom_config)
    print(tex)
    
    # Display cropped image
    cv2.imshow("cropped", resized)
     
    # Save the cropped image
    cv2.imwrite("Cropped Image.jpg", resized)
     
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    Output:

    (1080, 1920, 3)  # image size
    65.0             # thresh value
    CTEP             # -> OCR