File size: 7,698 Bytes
38a1055
 
 
2f4b30d
40ea775
38a1055
 
 
 
 
 
 
 
47319b1
 
a933dba
cb9aa85
 
4eeed51
2f4b30d
cb9aa85
 
 
 
ce5b353
4eeed51
 
 
 
 
cb9aa85
 
 
 
0680065
 
38a1055
 
 
 
 
 
 
 
 
 
 
4eeed51
 
 
 
38a1055
 
 
 
 
 
 
 
4eeed51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38a1055
4eeed51
 
38a1055
4eeed51
38a1055
4eeed51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38a1055
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92a8619
4c0f9b7
38a1055
 
4c0f9b7
4eeed51
 
 
 
 
 
 
 
38a1055
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2f4b30d
 
38a1055
 
cb6b17d
38a1055
 
84ebb29
 
38a1055
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
import matplotlib.pyplot as plt
import numpy as np
import cv2
from PIL import Image 
import streamlit as st
import tensorflow as tf
from sklearn.metrics import f1_score
from tensorflow.keras import optimizers
from tensorflow.keras.models import Sequential
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Dense, Flatten, MaxPooling2D, Dropout, Conv2D
from tensorflow.keras.models import load_model

  #  copied_image2 = original_image.copy()
  #img = cv2.imread('car3.jpg')

#img = cv2.imread(imagePath)
#gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

def my_function(uploaded_file):

  img = cv2.imread(uploaded_file)
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 
  #img = Image.open(uploaded_file)
  
  # Loads the data required for detecting the license plates from cascade classifier.
  plate_cascade = cv2.CascadeClassifier('indian_license_plate.xml')


  def detect_plate(img, text=''): # the function detects and perfors blurring on the number plate.
    plate_img = img.copy()
    roi = img.copy()
    #plate_img = Image.open(img)
    #roi = Image.open(img) 

      
    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.
    for (x,y,w,h) in plate_rect:
        roi_ = roi[y:y+h, x:x+w, :] # extracting the Region of Interest of license plate for blurring.
        plate = roi[y:y+h, x:x+w, :]
        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.
    if text!='':
        plate_img = cv2.putText(plate_img, text, (x-w//2,y-h//2),
                                cv2.FONT_HERSHEY_COMPLEX_SMALL , 0.5, (51,181,155), 1, cv2.LINE_AA)

    return plate_img, plate # returning the processed image.



  # Testing the above function
  def display(img_, title=''):
    img = cv2.cvtColor(img_, cv2.COLOR_BGR2RGB)
    fig = plt.figure(figsize=(10,6))
    ax = plt.subplot(111)
    ax.imshow(img)
    plt.axis('off')
    plt.title(title)
    plt.show()



  # Getting plate prom the processed image
  output_img, plate = detect_plate(img)


  # Match contours to license plate or character template
  def find_contours(dimensions, img) :

    # Find all contours in the image
    cntrs, _ = cv2.findContours(img.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    # Retrieve potential dimensions
    lower_width = dimensions[0]
    upper_width = dimensions[1]
    lower_height = dimensions[2]
    upper_height = dimensions[3]

    # Check largest 5 or  15 contours for license plate or character respectively
    cntrs = sorted(cntrs, key=cv2.contourArea, reverse=True)[:15]

    ii = cv2.imread('contour.jpg')

    x_cntr_list = []
    target_contours = []
    img_res = []
    for cntr in cntrs :
        # detects contour in binary image and returns the coordinates of rectangle enclosing it
        intX, intY, intWidth, intHeight = cv2.boundingRect(cntr)

        # checking the dimensions of the contour to filter out the characters by contour's size
        if intWidth > lower_width and intWidth < upper_width and intHeight > lower_height and intHeight < upper_height :
            x_cntr_list.append(intX) #stores the x coordinate of the character's contour, to used later for indexing the contours

            char_copy = np.zeros((44,24))
            # extracting each character using the enclosing rectangle's coordinates.
            char = img[intY:intY+intHeight, intX:intX+intWidth]
            char = cv2.resize(char, (20, 40))

            cv2.rectangle(ii, (intX,intY), (intWidth+intX, intY+intHeight), (50,21,200), 2)
            plt.imshow(ii, cmap='gray')

            # Make result formatted for classification: invert colors
            char = cv2.subtract(255, char)

            # Resize the image to 24x44 with black border
            char_copy[2:42, 2:22] = char
            char_copy[0:2, :] = 0
            char_copy[:, 0:2] = 0
            char_copy[42:44, :] = 0
            char_copy[:, 22:24] = 0

            img_res.append(char_copy) # List that stores the character's binary image (unsorted)

    # Return characters on ascending order with respect to the x-coordinate (most-left character first)

    plt.show()
    # arbitrary function that stores sorted list of character indeces
    indices = sorted(range(len(x_cntr_list)), key=lambda k: x_cntr_list[k])
    img_res_copy = []
    for idx in indices:
        img_res_copy.append(img_res[idx])# stores character images according to their index
    img_res = np.array(img_res_copy)

    return img_res


  # Find characters in the resulting images
  def segment_characters(image) :

    # Preprocess cropped license plate image
    img_lp = cv2.resize(image, (333, 75))
    img_gray_lp = cv2.cvtColor(img_lp, cv2.COLOR_BGR2GRAY)
    _, img_binary_lp = cv2.threshold(img_gray_lp, 200, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    img_binary_lp = cv2.erode(img_binary_lp, (3,3))
    img_binary_lp = cv2.dilate(img_binary_lp, (3,3))

    LP_WIDTH = img_binary_lp.shape[0]
    LP_HEIGHT = img_binary_lp.shape[1]

    # Make borders white
    img_binary_lp[0:3,:] = 255
    img_binary_lp[:,0:3] = 255
    img_binary_lp[72:75,:] = 255
    img_binary_lp[:,330:333] = 255

    # Estimations of character contours sizes of cropped license plates
    dimensions = [LP_WIDTH/6,
                       LP_WIDTH/2,
                       LP_HEIGHT/10,
                       2*LP_HEIGHT/3]
    plt.imshow(img_binary_lp, cmap='gray')
    plt.show()
    cv2.imwrite('contour.jpg',img_binary_lp)

    # Get contours within cropped license plate
    char_list = find_contours(dimensions, img_binary_lp)

    return char_list



  # Let's see the segmented characters
  char = segment_characters(plate)




  # Using the Model that we Trained on Kaggle Dataset earlier
  model = load_model('licence_trained_model.h5', compile=False)



  # Predicting the output
  def fix_dimension(img):
    new_img = np.zeros((28,28,3))
    for i in range(3):
      new_img[:,:,i] = img
    return new_img




  def show_results():
    dic = {}
    characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    for i, c in enumerate(characters):
        dic[i] = c

    output = []
    for i, ch in enumerate(char):  # iterating over the characters
        img_ = cv2.resize(ch, (28, 28), interpolation=cv2.INTER_AREA)
        img = fix_dimension(img_)
        img = img.reshape(1, 28, 28, 3)  # preparing image for the model
        predictions = model.predict(img,verbose=0)
        y_ = np.argmax(predictions, axis=1)[0]  # get index of the maximum probability
        character = dic[y_]
        output.append(character)  # storing the result in a list

    plate_number = ''.join(output)
    print(plate_number) #
    st.write(plate_number)


    return plate_number















def run():
    st.write('##### Number plate Recognition')
    # Making Form
    # Create a Streamlit form
    with st.form(key='Number plate Recognition'):
        # Add a file uploader to the form
        uploaded_files = st.file_uploader("Upload a file of one of these format .JPEG/.JPG/.PNG file", accept_multiple_files=True)

        # Check if any file is uploaded
        if uploaded_files:
            for uploaded_file in uploaded_files:
                st.write("filename:", uploaded_file.name)
        # Close the form
        submitted = st.form_submit_button('Recognize')
        
    
    if submitted:
        for uploaded_file in uploaded_files:
            my_function(uploaded_file)
        
        
if __name__ == '__main__':
    run()