You are on page 1of 31

A project report on

“NUMBER PLATE DETECTION USING IMAGE


PROCESSING”
A Project Work submitted in partial fulfillment of the requirements for Bachelor's Degree

In

ELECTRICAL AND ELECTRONICS ENGINEERING

By

M V S Mahesh (191230028)

B. Suchitha (191230018)

K. Kiran (181230021)

Under the Supervision of

Dr. Rahul Jaiswal


Assistant Professor

राष्ट्र ीय प्रौद्योगिकी संस्थान दिल्ली

NATIONAL INSTITUTE OF TECHNOLOGY DELHI

(An Autonomous Institute under the aegis of Ministry of Education, Govt. of India)

1
DECLARATION

We hereby declare that the work presented in the report entitled “Number plate
detection using image processing” submitted by us for the fulfilment of the
project, is an authentic record of our work carried out under the guidance of
Dr.Rahul Jaiswal

…………………………

Date: May 13, 2022

M V S Mahesh

…………………………

Date: May 13, 2022

B. Suchitha

…………………………

Date: May 13, 2022

K. Kiran

2
CERTIFICATE
This is to certify that the above statement made by the candidates is correct to the
best of my knowledge.

…………………………….

Date­­: May 13,2022

Dr. Rahul Jaiswal

3
ACKNOWLEDGEMENT

We have taken a lot of effort into this project. However, completing this project
would not have been possible without the support and guidance of a lot of
individuals. We would like to extend our sincere thanks to all of them.

We are highly indebted to Dr. Rahul Jaiswal for his guidance and supervision.
We would like to thank him for providing the necessary information and
resources for this project.

We would like to express our gratitude towards our parents & our friends for
their kind co-operation and encouragement which help us a lot in completing
this project.

Our thanks and appreciations also go to our colleagues in developing the project.
Thank you to all the people who have willingly helped us out with their abilities.

M V S Mahesh

B. Suchitha

K. Kiran

4
CONTENTS

S.No. Title Pg.No.


1. ABSTRACT 6
2. INTRODUCTION 7
3. 9
THEORY

3.1 Digital image transformations

- Filtering
- Affine Transformations
- Image denoising methods with morphology

4. METHODOLOGY 12
5. 15
CODE

5.1 Code for processing the image and extracting


the number plate and subsequently the license
number on the plate

5.2 Code for user interface


6. DEPLOYMENT OF USER INTERFACE 29
7. CONCLUSION 31
8. REFERENCES 31

5
ABSTRACT

The main objective of this project is to automate the entries of vehicles at main gate.

Recognizing Car License Plate is a very important task for a camera surveillance-based
security system. We can extract the license plate from an image using Image processing
techniques and then we can use Optical Character Recognition to recognize the license
number.

The extraction of the image is done in 3 steps:

Step 1: Extraction of an image from a video.

Step 2: Processing the image to extract the number plate.

Step 3: Extracting the plate number from the previously extracted number plate.

6
INTRODUCTION

Digital image processing is the use of a digital computer to process digital images
through an algorithm. As a subcategory or field of digital signal processing, digital
image processing has many advantages over analog image processing. It allows a
much wider range of algorithms to be applied to the input data and can avoid
problems such as the build-up of noise and distortion during processing. Since
images are defined over two dimensions (perhaps more) digital image processing
may be modeled in the form of multidimensional systems. The generation and
development of digital image processing are mainly affected by three factors: first,
the development of computers; second, the development of mathematics
(especially the creation and improvement of discrete mathematics theory); third,
the demand for a wide range of applications in environment, agriculture, military,
industry and medical science has increased.

Image processing for this particular project includes:

● Finding contours
● Finding vertical edges
● Grey scaling the image
● Binarizing the image
● Applying closing morphological transformation

Contours of an image:
Contours are the line joining all the points along the boundary of an image that are
having the same intensity. It helps in shape analysis.

Gray scale:

In digital images, grayscale means that the value of each pixel represents only the

7
intensity information of the light. Such images typically display only the darkest black to
the brightest white. In other words, the image contains only black, white, and gray colors,
in which gray has multiple levels.

Image Binarization:

It is the conversion of document image into bi-level document image. Image


pixels are separated into dual collection of pixels, i.e. black and white. The main goal of
image binarization is the segmentation of document into foreground text and background.

Morphing

It is a special effect in motion pictures and animations that changes (or morphs)
one image or shape into another through a seamless transition. Traditionally such a
depiction would be achieved through dissolving techniques on film.

Morphological closing

It is a dilation followed by an erosion (i.e. the reverse of the operations for an


opening). As you might be able to guess, the net effect of the closing operation is to
remove background pixels that fit the structuring element. In other words, closing tends
to close gaps in the image

8
THEORY
Digital image processing is the use of a digital computer to process digital images
through an algorithm. As a subcategory or field of digital signal processing, digital
image processing has many advantages over analog image processing. It allows a
much wider range of algorithms to be applied to the input data and can avoid
problems such as the build-up of noise and distortion during processing. Since
images are defined over two dimensions (perhaps more) digital image processing
may be modeled in the form of multidimensional systems. The generation and
development of digital image processing are mainly affected by three factors: first,
the development of computers; second, the development of mathematics
(especially the creation and improvement of discrete mathematics theory); third,
the demand for a wide range of applications in environment, agriculture, military,
industry and medical science has increased.

Digital Image Transformations

1. Filtering

Digital filters are used to blur and sharpen digital images. Filtering can be
performed by:
● convolution with specifically designed kernels (filter array) in the spatial
domain
● masking specific frequency regions in the frequency (Fourier) domain
2. Affine transformations

Affine transformations enable basic image transformations including scale,


rotate, translate, mirror and shear

9
To apply the affine matrix to an image, the image is converted to matrix in
which each entry corresponds to the pixel intensity at that location. Then each
pixel's location can be represented as a vector indicating the coordinates of that
pixel in the image, [x, y], where x and y are the row and column of a pixel in the
image matrix. This allows the coordinate to be multiplied by an
affine-transformation matrix, which gives the position that the pixel value will be
copied to in the output image.
However, to allow transformations that require translation transformations, 3
dimensional homogeneous coordinates are needed. The third dimension is usually
set to a non-zero constant, usually 1, so that the new coordinate is [x, y, 1]. This
allows the coordinate vector to be multiplied by a 3 by 3 matrix, enabling
translation shifts. So the third dimension, which is the constant 1, allows
translation.
Because matrix multiplication is associative, multiple affine transformations
can be combined into a single affine transformation by multiplying the matrix of
each individual transformation in the order that the transformations are done. This
results in a single matrix that, when applied to a point vector, gives the same result
as all the individual transformations performed on the vector [x, y, 1] in sequence.
Thus a sequence of affine transformation matrices can be reduced to a single affine
transformation matrix.

3. Image denoising with Morphology


Mathematical morphology is suitable for denoising images. Structuring
element are important in Mathematical morphology.
In order to apply the denoising method to an image, the image is converted
into grayscale. A mask with denoising method is logical matrix with [1 1 1; 1 1 1 ;
1 1 1]. The denoising methods start from the center of the picture with half of
height, half of width, and end with the image boundary of row number, column
number. Neighbor is a block in the original image with the boundary [the point
below center: the point above, the point on left of center: the point on the right of
center]. Convolution Neighbor and structuring element and then replace the center
with a minimum of neighbor.

