ProjectCNN2 / classifier.py
HimanshuA's picture
Update classifier.py
cb9aa85 verified
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()