Automatic License Number Plate Recognition System
Automatic License Number Plate Recognition System
Automatic License Number Plate Recognition System
Recognition System
Project idea: The objective of this machine learning project is to detect and
recognize the license number plate of a vehicle and read the license
numbers printed on the plate. This could be a good application for security
scans, traffic monitoring, etc.
In this python project, to identify the number plate in the input image, we will use
following features of openCV:
Now, let’s dive into the number plate recognition code. Follow the steps below:
1. Imports:
For this project we need numpy and pillow python libraries with openCV and
pytesseract
import numpy as np
import cv2
from PIL import Image
2. Now we will define three functions, to find the unnecessary contours that
openCV may identify but it does not have probability of being a number plate.
2.1. The first function to check the area range and width-height ratio:
if ratio < 1:
ratio = 1 / ratio
if (area < 1063.62 or area > 73862.5) or (ratio < 3 or ratio > 6):
return False
return True
def isMaxWhite(plate):
avg = np.mean(plate)
if(avg>=115):
return True
else:
return False
def ratio_and_rotation(rect):
if(width>height):
angle = -rect_angle
else:
angle = 90 + rect_angle
if angle>15:
return False
if height == 0 or width == 0:
return False
area = height*width
if not ratioCheck(area,width,height):
return False
else:
return True
3. Now we will write a function to clean the identified number plate for
preprocessing before feeding to pytesseract:
def clean2_plate(plate):
pass
num_contours,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
if num_contours:
max_cntr_index = np.argmax(contour_area)
max_cnt = num_contours[max_cntr_index]
max_cntArea = contour_area[max_cntr_index]
x,y,w,h = cv2.boundingRect(max_cnt)
if not ratioCheck(max_cntArea,w,h):
return plate,None
else:
4. In this step, we will take an image input. We will perform Gaussian Blur, Sobel
and morphological operations. After we find contours in the image and loop
through each contour to identify the number plate. We will then clean the image
contour and feed it to pytesseract to recognize the number and characters.
img = cv2.imread("testData/sample15.jpg")
cv2.imshow("input",img)
pass
img2 = cv2.Sobel(img2,cv2.CV_8U,1,0,ksize=3)
_,img2 = cv2.threshold(img2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
morph_img_threshold = img2.copy()
num_contours, hierarchy=
cv2.findContours(morph_img_threshold,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NON
E)
min_rect = cv2.minAreaRect(cnt)
if ratio_and_rotation(min_rect):
x,y,w,h = cv2.boundingRect(cnt)
plate_img = img[y:y+h,x:x+w]
print("Number identified number plate...")
pass
if(isMaxWhite(plate_img)):
if rect:
fg=0
x1,y1,w1,h1 = rect
x,y,w,h = x+x1,y+y1,w1,h1
# cv2.imwrite("clena.png",clean_plate)
plate_im = Image.fromarray(clean_plate)
import tkinter as tk
import numpy as np
import cv2
def clean2_plate(plate):
num_contours,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
if num_contours:
max_cntr_index = np.argmax(contour_area)
max_cnt = num_contours[max_cntr_index]
max_cntArea = contour_area[max_cntr_index]
x,y,w,h = cv2.boundingRect(max_cnt)
if not ratioCheck(max_cntArea,w,h):
return plate,None
return final_img,[x,y,w,h]
else:
return plate,None
if ratio < 1:
ratio = 1 / ratio
if (area < 1063.62 or area > 73862.5) or (ratio < 3 or ratio > 6):
return False
return True
def isMaxWhite(plate):
avg = np.mean(plate)
if(avg>=115):
return True
else:
return False
def ratio_and_rotation(rect):
if(width>height):
angle = -rect_angle
else:
angle = 90 + rect_angle
if angle>15:
return False
if height == 0 or width == 0:
return False
area = height*width
if not ratioCheck(area,width,height):
return False
else:
return True
top=tk.Tk()
top.geometry('900x700')
img = ImageTk.PhotoImage(Image.open("logo.png"))
top.configure(background='#CDCDCD')
label=Label(top,background='#CDCDCD', font=('arial',35,'bold'))
# label.grid(row=0,column=1)
sign_image = Label(top,bd=10)
plate_image=Label(top,bd=10)
def classify(file_path):
res_text=[0]
res_img=[0]
img = cv2.imread(file_path)
img2 = cv2.Sobel(img2,cv2.CV_8U,1,0,ksize=3)
_,img2 = cv2.threshold(img2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
morph_img_threshold = img2.copy()
num_contours, hierarchy=
cv2.findContours(morph_img_threshold,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NON
E)
min_rect = cv2.minAreaRect(cnt)
if ratio_and_rotation(min_rect):
x,y,w,h = cv2.boundingRect(cnt)
plate_img = img[y:y+h,x:x+w]
res_img[0]=plate_img
cv2.imwrite("result.png",plate_img)
if(isMaxWhite(plate_img)):
if rect:
fg=0
x1,y1,w1,h1 = rect
x,y,w,h = x+x1,y+y1,w1,h1
plate_im = Image.fromarray(clean_plate)
res_text[0]=text
if text:
break
label.configure(foreground='#011638', text=res_text[0])
uploaded=Image.open("result.png")
im=ImageTk.PhotoImage(uploaded)
plate_image.configure(image=im)
plate_image.image=im
plate_image.pack()
plate_image.place(x=560,y=320)
def show_classify_button(file_path):
classify_b.configure(background='#364156', foreground='white',font=('arial',15,'bold'))
classify_b.place(x=490,y=550)
def upload_image():
try:
file_path=filedialog.askopenfilename()
uploaded=Image.open(file_path)
uploaded.thumbnail(((top.winfo_width()/2.25),(top.winfo_height()/2.25)))
im=ImageTk.PhotoImage(uploaded)
sign_image.configure(image=im)
sign_image.image=im
label.configure(text='')
show_classify_button(file_path)
except:
pass
upload=Button(top,text="Upload an image",command=upload_image,padx=10,pady=5)
upload.configure(background='#364156', foreground='white',font=('arial',15,'bold'))
upload.pack()
upload.place(x=210,y=550)
sign_image.pack()
sign_image.place(x=70,y=200)
label.pack()
label.place(x=500,y=220)
heading = Label(top,image=img)
heading.configure(background='#CDCDCD',foreground='#364156')
heading.pack()
top.mainloop()
Summary
In this article, we have developed a deep learning project to recognize license
number plate. We discussed some important features of openCV like Gaussian
blur, Sobel operators, Morphological transformations. The application detects
number plate text from an image. We have identified and cleaned the number plate
using openCV. To identify the number plate digits and characters we used
pytesseract.
: