Reputation: 159
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
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:
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