License Plate Recognition using OpenCV in Python

This tutorial will tell you the way to implement License Plate Recognition from car image in Python program using OpenCV and Pytesseract.

Let’s begin and implement it now step by step.

Follow the step with me to do this task.

Install required libraries for License Plate Recognition

Open cmd and install OpenCV and imutils using the following commands-

pip install opencv-contrib-python

OpenCV will be used here for various pre-processing techniques and for displaying the image.

pip install imutils

imutils library contains a series of basic pre-processing functions and here it will be used for resizing the image.

Now for installing pytesseract, head over to https://github.com/UB-Mannheim/tesseract/wiki and download and install it.

Use of pytesseract

The tesseract library is an optical character recognition (OCR) tool for Python. That is, it can recognize and read the text embedded from any image. So we’ll use it for identifying the characters inside the number plate.

For this tutorial, we will use the image you can see below:

front of black car

 

Pre-processing of image

Now, look at our code given below:

import cv2
import imutils
import numpy as np
import pytesseract
from PIL import Image
pytesseract.pytesseract.tesseract_cmd = 'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'
img = cv2.imread('4.jpg',cv2.IMREAD_COLOR)
img = imutils.resize(img, width=500 )
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #convert to grey scale
gray = cv2.bilateralFilter(gray, 11, 17, 17) #Blur to reduce noise
edged = cv2.Canny(gray, 30, 200) #Perform Edge detection
 
  1. Here, we first imported all the three libraries required by using the Python import keyword.
  2.  Then the image is read and converted into gray-scale as less information will be stored for each pixel.
  3. After that, using OpenCV’s bilateralFilter fuunction, we reduce the noise in the image for a better edge detection.
  4. Finally, we use the Canny edge detection algorithm. It takes first argument as our input image, second and third arguments are our minVal and maxVal respectively which specify the threshold values.

This program will give the following output:

edge detection of car front

Finding and displaying Contours

Let us write our code first:

# find contours from the edged image and keep only the largest
# ones, and initialize our screen contour
cnts,new = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
img1=img.copy()
cv2.drawContours(img1,cnts,-1,(0,255,0),3)
cv2.imshow("img1",img1)
cv2.waitKey(0)

Now, let’s understand what are contours?

Contours are curves that help in identifying the regions in an image with the same intensity. Here, contours will help us in identifying the license plate of the car from the image. We are using two contours functions, cv2.findContours and cv2.drawContours.

cv.findContours() function takes three arguments-

  1. The first argument is the source image. Here we make a copy of the edged image as this function repeatedly finds contours in the image, meaning it makes the image unusable for future use. Also, the edged image makes identifying similar intensity curves easier.
  2. The second argument is the contour retrieval mode. Here the RETR_LIST type is used to retrieve all the detected contours in the image.
  3. The third parameter is the contour approximation method. CHAIN_APPROX_SIMPLE stores the end-points of the detected contours.

cv2.drawContours() function takes five arguments-

  1. The first argument is the image in which the detected contours will be drawn.
  2. The second argument is the variable that stores all the detected contours.
  3. Then, the third argument is contour indexes. Here we use the value -1 which will use the indexes of all the contours detected in our image. Hence all of the contours will be drawn on the image.
  4. After that, the fourth argument is the color in which contours will be drawn.
  5. The fifth argument is the thickness of the contour curve to be drawn.

This gives the following output-

car drawContours

Let’s continue coding:

#sorts contours based on minimum area 30 and ignores the ones below that
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:30]
screenCnt = None #will store the number plate contour
img2 = img.copy()
cv2.drawContours(img2,cnts,-1,(0,255,0),3) 
cv2.imshow("img2",img2) #top 30 contours
cv2.waitKey(0)
count=0

Here, we select the top 30 contours according to the area in decreasing order as we don’t need the various small contours. This reduces the redundant and small contours that are not needed.
This gives the following output-

car scanning machine learning

After that, see the code below:

idx=7
# loop over contours
for c in cnts:
  # approximate the contour
        peri = cv2.arcLength(c, True)
        approx = cv2.approxPolyDP(c, 0.018 * peri, True)
        if len(approx) == 4: #chooses contours with 4 corners
                screenCnt = approx
                x,y,w,h = cv2.boundingRect(c) #finds co-ordinates of the plate
                new_img=img[y:y+h,x:x+w]
                cv2.imwrite('./'+str(idx)+'.png',new_img) #stores the new image
                idx+=1
                break
  1. We loop over the selected 30 contours and then check one by one if the contour contains four corners as that would most likely be the number plate. Using peri function, we calculate perimeter of each contour.
  2. Then after finding coordinates of the plate using OpenCVs boundingRect function, we store the image with new dimensions in the variable new_img.
  3. Then using OpenCV’s function imwrite, we store the image in the directory.

Extracting text using Pytesseract

It’s time to extract the number or text from the plate:

#draws the selected contour on original image        
cv2.drawContours(img, [screenCnt], -1, (0, 255, 0), 3)
cv2.imshow("Final image with plate detected",img)
cv2.waitKey(0)
Cropped_loc='./7.png' #the filename of cropped image
cv2.imshow("cropped",cv2.imread(Cropped_loc)) 
text=pytesseract.image_to_string(Cropped_loc,lang='eng') #converts image characters to string
print("Number is:" ,text)
cv2.waitKey(0)
cv2.destroyAllWindows() 

Here, we draw the selected contour on the original image which will be on the license plate as shown-

license plate contour of car

Then using pytesseract, we extract the characters from the image and print the text on the screen as you can see below:

license plate text in python using opencv

Yea, we did it… License Plate Recognition in Python has been done successfully.

I hope you all liked the article!

Also, read:

 

Leave a Reply

Your email address will not be published. Required fields are marked *