|
import streamlit as st |
|
import argparse |
|
import io |
|
from io import BytesIO |
|
from PIL import ImageOps, Image |
|
import warnings |
|
import os |
|
import cv2 |
|
import random |
|
import warnings |
|
import numpy as np |
|
import pandas as pd |
|
import seaborn as sns |
|
from tqdm import tqdm |
|
from ultralytics import YOLO |
|
from termcolor import colored |
|
import matplotlib.pyplot as plt |
|
|
|
warnings.filterwarnings('ignore') |
|
|
|
st.set_page_config( |
|
page_title="Auto NPR", |
|
page_icon="β¨", |
|
layout="centered", |
|
initial_sidebar_state="expanded", |
|
) |
|
|
|
top_image = Image.open('favicon.ico') |
|
main_image = Image.open('main_banner.png') |
|
|
|
upload_path = "" |
|
download_path = "" |
|
|
|
st.image(main_image,use_column_width='auto') |
|
st.sidebar.image(top_image,use_column_width='auto') |
|
st.sidebar.header('Input') |
|
selected_type = st.sidebar.selectbox('Please select an activity type', ["Upload Image", "Live Video Feed"]) |
|
|
|
|
|
best_model_plate = YOLO('best.pt') |
|
best_model_digits = YOLO('best2.pt') |
|
|
|
def Detect_Plate(img): |
|
''' |
|
Predict on a car image and return result folder and predicted image path. |
|
''' |
|
result1 = best_model_plate.predict([img], save=True, iou=0.7) |
|
|
|
|
|
result_path1 = result1[0].save_dir |
|
pred1_path = os.path.join(result_path1, os.listdir(result_path1)[-1]) |
|
return result1, pred1_path |
|
|
|
def Detect_Digits(img2) : |
|
''' |
|
Predict on a croped plate and return result folder and predicted image. |
|
''' |
|
result2 = best_model_digits.predict([img2], save=True, iou=0.7, show_conf=False) |
|
|
|
|
|
result_path = result2[0].save_dir |
|
pred2_path = os.path.join(result_path, os.listdir(result_path)[0]) |
|
return result2, pred2_path |
|
|
|
def Sort_Digits(result2) : |
|
''' |
|
Sort detected labels base on their X-cordinate, |
|
--- Sort from lef to right --- |
|
''' |
|
list_of_items = [] |
|
for i in range(len(result2[0])) : |
|
|
|
class_label = classes_dict[str(int(result2[0][i].boxes.cls))] |
|
|
|
cord_x = int(result2[0][i].boxes.xyxy[0][0]) |
|
list_of_items.append((cord_x, class_label)) |
|
|
|
list_of_items.sort() |
|
|
|
|
|
digits = [] |
|
for digit in list_of_items : |
|
digits.append(digit[1]) |
|
if len(digits) == 7 : digits.append('0') |
|
return digits |
|
|
|
|
|
raw_plate = ('raw_plate.png') |
|
|
|
classes_dict = { |
|
'0':'0', |
|
'1':'1', |
|
'2':'2', |
|
'3':'3', |
|
'4':'4', |
|
'5':'5', |
|
'6':'6', |
|
'7':'7', |
|
'8':'8', |
|
'9':'9', |
|
'10':'B', |
|
'11':'C', |
|
'12':'D', |
|
'13':'G', |
|
'14':'H', |
|
'15':'J', |
|
'16':'L', |
|
'17':'M', |
|
'18':'N', |
|
'19':'S', |
|
'20':'T', |
|
'21':'V', |
|
'22':'Y' |
|
} |
|
|
|
def Plot_Result(raw_plate, digits) : |
|
|
|
raw_plate = cv2.imread(raw_plate) |
|
raw_plate = cv2.cvtColor(raw_plate, cv2.COLOR_BGR2RGB) |
|
|
|
|
|
p1 = (18, 150) |
|
p2 = (143, 150) |
|
p3 = (268, 150) |
|
p4 = (393, 150) |
|
p5 = (518, 150) |
|
p6 = (643, 150) |
|
p7 = (778, 180) |
|
p8 = (878, 180) |
|
|
|
|
|
cv2.putText(raw_plate, digits[0], p1, cv2.FONT_HERSHEY_COMPLEX, 5, (0, 0, 0), 5, cv2.LINE_AA); |
|
cv2.putText(raw_plate, digits[1], p2, cv2.FONT_HERSHEY_COMPLEX, 5, (0, 0, 0), 5, cv2.LINE_AA); |
|
cv2.putText(raw_plate, digits[2], p3, cv2.FONT_HERSHEY_COMPLEX, 5, (0, 0, 0), 5, cv2.LINE_AA); |
|
cv2.putText(raw_plate, digits[3], p4, cv2.FONT_HERSHEY_COMPLEX, 5, (0, 0, 0), 5, cv2.LINE_AA); |
|
cv2.putText(raw_plate, digits[4], p5, cv2.FONT_HERSHEY_COMPLEX, 5, (0, 0, 0), 5, cv2.LINE_AA); |
|
cv2.putText(raw_plate, digits[5], p6, cv2.FONT_HERSHEY_COMPLEX, 5, (0, 0, 0), 5, cv2.LINE_AA); |
|
cv2.putText(raw_plate, digits[6], p7, cv2.FONT_HERSHEY_COMPLEX, 5, (0, 0, 0), 5, cv2.LINE_AA); |
|
cv2.putText(raw_plate, digits[7], p8, cv2.FONT_HERSHEY_COMPLEX, 5, (0, 0, 0), 5, cv2.LINE_AA); |
|
|
|
|
|
filename = 'output_image.jpg' |
|
cv2.imwrite(filename, raw_plate) |
|
|
|
out_img = cv2.imread("output_image.jpg") |
|
st.image(out_img, caption='final image β
') |
|
|
|
|
|
def FINAL(img) : |
|
''' |
|
A pipeline for all parts of phase 3. |
|
start with a car image. |
|
result is digits and char on car plate. |
|
''' |
|
|
|
|
|
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
|
|
|
|
|
result1, _ = Detect_Plate(img) |
|
|
|
|
|
pts = result1[0].boxes.xyxy.tolist()[0] |
|
|
|
|
|
img2 = img[round(pts[1]):round(pts[3]), round(pts[0]):round(pts[2])] |
|
|
|
|
|
img2 = cv2.resize(img2, (120, 70)) |
|
|
|
|
|
result2, _ = Detect_Digits(img2) |
|
|
|
|
|
digits = Sort_Digits(result2) |
|
|
|
Plot_Result(raw_plate, digits) |
|
|
|
|
|
|
|
if selected_type == "Upload Image": |
|
uploaded_file = st.file_uploader("Upload Image of car's plate π", type=["png","jpg","bmp","jpeg"]) |
|
|
|
if uploaded_file is not None: |
|
image = Image.open(uploaded_file).convert('RGB') |
|
st.image(image, width=400, caption='input image π·') |
|
|
|
image.save('input_image.jpg') |
|
|
|
img = cv2.imread('input_image.jpg') |
|
|
|
st.markdown("------") |
|
|
|
FINAL(img) |
|
|
|
|
|
|
|
|
|
else: |
|
st.warning('β Please upload your Image π―') |
|
|
|
st.markdown("<br><hr><center>Made with β€οΈ by <a href='https://omidsakaki.ir/'><strong>omid sakaki ghazvini</strong></a></center><hr>", unsafe_allow_html=True) |