Automatic Number Plate Recognition with Easy OCR and OpenCV

Muhammad Moin
Augmented AI
Published in
4 min readSep 28, 2022

In this article, Automatic Number Plate Recognition is implemented with Easy OCR and Open CV

Easy OCR is a python based library with ready to use OCR models

The implementation of ANPR is divided into several small steps

  1. Install and Import Dependencies
  2. Reading an Image
  3. Apply Filter and Find Edges For Localization
  4. Find the Contours and Apply Mask
  5. Creating a Blank Mask:
  6. Drawing the Contours
  7. Use Easy OCR to Read Text
  8. Render Results: Overlay Results on the Original Image

Install and Import Dependencies

Install Dependencies

!pip install easyocr!pip install imutils

Importing the Required Libraries

import cv2import numpy as npimport matplotlib.pyplot as pltimport imutilsimport easyocr

Reading an Image

The image will be used to test the designed Automatic Number Plate Recognition System (ANPR)

img = cv2.imread('test.jpg')
Sample Image (To test Automatic Number Plate Recognition System)

While extracting information from the image, the image is converted into Gray Scale, as it simplifies the algorithm and reduces the computational requirements

When cv2 reads an image, it reads in the format of Blue, Green and Red

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

To display the image using Matplotlib, the image needs to be in RGB format, as the image is currently in BGR format, it will be converted into the RGB format

plt.imshow(cv2.cvtColor(gray, cv2.COLOR_BGR2RGB))

Apply Filter and Find Edges For Localization

Filtering is applied to remove the noise from the image and edge detection enable us to find edges with in the image

bfilter = cv2.bilateralFilter(gray, 11, 11, 17)

For Edge Detection, Canny Algorithm is used

edged = cv2.Canny(bfilter, 30, 200)

Lets see the resulting images

plt.imshow(cv2.cvtColor(edged, cv2.COLOR_BGR2RGB))
Edges of the Image

Find the Contours and Apply Mask

The last parameter cv2.CHAIN_APPROX_SIMPLE, gives us the simplified version of contours

cv2.CHAIN_APPROX_NONE gives (734 points) and with cv2.CHAIN_APPROX_SIMPLE (only 4 points)

keypoints = cv2.findContours(edged.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

Ideally, in number plate recognition, we should get 4 key points from contour

contours = imutils.grab_contours(keypoints)

Sorting the Top 10 Contours

contours = sorted(contours, key = cv2.contourArea, reverse = True)[:10]

Now, we will loop through each of the contour and see whether it actually represents a square or a number plate

If our approximation has 4 key points, it will be most likely be specified as out Number Plate Location

location = Nonefor contour in contours:
# cv2.approxPolyDP returns a resampled contour, so this will still return a set of (x, y) points
approx = cv2.approxPolyDP(contour, 10, True)
if len(approx) == 4:
location = approx
break

Creating a Blank Mask:

Now, a blank mask will be created, the mask will have the same shape as the gray image

mask = np.zeros(gray.shape, np.uint8)

Drawing the Contours

new_image = cv2.drawContours(mask, [location], 0, 255, -1)

The bitwise_and operator returns an array that corresponds to the resulting image from the merger of the given two images.

new_image = cv2.bitwise_and(img, img, mask = mask)plt.imshow(cv2.cvtColor(new_image, cv2.COLOR_BGR2RGB))

In the next step, we will find all those section where the image isn’t black

To get the image which purely represent the segment which has the number plate

(x, y) = np.where(mask == 255)(x1, y1) = (np.min(x), np.min(y))(x2, y2) = (np.max(x), np.max(y))# Adding Buffercropped_image = gray[x1:x2+3, y1:y2+3]plt.imshow(cv2.cvtColor(cropped_image, cv2.COLOR_BGR2RGB))
Adding Buffer

Use Easy OCR to Read Text

reader = easyocr.Reader(['en'])result = reader.readtext(cropped_image)print(result)

Render Results: Overlay Results on the Original Image

text = result[0][1]font = cv2.FONT_HERSHEY_SIMPLEXres = cv2.putText(img, text = text, org = (approx[0][0][0], approx[1][0][1]+60), fontFace = font, fontScale = 1, color = (0, 255, 0), thickness = 5)res = cv2.rectangle(img, tuple(approx[0][0]), tuple(approx[2][0]), (0,255, 0), 3)plt.imshow(cv2.cvtColor(res, cv2.COLOR_BGR2RGB))
Final Image

The github link contain the complete script.

Courses & Projects

YOLO+ Subscription

Augmented Startup Courses

--

--