10
Take the Closing method for example.
Dilation first
1. Read the image and convert it into grayscale with Matlab.
1. Get the size of an image. The return value row numbers
and column numbers are the boundaries we are going to
use later.
2. structuring elements depend on your dilation or erosion
function. The minimum of the neighbor of a pixel leads to
an erosion method and the maximum of neighbor leads to
a dilation method.
3. Set the time for dilation, erosion, and closing.
2. Create a zero matrix of the same size as the original image.
3. Dilation first with structuring window.
1. structuring window is 3*3 matrix and convolution
2. For loop extract the minimum with window from row
range [2 ~ image height - 1] with column range [2 ~
image width - 1]
4. Fill the minimum value to the zero matrix and save a new image
1. For the boundary, it can still be improved. Since in the
method, a boundary is ignored. Padding elements can be
applied to deal with boundaries.
Then Erosion (Take the dilation image as input)
1. Create a zero matrix of the same size as the original image.
2. Erosion with structuring window.
1. structuring window is 3*3 matrix and convolution
2. For loop extract the maximum with window from row
range [2 ~ image height - 1] with column range [2 ~
image width - 1]
3. Fill the maximum value to the zero matrix and save a new image
1. For the boundary, it can still be improved. Since in the
method, boundary is ignored. Padding elements can be
applied to deal with boundaries.
4. Results are as above table shown

11
METHODOLOGY

1. To reduce the noise we need to blur the input Image with Gaussian Blur then
convert the it to grayscale.

Fig. 1.1: Blurred (Using Gaussian Blur) and grayscaled


2. Find vertical edges in the image.

Fig. 1.2: Finding Vertical Edges

12
3. To reveal the plate we have to binarize the image. For this apply Otsu’s
Thresholding on the vertical edge image. In other thresholding methods we have
to choose a threshold value to binarize the image but Otsu’s Thresholding
determines the value automatically.

Fig. 1.3: Binarized image using Otsu’s Thresholding


4. Apply Closing Morphological Transformation on thresholded image. Closing is
useful to fill small black regions between white regions in a thresholded image. It
reveals the rectangular white box of the license plate.

Fig 1.4: Applying Closing Morphological Transformation

13
5. To detect the plate we need to find contours in the image. It is important to
binarize and morph the image before finding contours so that it can find more
relevant and less number of contours in the image. If you draw all the extracted
contours on original image, it would look like this:

Fig. 1.5: Overlaying Contoured Image over the Original Image


6. Now find the minimum area rectangle enclosed by each of the contour and
validate their side ratios and area. We have defined the minimum and maximum
area of the plate as 4500 and 30000 respectively.
7. Now find the contours in the validated region and validate the side ratios and area
of the bounding rectangle of the largest contour in that region. After validating you
will get a perfect contour of a license plate. Now extract that contour from the
original image. We will get the image of plate:

Fig. 1.6: Extracted Number Plate Image

14
CODE
Code for processing the image and extracting the number plate and
subsequently the license number on the plate:

import cv2
import numpy as np
from skimage.filters import threshold_local
import tensorflow as tf
from skimage import measure
import imutils
from datetime import datetime

def sort_cont(character_contours):
"""
To sort contours from left to right
"""
i = 0
boundingBoxes = [cv2.boundingRect(c) for c in character_contours]
(character_contours, boundingBoxes) =
zip(*sorted(zip(character_contours, boundingBoxes),
key=lambda b:
b[1][i], reverse=False))
return character_contours

def segment_chars(plate_img, fixed_width):


"""
extract Value channel from the HSV format of image and apply adaptive
thresholding
to reveal the characters on the license plate
"""
V = cv2.split(cv2.cvtColor(plate_img, cv2.COLOR_BGR2HSV))[2]

T = threshold_local(V, 29, offset=15, method='gaussian')

thresh = (V > T).astype('uint8') * 255

thresh = cv2.bitwise_not(thresh)

15
# resize the license plate region to a canoncial size
plate_img = imutils.resize(plate_img, width=fixed_width)
thresh = imutils.resize(thresh, width=fixed_width)
bgr_thresh = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)

# perform a connected components analysis and initialize the mask to


store the locations
# of the character candidates
labels = measure.label(thresh, connectivity=2, background=0)

charCandidates = np.zeros(thresh.shape, dtype='uint8')

# loop over the unique components


characters = []
for label in np.unique(labels):
# if this is the background label, ignore it
if label == 0:
continue
# otherwise, construct the label mask to display only connected
components for the
# current label, then find contours in the label mask
labelMask = np.zeros(thresh.shape, dtype='uint8')
labelMask[labels == label] = 255

