Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e3e731e

Browse files
Merge pull request avinashkranjan#692 from mehabhalodiya/NumPlate
Added number plate detector
2 parents ebc3467 + f27a242 commit e3e731e

File tree

3 files changed

+153
-0
lines changed

3 files changed

+153
-0
lines changed

‎Num-Plate-Detector/README.md‎

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Number plate detection
2+
3+
## Methodology:
4+
5+
License plate of the vehicle is detected using various features of image processing library openCV and recognizing the text on the license plate using python tool named as tesseract.
6+
7+
To recognize the license plate we are using the fact that license plate of any vehicle has rectangular shape. So, after all the processing of an image we will find the contour having four points inside the list and consider it as the license plate of the vehicle.
8+
9+
</br>
10+
11+
## Dependencies
12+
- OpenCV
13+
- Numpy and Pandas
14+
- [Tesseract 4](https://github.com/tesseract-ocr/tesseract/wiki)
15+
16+
</br>
17+
18+
## Preprocessing
19+
20+
Grayscale images are much easier to work within a variety of tasks like In many morphological operations and image segmentation problems, it is easier to work with the single-layered image (Grayscale image)than a three-layered image (RGB color image ).
21+
22+
</br>
23+
24+
After gray scaling we will blur the gray image to reduce the background noise. I had used the bilateral filter to blur the image because it actually preserves all strength, it removes noise quite well and strengthens the edges in the image when we deal with a single-layered image.
25+
26+
</br>
27+
28+
After blurring we will do edge detection. Canny Edge Detection follows the series of steps and is a very powerful edge detection method. We will use the Canny edge detection to extract the edges from the blurred image because of its optimal result, well-defined edges, and accurate detection.
29+
30+
</br>
31+
32+
After finding edges we will find the contours from and edged image. There are mainly two important types of contours Retrieval Modes. The first one is the `cv2.RETER_LIST` which retrieves all the contours from an image and second is `cv2.RETER_EXTERNAL` which retrieves external or outer contours from an image. There are two types of Approximation Methods. The first method is the `cv2.CHAIN_APPROX_NONE` stores all the boundary points. But we don't necessarily need all bounding points. If the points form a straight line, we only need the start and ending points of that line. The second method is the `cv2.CHAIN_APPROX_SIMPLE` instead only provides these start and endpoints of bounding contours, thus resulting in much more efficient storage of contour information.
33+
34+
</br>
35+
36+
After finding contours we will sort the contours. Sorting contours is quite useful when doing image processing. We will sort contours by area which will help us to eliminate some small and useless contours made by noise and extract the large contours which contain the number plate of a vehicle.
37+
38+
</br>
39+
40+
## Detecting Plate
41+
42+
After we sort the contours we will now take a variable plate and store a value none in the variable recognizing that we did not find number plate till now. Now we iterate through all the contours we get after sorting from the largest to the smallest having our number plate in there so we should be able to segment it out. Now to that, we will look through all the contours and going to calculate the perimeter for the each contour. Then we will use `cv2.approxPolyDP()` function to count the number of sides.
43+
44+
</br>
45+
46+
The `cv2.approxPolyDP()` takes three parameters. First one is the individual contour which we wish to approximate. Second parameter is Approximation Accuracy Important parameter is determining the accuracy of the approximation. Small values give precise- approximations, large values give more generic approximation. A good rule of thumb is less than 5% of the contour perimeter. Third parameter is a Boolean value that states whether the approximate contour should be open or closed.
47+
48+
</br>
49+
50+
I had used contour approximation and it approximate a contour shape to another shape with less number of that is dependent on the position I specify so the 0.02 is the precision that worked.
51+
52+
</br>
53+
54+
## Usage
55+
56+
- `data.csv` contains the date, time and vehicle license number.
57+
- Tesseract is a library which uses OCR engine.
58+
- Tesseract contain more than hundred languages to choose, if you want to change:
59+
- Open `number_plate.py` and change the `config` variable.
60+
- In `config` variable change **'eng'** to your preferred language.
61+
- Use Tesseract 4 as this is the latest version which uses LSTM network.
62+
63+
</br>
64+
65+
Run the following:
66+
67+
python number_plate.py
68+
69+

‎Num-Plate-Detector/car.jpeg‎

7.75 KB
Loading[フレーム]

‎Num-Plate-Detector/number_plate.py‎

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# importing libraries
2+
import numpy as np
3+
import cv2
4+
import imutils
5+
import sys
6+
import pytesseract
7+
import pandas as pd
8+
import time
9+
10+
image = cv2.imread(input("Enter the path of image: "))
11+
12+
image = imutils.resize(image, width=500)
13+
14+
pytesseract.pytesseract.tesseract_cmd = input("Enter the path of tesseract in your local system : ")
15+
16+
# displaying it
17+
cv2.imshow("Original Image", image)
18+
19+
# converting it into gtray scale
20+
# cv2.imshow("1 - Grayscale Conversion", gray)
21+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
22+
23+
#cv2.imshow("2 - Bilateral Filter", gray)
24+
gray = cv2.bilateralFilter(gray, 11, 17, 17)
25+
26+
# canny edge detector
27+
#cv2.imshow("4 - Canny Edges", edged)
28+
edged = cv2.Canny(gray, 170, 200)
29+
30+
"""
31+
there are three arguments in cv2.findContours() function, first one is source image,
32+
second is contour retrieval mode, third is contour approximation method.py
33+
34+
If you pass cv2.CHAIN_APPROX_NONE, all the boundary points are stored.
35+
But actually do we need all the points? For eg, you found the contour of a straight line.
36+
Do you need all the points on the line to represent that line?
37+
No, we need just two end points of that line.
38+
This is what cv2.CHAIN_APPROX_SIMPLE does.
39+
It removes all redundant points and compresses the contour, thereby saving memory.
40+
"""
41+
42+
cnts, _ = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
43+
44+
# contour area is given by the function cv2.contourArea()
45+
cnts=sorted(cnts, key = cv2.contourArea, reverse = True)[:30]
46+
NumberPlateCnt = None
47+
48+
count = 0
49+
for c in cnts:
50+
"""
51+
contour perimeter is also called arclength. It can be found out using cv2.arcLength()
52+
function.Second argument specify whether shape is a closed contour( if passed
53+
True), or just a curve.
54+
"""
55+
peri = cv2.arcLength(c, True)
56+
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
57+
if len(approx) == 4:
58+
NumberPlateCnt = approx
59+
break
60+
61+
# Masking the part other than the number plate
62+
mask = np.zeros(gray.shape,np.uint8)
63+
new_image = cv2.drawContours(mask,[NumberPlateCnt],0,255,-1)
64+
new_image = cv2.bitwise_and(image,image,mask=mask)
65+
cv2.namedWindow("Final_image",cv2.WINDOW_NORMAL)
66+
cv2.imshow("Final_image",new_image)
67+
68+
# Configuration for tesseract
69+
config = ('-l eng --oem 1 --psm 3')
70+
71+
# Run tesseract OCR on image
72+
text = pytesseract.image_to_string(new_image, config=config)
73+
74+
#Data is stored in CSV file
75+
raw_data = {'date': [time.asctime( time.localtime(time.time()) )],
76+
'v_number': [text]}
77+
78+
df = pd.DataFrame(raw_data, columns = ['date', 'v_number'])
79+
df.to_csv('data.csv')
80+
81+
# Print recognized text
82+
print(text)
83+
84+
cv2.waitKey(0)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /