HimanshuA commited on
Commit
0fcef81
1 Parent(s): 2c6c983

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +216 -0
app.py ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib.pyplot as plt
2
+ import numpy as np
3
+ import cv2
4
+ import tensorflow as tf
5
+ from sklearn.metrics import f1_score
6
+ from tensorflow.keras import optimizers
7
+ from tensorflow.keras.models import Sequential
8
+ from tensorflow.keras.preprocessing.image import ImageDataGenerator
9
+ from tensorflow.keras.layers import Dense, Flatten, MaxPooling2D, Dropout, Conv2D
10
+ import streamlit as st
11
+
12
+
13
+ # Loads the data required for detecting the license plates from cascade classifier.
14
+ plate_cascade = cv2.CascadeClassifier('../input/ai-indian-license-plate-recognition-data/indian_license_plate.xml')
15
+ # add the path to 'india_license_plate.xml' file.
16
+
17
+
18
+
19
+ model = load_model('.h5', compile=False)
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+ def detect_plate(img, text=''): # the function detects and perfors blurring on the number plate.
28
+ plate_img = img.copy()
29
+ roi = img.copy()
30
+ plate_rect = plate_cascade.detectMultiScale(plate_img, scaleFactor = 1.2, minNeighbors = 7) # detects numberplates and returns the coordinates and dimensions of detected license plate's contours.
31
+ for (x,y,w,h) in plate_rect:
32
+ roi_ = roi[y:y+h, x:x+w, :] # extracting the Region of Interest of license plate for blurring.
33
+ plate = roi[y:y+h, x:x+w, :]
34
+ cv2.rectangle(plate_img, (x+2,y), (x+w-3, y+h-5), (51,181,155), 3) # finally representing the detected contours by drawing rectangles around the edges.
35
+ if text!='':
36
+ plate_img = cv2.putText(plate_img, text, (x-w//2,y-h//2),
37
+ cv2.FONT_HERSHEY_COMPLEX_SMALL , 0.5, (51,181,155), 1, cv2.LINE_AA)
38
+
39
+ return plate_img, plate # returning the processed image.
40
+
41
+
42
+
43
+
44
+ # Testing the above function
45
+ def display(img_, title=''):
46
+ img = cv2.cvtColor(img_, cv2.COLOR_BGR2RGB)
47
+ fig = plt.figure(figsize=(10,6))
48
+ ax = plt.subplot(111)
49
+ ax.imshow(img)
50
+ plt.axis('off')
51
+ plt.title(title)
52
+ plt.show()
53
+
54
+ # img = cv2.imread('../input/ai-indian-license-plate-recognition-data/car.jpg')
55
+ display(img, 'input image')
56
+
57
+
58
+
59
+ # Getting plate prom the processed image
60
+ output_img, plate = detect_plate(img)
61
+
62
+
63
+
64
+ display(output_img, 'detected license plate in the input image')
65
+
66
+
67
+
68
+ display(plate, 'extracted license plate from the image')
69
+
70
+
71
+
72
+
73
+ # Match contours to license plate or character template
74
+ def find_contours(dimensions, img) :
75
+
76
+ # Find all contours in the image
77
+ cntrs, _ = cv2.findContours(img.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
78
+
79
+ # Retrieve potential dimensions
80
+ lower_width = dimensions[0]
81
+ upper_width = dimensions[1]
82
+ lower_height = dimensions[2]
83
+ upper_height = dimensions[3]
84
+
85
+ # Check largest 5 or 15 contours for license plate or character respectively
86
+ cntrs = sorted(cntrs, key=cv2.contourArea, reverse=True)[:15]
87
+
88
+ ii = cv2.imread('contour.jpg')
89
+
90
+ x_cntr_list = []
91
+ target_contours = []
92
+ img_res = []
93
+ for cntr in cntrs :
94
+ # detects contour in binary image and returns the coordinates of rectangle enclosing it
95
+ intX, intY, intWidth, intHeight = cv2.boundingRect(cntr)
96
+
97
+ # checking the dimensions of the contour to filter out the characters by contour's size
98
+ if intWidth > lower_width and intWidth < upper_width and intHeight > lower_height and intHeight < upper_height :
99
+ x_cntr_list.append(intX) #stores the x coordinate of the character's contour, to used later for indexing the contours
100
+
101
+ char_copy = np.zeros((44,24))
102
+ # extracting each character using the enclosing rectangle's coordinates.
103
+ char = img[intY:intY+intHeight, intX:intX+intWidth]
104
+ char = cv2.resize(char, (20, 40))
105
+
106
+ cv2.rectangle(ii, (intX,intY), (intWidth+intX, intY+intHeight), (50,21,200), 2)
107
+ plt.imshow(ii, cmap='gray')
108
+
109
+ # Make result formatted for classification: invert colors
110
+ char = cv2.subtract(255, char)
111
+
112
+ # Resize the image to 24x44 with black border
113
+ char_copy[2:42, 2:22] = char
114
+ char_copy[0:2, :] = 0
115
+ char_copy[:, 0:2] = 0
116
+ char_copy[42:44, :] = 0
117
+ char_copy[:, 22:24] = 0
118
+
119
+ img_res.append(char_copy) # List that stores the character's binary image (unsorted)
120
+
121
+ # Return characters on ascending order with respect to the x-coordinate (most-left character first)
122
+
123
+ plt.show()
124
+ # arbitrary function that stores sorted list of character indeces
125
+ indices = sorted(range(len(x_cntr_list)), key=lambda k: x_cntr_list[k])
126
+ img_res_copy = []
127
+ for idx in indices:
128
+ img_res_copy.append(img_res[idx])# stores character images according to their index
129
+ img_res = np.array(img_res_copy)
130
+
131
+ return img_res
132
+
133
+
134
+
135
+
136
+
137
+ # Find characters in the resulting images
138
+ def segment_characters(image) :
139
+
140
+ # Preprocess cropped license plate image
141
+ img_lp = cv2.resize(image, (333, 75))
142
+ img_gray_lp = cv2.cvtColor(img_lp, cv2.COLOR_BGR2GRAY)
143
+ _, img_binary_lp = cv2.threshold(img_gray_lp, 200, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
144
+ img_binary_lp = cv2.erode(img_binary_lp, (3,3))
145
+ img_binary_lp = cv2.dilate(img_binary_lp, (3,3))
146
+
147
+ LP_WIDTH = img_binary_lp.shape[0]
148
+ LP_HEIGHT = img_binary_lp.shape[1]
149
+
150
+ # Make borders white
151
+ img_binary_lp[0:3,:] = 255
152
+ img_binary_lp[:,0:3] = 255
153
+ img_binary_lp[72:75,:] = 255
154
+ img_binary_lp[:,330:333] = 255
155
+
156
+ # Estimations of character contours sizes of cropped license plates
157
+ dimensions = [LP_WIDTH/6,
158
+ LP_WIDTH/2,
159
+ LP_HEIGHT/10,
160
+ 2*LP_HEIGHT/3]
161
+ plt.imshow(img_binary_lp, cmap='gray')
162
+ plt.show()
163
+ cv2.imwrite('contour.jpg',img_binary_lp)
164
+
165
+ # Get contours within cropped license plate
166
+ char_list = find_contours(dimensions, img_binary_lp)
167
+
168
+ return char_list
169
+
170
+
171
+
172
+ # Let's see the segmented characters
173
+ char = segment_characters(plate)
174
+
175
+
176
+
177
+
178
+ for i in range(10):
179
+ plt.subplot(1, 10, i+1)
180
+ plt.imshow(char[i], cmap='gray')
181
+ plt.axis('off')
182
+
183
+
184
+
185
+
186
+
187
+ # Predicting the output
188
+ def fix_dimension(img):
189
+ new_img = np.zeros((28,28,3))
190
+ for i in range(3):
191
+ new_img[:,:,i] = img
192
+ return new_img
193
+
194
+ def show_results():
195
+ dic = {}
196
+ characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
197
+ for i,c in enumerate(characters):
198
+ dic[i] = c
199
+
200
+ output = []
201
+ for i,ch in enumerate(char): #iterating over the characters
202
+ img_ = cv2.resize(ch, (28,28), interpolation=cv2.INTER_AREA)
203
+ img = fix_dimension(img_)
204
+ img = img.reshape(1,28,28,3) #preparing image for the model
205
+ y_ = model.predict_classes(img)[0] #predicting the class
206
+ character = dic[y_] #
207
+ output.append(character) #storing the result in a list
208
+
209
+ plate_number = ''.join(output)
210
+
211
+ return plate_number
212
+
213
+ print(show_results())
214
+
215
+
216
+