cnts = cv2.findContours(labelMask, cv2.RETR_EXTERNAL,


cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[1] if imutils.is_cv3() else cnts[0]

# ensure at least one contour was found in the mask


if len(cnts) > 0:

# grab the largest contour which corresponds to the component


in the mask, then
# grab the bounding box for the contour
c = max(cnts, key=cv2.contourArea)
(boxX, boxY, boxW, boxH) = cv2.boundingRect(c)

# compute the aspect ratio, solodity, and height ration for


the component

16
aspectRatio = boxW / float(boxH)
solidity = cv2.contourArea(c) / float(boxW * boxH)
heightRatio = boxH / float(plate_img.shape[0])

# determine if the aspect ratio, solidity, and height of the


contour pass
# the rules tests
keepAspectRatio = aspectRatio < 1.0
keepSolidity = solidity > 0.15
keepHeight = heightRatio > 0.5 and heightRatio < 0.95

# check to see if the component passes all the tests


if keepAspectRatio and keepSolidity and keepHeight and boxW >
14:
# compute the convex hull of the contour and draw it on
the character
# candidates mask
hull = cv2.convexHull(c)

cv2.drawContours(charCandidates, [hull], -1, 255, -1)

contours, hier = cv2.findContours(charCandidates, cv2.RETR_EXTERNAL,


cv2.CHAIN_APPROX_SIMPLE)
if contours:
contours = sort_cont(contours)
addPixel = 4 # value to be added to each dimension of the
character
for c in contours:
(x, y, w, h) = cv2.boundingRect(c)
if y > addPixel:
y = y - addPixel
else:
y = 0
if x > addPixel:
x = x - addPixel
else:
x = 0
temp = bgr_thresh[y:y + h + (addPixel * 2), x:x + w +
(addPixel * 2)]

17
characters.append(temp)
return characters
else:
return None

class PlateFinder:
def __init__(self):
self.min_area = 4500 # minimum area of the plate
self.max_area = 30000 # maximum area of the plate

self.element_structure =
cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(22, 3))

def preprocess(self, input_img):


imgBlurred = cv2.GaussianBlur(input_img, (7, 7), 0) # old window
was (5,5)
gray = cv2.cvtColor(imgBlurred, cv2.COLOR_BGR2GRAY) # convert to
gray
sobelx = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize=3) # sobelX to
get the vertical edges
ret2, threshold_img = cv2.threshold(sobelx, 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)

element = self.element_structure
morph_n_thresholded_img = threshold_img.copy()
cv2.morphologyEx(src=threshold_img, op=cv2.MORPH_CLOSE,
kernel=element, dst=morph_n_thresholded_img)
return morph_n_thresholded_img

def extract_contours(self, after_preprocess):


contours, _ = cv2.findContours(after_preprocess,
mode=cv2.RETR_EXTERNAL,

method=cv2.CHAIN_APPROX_NONE)
return contours

def clean_plate(self, plate):


gray = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)

18
thresh = cv2.adaptiveThreshold(gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)

if contours:
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas) # index of the largest contour
in the area array

max_cnt = contours[max_index]
max_cntArea = areas[max_index]
x, y, w, h = cv2.boundingRect(max_cnt)
rect = cv2.minAreaRect(max_cnt)
rotatedPlate = plate
if not self.ratioCheck(max_cntArea, rotatedPlate.shape[1],
rotatedPlate.shape[0]):
return plate, False, None
return rotatedPlate, True, [x, y, w, h]
else:
return plate, False, None

def check_plate(self, input_img, contour):


min_rect = cv2.minAreaRect(contour)
if self.validateRatio(min_rect):
x, y, w, h = cv2.boundingRect(contour)
after_validation_img = input_img[y:y + h, x:x + w]
after_clean_plate_img, plateFound, coordinates =
self.clean_plate(after_validation_img)
if plateFound:
characters_on_plate =
self.find_characters_on_plate(after_clean_plate_img)
if (characters_on_plate is not None and
len(characters_on_plate) == 8):
x1, y1, w1, h1 = coordinates
coordinates = x1 + x, y1 + y
after_check_plate_img = after_clean_plate_img

