Brandon Jacobson
Brandon Jacobson

Reputation: 159

How do I get Tesseract to read the license plate in the this Python OpenCV project?

enter image description hereenter image description here

My OpenCV code works just fine. It find the license plate, extracts a black and white version of it, using the contours, and then when I pass it to pytesseract, it won't read any of the letters. I've tracked the program throughout each line of the code and the OpenCV works fine, but pytesseract won't extract the text from the image. There are no errors, it just doesn't read any text. The license plate is mine.

import cv2
# pip install imutils
import imutils
import pytesseract

pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files (x86)\Tesseract-OCR\tesseract.exe'

# Read the image file
image = cv2.imread('LP.jpg')
# image = imutils.resize(image, width=500)

# Convert to Grayscale Image
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Removes Noise
gray_image = cv2.bilateralFilter(gray_image, 11, 17, 17)

# Canny Edge Detection
canny_edge = cv2.Canny(gray_image, 100, 200)

# Find contours based on Edges
# The code below needs an - or else you'll get a ValueError: too many values to unpack (expected 2) or a numpy error
_, contours, new = cv2.findContours(canny_edge.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:30]

# # Initialize license Plate contour and x,y coordinates
contour_with_license_plate = None
license_plate = None
x = None
y = None
w = None
h = None

# Find the contour with 4 potential corners and create a Region of Interest around it
for contour in contours:
    # Find Perimeter of contour and it should be a closed contour
    perimeter = cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, 0.02 * perimeter, True)
    # This checks if it's a rectangle
    if len(approx) == 4:
        contour_with_license_plate = approx
        x, y, w, h = cv2.boundingRect(contour)
        license_plate = gray_image[y:y + h, x:x + w]
        break


# # approximate_contours = cv2.drawContours(image, [contour_with_license_plate], -1, (0, 255, 0), 3)

# Text Recognition
text = pytesseract.image_to_string(license_plate, lang='eng')
print(text)
# Draw License Plate and write the Text
image = cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 3)
image = cv2.putText(image, text, (x-100, y-50), cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 255, 0), 6, cv2.LINE_AA)

print("License Plate: ", text)

cv2.imshow("License Plate Detection", image)
cv2.waitKey(0)

Upvotes: 0

Views: 1461

Answers (1)

Ahx
Ahx

Reputation: 7985

Here is my partial answer, maybe you can perfect it.

Apply adaptive-threshold + bitwise-not operations to the license_plate variable.

The result will be:

enter image description here

Now if you read it:

txt = pytesseract.image_to_string(bnt, config="--psm 6")  
print(txt)

Result:

277 BOY

Unfortunately Q is recognized as O.

Code: (Just replace text recogniiton commented part with the below)


thr = cv2.adaptiveThreshold(license_plate, 252, cv2.ADAPTIVE_THRESH_MEAN_C,
                            cv2.THRESH_BINARY_INV, 91, 93)
bnt = cv2.bitwise_not(thr)
txt = pytesseract.image_to_string(bnt, config="--psm 6")
print(txt)

Upvotes: 2

Related Questions