Pytesseract not giving expected output
up vote
1
down vote
favorite
I'm new to pyhton and I'm making a number plate recognition system using haar cascade. My code works fine to detect the number plate and make contours but pytesseract ocr fails to recognise the characters and gives strange results. Please help.
The detected plate using haar cascades
contours made on the detected region
This is the output
import cv2
import numpy as np
import pytesseract
plate_cascade = cv2.CascadeClassifier('C:/Users/Jai/Desktop/Test/haarcascade_plate.xml')
img = cv2.imread('C:/Users/Jai/Desktop/Test/images/NumberPlates/IMG_20181029_194221.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.array(gray, dtype='uint8')
cv2.imshow('gray', gray)
plates = plate_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in plates:
cv2.rectangle(img, (x,y), (x+w,y+h),(255,0,0),5)
roiGray = gray[y:y+h, x:x+w]
roiImg = img[y:y+h, x:x+w]
roiUGray = cv2.bitwise_not(roiGray)
cv2.imshow('img', img)
cv2.imshow('roi_gray', roiUGray)
ret, thresh = cv2.threshold(roiUGray, 127, 255,0)
cv2.imshow("img", img)
height, width = thresh.shape
newImage = np.zeros((height, width, 3), np.uint8)
newImage[:, :] = (0,0,0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
num = 0
area = 0
for j in range(len(contours)):
if hierarchy[0][j][3] != -1:
area = area + cv2.contourArea(contours[j])
num += 1
if num != 0:
avgArea = float(area)/float(num)
for j in range(len(contours)):
if hierarchy[0][j][3] != -1 and cv2.contourArea(contours[j]) > 0.2*avgArea:
cv2.drawContours(newImage, contours[j], -1, (255,255,255), 1)
blur = cv2.GaussianBlur(newImage, (1, 1), 0)
cv2.imshow("roi", blur)
ocr_result = pytesseract.image_to_string(blur, lang='eng')
print(ocr_result)
cv2.waitKey(0)
cv2.destroyAllWindows()
python python-3.x opencv pytesseract
add a comment |
up vote
1
down vote
favorite
I'm new to pyhton and I'm making a number plate recognition system using haar cascade. My code works fine to detect the number plate and make contours but pytesseract ocr fails to recognise the characters and gives strange results. Please help.
The detected plate using haar cascades
contours made on the detected region
This is the output
import cv2
import numpy as np
import pytesseract
plate_cascade = cv2.CascadeClassifier('C:/Users/Jai/Desktop/Test/haarcascade_plate.xml')
img = cv2.imread('C:/Users/Jai/Desktop/Test/images/NumberPlates/IMG_20181029_194221.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.array(gray, dtype='uint8')
cv2.imshow('gray', gray)
plates = plate_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in plates:
cv2.rectangle(img, (x,y), (x+w,y+h),(255,0,0),5)
roiGray = gray[y:y+h, x:x+w]
roiImg = img[y:y+h, x:x+w]
roiUGray = cv2.bitwise_not(roiGray)
cv2.imshow('img', img)
cv2.imshow('roi_gray', roiUGray)
ret, thresh = cv2.threshold(roiUGray, 127, 255,0)
cv2.imshow("img", img)
height, width = thresh.shape
newImage = np.zeros((height, width, 3), np.uint8)
newImage[:, :] = (0,0,0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
num = 0
area = 0
for j in range(len(contours)):
if hierarchy[0][j][3] != -1:
area = area + cv2.contourArea(contours[j])
num += 1
if num != 0:
avgArea = float(area)/float(num)
for j in range(len(contours)):
if hierarchy[0][j][3] != -1 and cv2.contourArea(contours[j]) > 0.2*avgArea:
cv2.drawContours(newImage, contours[j], -1, (255,255,255), 1)
blur = cv2.GaussianBlur(newImage, (1, 1), 0)
cv2.imshow("roi", blur)
ocr_result = pytesseract.image_to_string(blur, lang='eng')
print(ocr_result)
cv2.waitKey(0)
cv2.destroyAllWindows()
python python-3.x opencv pytesseract
1
My suggestion is to crop the contour selected place of Image and give directly to Tesseract , you can get your required output
– Naga Kiran
Nov 11 at 8:49
Could you upload the original image so I can test? Thanks.
– qr7NmUTjF6vbA4n8V3J9
Nov 11 at 12:12
I've already uploaded the original image
– Jai Ahuja
Nov 12 at 20:38
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I'm new to pyhton and I'm making a number plate recognition system using haar cascade. My code works fine to detect the number plate and make contours but pytesseract ocr fails to recognise the characters and gives strange results. Please help.
The detected plate using haar cascades
contours made on the detected region
This is the output
import cv2
import numpy as np
import pytesseract
plate_cascade = cv2.CascadeClassifier('C:/Users/Jai/Desktop/Test/haarcascade_plate.xml')
img = cv2.imread('C:/Users/Jai/Desktop/Test/images/NumberPlates/IMG_20181029_194221.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.array(gray, dtype='uint8')
cv2.imshow('gray', gray)
plates = plate_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in plates:
cv2.rectangle(img, (x,y), (x+w,y+h),(255,0,0),5)
roiGray = gray[y:y+h, x:x+w]
roiImg = img[y:y+h, x:x+w]
roiUGray = cv2.bitwise_not(roiGray)
cv2.imshow('img', img)
cv2.imshow('roi_gray', roiUGray)
ret, thresh = cv2.threshold(roiUGray, 127, 255,0)
cv2.imshow("img", img)
height, width = thresh.shape
newImage = np.zeros((height, width, 3), np.uint8)
newImage[:, :] = (0,0,0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
num = 0
area = 0
for j in range(len(contours)):
if hierarchy[0][j][3] != -1:
area = area + cv2.contourArea(contours[j])
num += 1
if num != 0:
avgArea = float(area)/float(num)
for j in range(len(contours)):
if hierarchy[0][j][3] != -1 and cv2.contourArea(contours[j]) > 0.2*avgArea:
cv2.drawContours(newImage, contours[j], -1, (255,255,255), 1)
blur = cv2.GaussianBlur(newImage, (1, 1), 0)
cv2.imshow("roi", blur)
ocr_result = pytesseract.image_to_string(blur, lang='eng')
print(ocr_result)
cv2.waitKey(0)
cv2.destroyAllWindows()
python python-3.x opencv pytesseract
I'm new to pyhton and I'm making a number plate recognition system using haar cascade. My code works fine to detect the number plate and make contours but pytesseract ocr fails to recognise the characters and gives strange results. Please help.
The detected plate using haar cascades
contours made on the detected region
This is the output
import cv2
import numpy as np
import pytesseract
plate_cascade = cv2.CascadeClassifier('C:/Users/Jai/Desktop/Test/haarcascade_plate.xml')
img = cv2.imread('C:/Users/Jai/Desktop/Test/images/NumberPlates/IMG_20181029_194221.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.array(gray, dtype='uint8')
cv2.imshow('gray', gray)
plates = plate_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in plates:
cv2.rectangle(img, (x,y), (x+w,y+h),(255,0,0),5)
roiGray = gray[y:y+h, x:x+w]
roiImg = img[y:y+h, x:x+w]
roiUGray = cv2.bitwise_not(roiGray)
cv2.imshow('img', img)
cv2.imshow('roi_gray', roiUGray)
ret, thresh = cv2.threshold(roiUGray, 127, 255,0)
cv2.imshow("img", img)
height, width = thresh.shape
newImage = np.zeros((height, width, 3), np.uint8)
newImage[:, :] = (0,0,0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
num = 0
area = 0
for j in range(len(contours)):
if hierarchy[0][j][3] != -1:
area = area + cv2.contourArea(contours[j])
num += 1
if num != 0:
avgArea = float(area)/float(num)
for j in range(len(contours)):
if hierarchy[0][j][3] != -1 and cv2.contourArea(contours[j]) > 0.2*avgArea:
cv2.drawContours(newImage, contours[j], -1, (255,255,255), 1)
blur = cv2.GaussianBlur(newImage, (1, 1), 0)
cv2.imshow("roi", blur)
ocr_result = pytesseract.image_to_string(blur, lang='eng')
print(ocr_result)
cv2.waitKey(0)
cv2.destroyAllWindows()
python python-3.x opencv pytesseract
python python-3.x opencv pytesseract
asked Nov 11 at 8:08
Jai Ahuja
82
82
1
My suggestion is to crop the contour selected place of Image and give directly to Tesseract , you can get your required output
– Naga Kiran
Nov 11 at 8:49
Could you upload the original image so I can test? Thanks.
– qr7NmUTjF6vbA4n8V3J9
Nov 11 at 12:12
I've already uploaded the original image
– Jai Ahuja
Nov 12 at 20:38
add a comment |
1
My suggestion is to crop the contour selected place of Image and give directly to Tesseract , you can get your required output
– Naga Kiran
Nov 11 at 8:49
Could you upload the original image so I can test? Thanks.
– qr7NmUTjF6vbA4n8V3J9
Nov 11 at 12:12
I've already uploaded the original image
– Jai Ahuja
Nov 12 at 20:38
1
1
My suggestion is to crop the contour selected place of Image and give directly to Tesseract , you can get your required output
– Naga Kiran
Nov 11 at 8:49
My suggestion is to crop the contour selected place of Image and give directly to Tesseract , you can get your required output
– Naga Kiran
Nov 11 at 8:49
Could you upload the original image so I can test? Thanks.
– qr7NmUTjF6vbA4n8V3J9
Nov 11 at 12:12
Could you upload the original image so I can test? Thanks.
– qr7NmUTjF6vbA4n8V3J9
Nov 11 at 12:12
I've already uploaded the original image
– Jai Ahuja
Nov 12 at 20:38
I've already uploaded the original image
– Jai Ahuja
Nov 12 at 20:38
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
This method uses contour detection to find the area of the number plate, and does a perspective transform on it. It then uses adaptive thresholding to detect the digits and does a medianBlur to get rid of noise that messes up the pytesseract operation.

The blue box is from the original image. The red box is from my number plate recognition haar cascade. The green is the contour detection of the number plate.

Here's the output of the perspective transform. I used the imutils module to do this.

This is the output of the adaptive thresholding and blurring, which I used the skimage module for.
Using this I got the output of:
fUP1ADN7120
And removing all characters that aren't uppercase or a digit gives:
UP1ADN7120
Which is only one character wrong.
This method isn't too bad, but you could get even better using another method. If this didn't work for you, then you could create a CNN.
Here's the code:
import cv2
import numpy as np
import pytesseract
import imutils.perspective
from skimage.filters import threshold_local
plate_cascade = cv2.CascadeClassifier('/usr/local/lib/python3.5/dist-packages/cv2/data/haarcascade_russian_plate_number.xml')
img = cv2.imread('GNA0d.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.array(gray, dtype='uint8')
plates = plate_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in plates:
cv2.rectangle(img, (x,y), (x+w,y+h),(0,0,255),2)
roiGray = gray[y:y+h, x:x+w]
roiImg = img[y:y+h, x:x+w]
blur = cv2.GaussianBlur(roiGray, (5, 5), 0)
edges = cv2.Canny(blur, 75, 200)
contours = cv2.findContours(edges.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1]
contours = sorted(contours, key = cv2.contourArea, reverse = True)[:5] #sort the contours, only getting the biggest to improve speed
for contour in contours:
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
#find contours with 4 edges
if len(approx) == 4:
screenCnt = approx
break
orig = roiImg.copy()
cv2.drawContours(roiImg, [screenCnt], -1, (0, 255, 0), 2)
#do a perspective transform
warped = imutils.perspective.four_point_transform(orig, screenCnt.reshape(4, 2))
graywarp = imutils.perspective.four_point_transform(roiGray, screenCnt.reshape(4, 2))
#threshold using adaptive thresholding
T = threshold_local(graywarp, 11, offset = 10, method = "gaussian")
graywarp = (graywarp > T).astype("uint8") * 255
#do a median blur to remove noise
graywarp = cv2.medianBlur(graywarp, 3)
text = pytesseract.image_to_string(graywarp)
print(text)
print("".join([c for c in text if c.isupper() or c.isdigit()]))
cv2.imshow("warped", warped)
cv2.imshow("graywarp", graywarp)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Quite a bit was taken from pyimagesearch, who explains it better than I ever could.
Thanks for the help. Really appreciate it. Will try it out for sure.
– Jai Ahuja
Nov 12 at 20:38
1
@JaiAhuja if this answer solves your original issue - please consider marking it as an accepted answer.
– Dmitrii Z.
Nov 14 at 15:05
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
This method uses contour detection to find the area of the number plate, and does a perspective transform on it. It then uses adaptive thresholding to detect the digits and does a medianBlur to get rid of noise that messes up the pytesseract operation.

The blue box is from the original image. The red box is from my number plate recognition haar cascade. The green is the contour detection of the number plate.

Here's the output of the perspective transform. I used the imutils module to do this.

This is the output of the adaptive thresholding and blurring, which I used the skimage module for.
Using this I got the output of:
fUP1ADN7120
And removing all characters that aren't uppercase or a digit gives:
UP1ADN7120
Which is only one character wrong.
This method isn't too bad, but you could get even better using another method. If this didn't work for you, then you could create a CNN.
Here's the code:
import cv2
import numpy as np
import pytesseract
import imutils.perspective
from skimage.filters import threshold_local
plate_cascade = cv2.CascadeClassifier('/usr/local/lib/python3.5/dist-packages/cv2/data/haarcascade_russian_plate_number.xml')
img = cv2.imread('GNA0d.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.array(gray, dtype='uint8')
plates = plate_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in plates:
cv2.rectangle(img, (x,y), (x+w,y+h),(0,0,255),2)
roiGray = gray[y:y+h, x:x+w]
roiImg = img[y:y+h, x:x+w]
blur = cv2.GaussianBlur(roiGray, (5, 5), 0)
edges = cv2.Canny(blur, 75, 200)
contours = cv2.findContours(edges.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1]
contours = sorted(contours, key = cv2.contourArea, reverse = True)[:5] #sort the contours, only getting the biggest to improve speed
for contour in contours:
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
#find contours with 4 edges
if len(approx) == 4:
screenCnt = approx
break
orig = roiImg.copy()
cv2.drawContours(roiImg, [screenCnt], -1, (0, 255, 0), 2)
#do a perspective transform
warped = imutils.perspective.four_point_transform(orig, screenCnt.reshape(4, 2))
graywarp = imutils.perspective.four_point_transform(roiGray, screenCnt.reshape(4, 2))
#threshold using adaptive thresholding
T = threshold_local(graywarp, 11, offset = 10, method = "gaussian")
graywarp = (graywarp > T).astype("uint8") * 255
#do a median blur to remove noise
graywarp = cv2.medianBlur(graywarp, 3)
text = pytesseract.image_to_string(graywarp)
print(text)
print("".join([c for c in text if c.isupper() or c.isdigit()]))
cv2.imshow("warped", warped)
cv2.imshow("graywarp", graywarp)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Quite a bit was taken from pyimagesearch, who explains it better than I ever could.
Thanks for the help. Really appreciate it. Will try it out for sure.
– Jai Ahuja
Nov 12 at 20:38
1
@JaiAhuja if this answer solves your original issue - please consider marking it as an accepted answer.
– Dmitrii Z.
Nov 14 at 15:05
add a comment |
up vote
2
down vote
accepted
This method uses contour detection to find the area of the number plate, and does a perspective transform on it. It then uses adaptive thresholding to detect the digits and does a medianBlur to get rid of noise that messes up the pytesseract operation.

The blue box is from the original image. The red box is from my number plate recognition haar cascade. The green is the contour detection of the number plate.

Here's the output of the perspective transform. I used the imutils module to do this.

This is the output of the adaptive thresholding and blurring, which I used the skimage module for.
Using this I got the output of:
fUP1ADN7120
And removing all characters that aren't uppercase or a digit gives:
UP1ADN7120
Which is only one character wrong.
This method isn't too bad, but you could get even better using another method. If this didn't work for you, then you could create a CNN.
Here's the code:
import cv2
import numpy as np
import pytesseract
import imutils.perspective
from skimage.filters import threshold_local
plate_cascade = cv2.CascadeClassifier('/usr/local/lib/python3.5/dist-packages/cv2/data/haarcascade_russian_plate_number.xml')
img = cv2.imread('GNA0d.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.array(gray, dtype='uint8')
plates = plate_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in plates:
cv2.rectangle(img, (x,y), (x+w,y+h),(0,0,255),2)
roiGray = gray[y:y+h, x:x+w]
roiImg = img[y:y+h, x:x+w]
blur = cv2.GaussianBlur(roiGray, (5, 5), 0)
edges = cv2.Canny(blur, 75, 200)
contours = cv2.findContours(edges.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1]
contours = sorted(contours, key = cv2.contourArea, reverse = True)[:5] #sort the contours, only getting the biggest to improve speed
for contour in contours:
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
#find contours with 4 edges
if len(approx) == 4:
screenCnt = approx
break
orig = roiImg.copy()
cv2.drawContours(roiImg, [screenCnt], -1, (0, 255, 0), 2)
#do a perspective transform
warped = imutils.perspective.four_point_transform(orig, screenCnt.reshape(4, 2))
graywarp = imutils.perspective.four_point_transform(roiGray, screenCnt.reshape(4, 2))
#threshold using adaptive thresholding
T = threshold_local(graywarp, 11, offset = 10, method = "gaussian")
graywarp = (graywarp > T).astype("uint8") * 255
#do a median blur to remove noise
graywarp = cv2.medianBlur(graywarp, 3)
text = pytesseract.image_to_string(graywarp)
print(text)
print("".join([c for c in text if c.isupper() or c.isdigit()]))
cv2.imshow("warped", warped)
cv2.imshow("graywarp", graywarp)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Quite a bit was taken from pyimagesearch, who explains it better than I ever could.
Thanks for the help. Really appreciate it. Will try it out for sure.
– Jai Ahuja
Nov 12 at 20:38
1
@JaiAhuja if this answer solves your original issue - please consider marking it as an accepted answer.
– Dmitrii Z.
Nov 14 at 15:05
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
This method uses contour detection to find the area of the number plate, and does a perspective transform on it. It then uses adaptive thresholding to detect the digits and does a medianBlur to get rid of noise that messes up the pytesseract operation.

The blue box is from the original image. The red box is from my number plate recognition haar cascade. The green is the contour detection of the number plate.

Here's the output of the perspective transform. I used the imutils module to do this.

This is the output of the adaptive thresholding and blurring, which I used the skimage module for.
Using this I got the output of:
fUP1ADN7120
And removing all characters that aren't uppercase or a digit gives:
UP1ADN7120
Which is only one character wrong.
This method isn't too bad, but you could get even better using another method. If this didn't work for you, then you could create a CNN.
Here's the code:
import cv2
import numpy as np
import pytesseract
import imutils.perspective
from skimage.filters import threshold_local
plate_cascade = cv2.CascadeClassifier('/usr/local/lib/python3.5/dist-packages/cv2/data/haarcascade_russian_plate_number.xml')
img = cv2.imread('GNA0d.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.array(gray, dtype='uint8')
plates = plate_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in plates:
cv2.rectangle(img, (x,y), (x+w,y+h),(0,0,255),2)
roiGray = gray[y:y+h, x:x+w]
roiImg = img[y:y+h, x:x+w]
blur = cv2.GaussianBlur(roiGray, (5, 5), 0)
edges = cv2.Canny(blur, 75, 200)
contours = cv2.findContours(edges.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1]
contours = sorted(contours, key = cv2.contourArea, reverse = True)[:5] #sort the contours, only getting the biggest to improve speed
for contour in contours:
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
#find contours with 4 edges
if len(approx) == 4:
screenCnt = approx
break
orig = roiImg.copy()
cv2.drawContours(roiImg, [screenCnt], -1, (0, 255, 0), 2)
#do a perspective transform
warped = imutils.perspective.four_point_transform(orig, screenCnt.reshape(4, 2))
graywarp = imutils.perspective.four_point_transform(roiGray, screenCnt.reshape(4, 2))
#threshold using adaptive thresholding
T = threshold_local(graywarp, 11, offset = 10, method = "gaussian")
graywarp = (graywarp > T).astype("uint8") * 255
#do a median blur to remove noise
graywarp = cv2.medianBlur(graywarp, 3)
text = pytesseract.image_to_string(graywarp)
print(text)
print("".join([c for c in text if c.isupper() or c.isdigit()]))
cv2.imshow("warped", warped)
cv2.imshow("graywarp", graywarp)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Quite a bit was taken from pyimagesearch, who explains it better than I ever could.
This method uses contour detection to find the area of the number plate, and does a perspective transform on it. It then uses adaptive thresholding to detect the digits and does a medianBlur to get rid of noise that messes up the pytesseract operation.

The blue box is from the original image. The red box is from my number plate recognition haar cascade. The green is the contour detection of the number plate.

Here's the output of the perspective transform. I used the imutils module to do this.

This is the output of the adaptive thresholding and blurring, which I used the skimage module for.
Using this I got the output of:
fUP1ADN7120
And removing all characters that aren't uppercase or a digit gives:
UP1ADN7120
Which is only one character wrong.
This method isn't too bad, but you could get even better using another method. If this didn't work for you, then you could create a CNN.
Here's the code:
import cv2
import numpy as np
import pytesseract
import imutils.perspective
from skimage.filters import threshold_local
plate_cascade = cv2.CascadeClassifier('/usr/local/lib/python3.5/dist-packages/cv2/data/haarcascade_russian_plate_number.xml')
img = cv2.imread('GNA0d.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.array(gray, dtype='uint8')
plates = plate_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in plates:
cv2.rectangle(img, (x,y), (x+w,y+h),(0,0,255),2)
roiGray = gray[y:y+h, x:x+w]
roiImg = img[y:y+h, x:x+w]
blur = cv2.GaussianBlur(roiGray, (5, 5), 0)
edges = cv2.Canny(blur, 75, 200)
contours = cv2.findContours(edges.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1]
contours = sorted(contours, key = cv2.contourArea, reverse = True)[:5] #sort the contours, only getting the biggest to improve speed
for contour in contours:
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
#find contours with 4 edges
if len(approx) == 4:
screenCnt = approx
break
orig = roiImg.copy()
cv2.drawContours(roiImg, [screenCnt], -1, (0, 255, 0), 2)
#do a perspective transform
warped = imutils.perspective.four_point_transform(orig, screenCnt.reshape(4, 2))
graywarp = imutils.perspective.four_point_transform(roiGray, screenCnt.reshape(4, 2))
#threshold using adaptive thresholding
T = threshold_local(graywarp, 11, offset = 10, method = "gaussian")
graywarp = (graywarp > T).astype("uint8") * 255
#do a median blur to remove noise
graywarp = cv2.medianBlur(graywarp, 3)
text = pytesseract.image_to_string(graywarp)
print(text)
print("".join([c for c in text if c.isupper() or c.isdigit()]))
cv2.imshow("warped", warped)
cv2.imshow("graywarp", graywarp)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Quite a bit was taken from pyimagesearch, who explains it better than I ever could.
edited Nov 11 at 20:45
answered Nov 11 at 13:12
qr7NmUTjF6vbA4n8V3J9
1686
1686
Thanks for the help. Really appreciate it. Will try it out for sure.
– Jai Ahuja
Nov 12 at 20:38
1
@JaiAhuja if this answer solves your original issue - please consider marking it as an accepted answer.
– Dmitrii Z.
Nov 14 at 15:05
add a comment |
Thanks for the help. Really appreciate it. Will try it out for sure.
– Jai Ahuja
Nov 12 at 20:38
1
@JaiAhuja if this answer solves your original issue - please consider marking it as an accepted answer.
– Dmitrii Z.
Nov 14 at 15:05
Thanks for the help. Really appreciate it. Will try it out for sure.
– Jai Ahuja
Nov 12 at 20:38
Thanks for the help. Really appreciate it. Will try it out for sure.
– Jai Ahuja
Nov 12 at 20:38
1
1
@JaiAhuja if this answer solves your original issue - please consider marking it as an accepted answer.
– Dmitrii Z.
Nov 14 at 15:05
@JaiAhuja if this answer solves your original issue - please consider marking it as an accepted answer.
– Dmitrii Z.
Nov 14 at 15:05
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246894%2fpytesseract-not-giving-expected-output%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
My suggestion is to crop the contour selected place of Image and give directly to Tesseract , you can get your required output
– Naga Kiran
Nov 11 at 8:49
Could you upload the original image so I can test? Thanks.
– qr7NmUTjF6vbA4n8V3J9
Nov 11 at 12:12
I've already uploaded the original image
– Jai Ahuja
Nov 12 at 20:38