19
return after_check_plate_img, characters_on_plate,
coordinates
return None, None, None

def find_possible_plates(self, input_img):


"""
Finding all possible contours that can be plates
"""
plates = []
self.char_on_plate = []
self.corresponding_area = []

self.after_preprocess = self.preprocess(input_img)
possible_plate_contours =
self.extract_contours(self.after_preprocess)

for cnts in possible_plate_contours:


plate, characters_on_plate, coordinates =
self.check_plate(input_img, cnts)
if plate is not None:
plates.append(plate)
self.char_on_plate.append(characters_on_plate)
self.corresponding_area.append(coordinates)

if (len(plates) > 0):


return plates
else:
return None

def find_characters_on_plate(self, plate):

charactersFound = segment_chars(plate, 400)


if charactersFound:
return charactersFound

# PLATE FEATURES
def ratioCheck(self, area, width, height):
min = self.min_area

20
max = self.max_area

ratioMin = 3
ratioMax = 6

ratio = float(width) / float(height)


if ratio < 1:
ratio = 1 / ratio

if (area < min or area > max) or (ratio < ratioMin or ratio >
ratioMax):
return False
return True

def preRatioCheck(self, area, width, height):


min = self.min_area
max = self.max_area

ratioMin = 2.5
ratioMax = 7

ratio = float(width) / float(height)


if ratio < 1:
ratio = 1 / ratio

if (area < min or area > max) or (ratio < ratioMin or ratio >
ratioMax):
return False
return True

def validateRatio(self, rect):


(x, y), (width, height), rect_angle = rect

if (width > height):


angle = -rect_angle
else:
angle = 90 + rect_angle

if angle > 15:


return False

21
if (height == 0 or width == 0):
return False

area = width * height


if not self.preRatioCheck(area, width, height):
return False
else:
return True

class NeuralNetwork:
def __init__(self):
self.model_file = "./model/binary_128_0.50_ver3.pb"
self.label_file = "./model/binary_128_0.50_labels_ver2.txt"
self.label = self.load_label(self.label_file)
self.graph = self.load_graph(self.model_file)
self.sess = tf.compat.v1.Session(graph=self.graph)

def load_graph(self, modelFile):


graph = tf.Graph()
graph_def = tf.compat.v1.GraphDef()
with open(modelFile, "rb") as f:
graph_def.ParseFromString(f.read())
with graph.as_default():
tf.import_graph_def(graph_def)
return graph

def load_label(self, labelFile):


label = []
proto_as_ascii_lines = tf.io.gfile.GFile(labelFile).readlines()
for l in proto_as_ascii_lines:
label.append(l.rstrip())
return label

def convert_tensor(self, image, imageSizeOuput):


"""
takes an image and tranform it in tensor

22
"""
image = cv2.resize(image, dsize=(imageSizeOuput, imageSizeOuput),
interpolation=cv2.INTER_CUBIC)
np_image_data = np.asarray(image)
np_image_data = cv2.normalize(np_image_data.astype('float'), None,
-0.5, .5, cv2.NORM_MINMAX)
np_final = np.expand_dims(np_image_data, axis=0)
return np_final

def label_image(self, tensor):

input_name = "import/input"
output_name = "import/final_result"

input_operation = self.graph.get_operation_by_name(input_name)
output_operation = self.graph.get_operation_by_name(output_name)

results = self.sess.run(output_operation.outputs[0],
{input_operation.outputs[0]: tensor})
results = np.squeeze(results)
labels = self.label
top = results.argsort()[-1:][::-1]
return labels[top[0]]

def label_image_list(self, listImages, imageSizeOuput):


plate = ""
for img in listImages:
if cv2.waitKey(25) & 0xFF == ord('q'):
break
plate = plate + self.label_image(self.convert_tensor(img,
imageSizeOuput))
return plate, len(plate)

def main(location):
findPlate = PlateFinder()

# Initialize the Neural Network


model = NeuralNetwork()

23
# Store plates in plates variable
plates = []

# Current date time


current = datetime.now()

cap = cv2.VideoCapture(location)
while (cap.isOpened()):
ret, img = cap.read()
if ret == True:
cv2.imshow('original video', img)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# cv2.waitKey(0)
possible_plates = findPlate.find_possible_plates(img)
if possible_plates is not None:
for i, p in enumerate(possible_plates):
chars_on_plate = findPlate.char_on_plate[i]
recognized_plate, _ =
model.label_image_list(chars_on_plate, imageSizeOuput=128)
plates.append(recognized_plate)
if (datetime.now() - current).total_seconds > 2:
break
cv2.imshow('plate', p)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break

cap.release()
cv2.destroyAllWindows()

return list(set(plates))

24
Code for user interface:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"
/>
<title>Number Plate Recognization</title>

<!-- Bootstrap CSS -->


<link

href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.
css"
rel="stylesheet"

integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2
QvZ6jIW3"
crossorigin="anonymous"
/>

<style>
html,
body {
height: 100%;
}

body {
display: flex;
align-items: center;
padding-top: 40px;
padding-bottom: 40px;
background-color: #f5f5f5;
background-image:
url('https://eskipaper.com/images/road-wallpaper-20.jpg');
background-size: cover;
}

25
.output {
font-weight: bold;
}

.form-signin {
width: 100%;
max-width: 330px;
padding: 15px;
margin: auto;
}

.form-signin .checkbox {
font-weight: 400;
}

.form-floating {
margin: 10px 0;
}

.form-signin .form-floating:focus-within {
z-index: 2;
}

.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}

.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}

.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;

26
user-select: none;
}

@media (min-width: 768px) {


.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
</head>
<body class="text-center">
<main class="form-signin">
<form method="POST" action="/" enctype ="multipart/form-data">
{% csrf_token %}
<p class="output">{{variable}}</p>
<h1 class="h3 mb-3 fw-normal">Upload Video Here</h1>
<div class="form-floating">
<input
type="file"
class="form-control"
id="id_docfile"
name="docfile"
required
/>
<label for="id_docfile"></label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">
Proceed
</button>
<!-- <a href="/signup">Not a user? Sign Up</a> -->
<p class="mt-5 mb-3 text-muted">&copy; 2017–2021</p>
</form>
</main>

<!-- Optional JavaScript; choose one of the two! -->

<!-- Option 1: Bootstrap Bundle with Popper -->


<script

27
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle
.min.js"

integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8n
bTov4+1p"
crossorigin="anonymous"
></script>

<!-- Option 2: Separate Popper and Bootstrap JS -->


<!--
<script
src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.mi
n.js"
integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa0
3rtR1zdB" crossorigin="anonymous"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js
"
integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/
YESvpZ13" crossorigin="anonymous"></script>
-->
</body>
</html>

28
DEPLOYMENT OF USER INTERFACE

Fig. 2.1: UI as seen by user

Fig. 2.2: UI as seen by user after uploading video

29
Fig. 2.3: UI as seen by user showing the number plates found

30
CONCLUSION
● The number plate extraction is done using various techniques of image
processing. The number plate is then segmented and OCR (Optical
Character Recognition) is used to recognize the license number on the plate.

● The UI is connected with the image processing code. The UI takes in the
video from the user and sends the video to the image processing code. This
also displays the output given by the code.

● The same code can be used to extract number plates in real time. This works
to automate the entries of vehicles into campus from any gate reducing the
chance of any error in the record of entries and also reducing the effort and
time required to do so.

REFERENCES
1. https://towardsdatascience.com/build-optical-character-recognition-
ocr-in-python
2. https://docs.opencv.org/4.x/d4/d13/tutorial_py_filtering.html
3. Automatic Number Plate Recognition System (ANPR): A Survey by
Chirag Indravadan Bhai Patel.
4. Documentation of libraries in OpenCV : “https://docs.opencv.org/4.x/”

31

You might also like