File size: 5,400 Bytes
1b87398
 
 
 
 
 
 
8746ac6
1b87398
 
 
 
 
 
 
 
 
a5820f2
 
1b87398
f86993f
1b87398
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f86993f
1b87398
 
 
f86993f
280d4d5
f86993f
280d4d5
1b87398
 
 
ed40238
1b87398
 
 
ed40238
 
f86993f
1b87398
f86993f
 
1b87398
 
 
f86993f
 
 
280d4d5
1b87398
 
 
 
 
 
 
 
f86993f
 
 
 
 
 
 
 
 
 
 
1b87398
f86993f
 
 
1b87398
 
 
 
 
 
 
8746ac6
f86993f
 
1b87398
 
 
 
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
import gradio as gr
import numpy as np
import cv2
from ultralytics import YOLO
from PIL import Image
import pandas as pd

# Model labels for characters and license plates
model1Labels = {0: 'single_number_plate', 1: 'double_number_plate'}

model2Labels = {
    0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: 'A', 11: 'B', 12: 'C',
    13: 'D', 14: 'E', 15: 'F', 16: 'G', 17: 'H', 18: 'I', 19: 'J', 20: 'K', 21: 'L', 22: 'M', 23: 'N', 24: 'O',
    25: 'P', 26: 'Q', 27: 'R', 28: 'S', 29: 'T', 30: 'U', 31: 'V', 32: 'W', 33: 'X', 34: 'Y', 35: 'Z'
}

# Load models
model = YOLO("models/LP-detection.pt")
model2 = YOLO("models/Charcter-LP.pt")

# Function to process license plate and detect text
def prediction(image):
    result = model.predict(source=image, conf=0.5)
    boxes = result[0].boxes
    height = boxes.xywh
    crd = boxes.data

    n = len(crd)
    lp_number = []
    img_lp_final = None  

    for i in range(n):
        ht = int(height[i][3])
        c = int(crd[i][5])

        xmin = int(crd[i][0])
        ymin = int(crd[i][1])
        xmax = int(crd[i][2])
        ymax = int(crd[i][3])

        img_lp = image[ymin:ymax, xmin:xmax]
        img_lp_final = img_lp.copy()  # Store the cropped image for display
        cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2)

        h = np.median(ht)

        # Second Model Prediction
        result2 = model2.predict(source=img_lp, conf=0.25)
        boxes_ocr = result2[0].boxes
        data2 = boxes_ocr.data

        n2 = len(data2)
        xaxis0, xaxis11, xaxis12 = [], [], []
        label0, label11, label12 = [], [], []
        numberPlate = ""

        if c == 0:  # Single line license plate
            for i in range(n2):
                x = int(data2[i][2])
                xaxis0.append(x)
                l = int(data2[i][5])
                label0.append(l)

            # Sort characters by x-axis for single line
            sorted_labels = [label0[i] for i in np.argsort(xaxis0)]
            numberPlate = ''.join([model2Labels.get(l) for l in sorted_labels])
            lp_number.append(numberPlate)

        elif c == 1:  # Double line license plate
            for i in range(n2):
                x = int(data2[i][0])
                y = int(data2[i][3])
                l = int(data2[i][5])
                if y < (h / 2):
                    xaxis11.append(x)
                    label11.append(l)
                else:
                    xaxis12.append(x)
                    label12.append(l)

            # Sort characters by x-axis for double line (upper and lower separately)
            sorted_labels11 = [label11[i] for i in np.argsort(xaxis11)]
            sorted_labels12 = [label12[i] for i in np.argsort(xaxis12)]
            numberPlate = ''.join([model2Labels.get(l) for l in sorted_labels11 + sorted_labels12])
            lp_number.append(numberPlate)

    return lp_number, img_lp_final  

# Function to process the video
def process_video(video_file):
    # Open the video
    cap = cv2.VideoCapture(video_file)
    
    if not cap.isOpened():  # Check if video was opened successfully
        return None, "Error: Unable to open video. Please check the file format or path."

    license_plate_texts = []
    processed_frames = []

    # Read frames one by one
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break  # Exit if no frame is read

        # Perform license plate detection and character recognition
        license_plate_text, cropped_plate_img = prediction(frame)

        # Collect license plate text
        license_plate_texts.append(" ".join(license_plate_text))  # Join the list of texts into a single string
        processed_frames.append(cropped_plate_img)

    # Check if frames were processed
    if not processed_frames:
        return None, "Error: No frames processed. Check the video file or format."

    # Save detected texts to Excel
    df = pd.DataFrame(license_plate_texts, columns=["License Plate"])
    df.to_excel("detected_license_plates.xlsx", index=False)

    # Save processed video with license plates highlighted
    output_video_path = 'processed_video.mp4'
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # Codec for MP4

    # Ensure frame shape is valid
    if len(processed_frames) > 0:
        frame = processed_frames[0]
        height, width, _ = frame.shape
        out = cv2.VideoWriter(output_video_path, fourcc, 20.0, (width, height))

        for processed_frame in processed_frames:
            out.write(processed_frame)

        cap.release()
        out.release()

        return output_video_path, "detected_license_plates.xlsx"
    else:
        return None, "Error: No valid frames found."

# Gradio interface
with gr.Blocks() as demo:
    gr.Markdown("# 🚗 License Plate Recognition (Video Upload)")
    gr.Markdown("Upload a video to get the license number of vehicles detected in each frame.")

    with gr.Row():
        video_input = gr.Video(label="Upload Video")  # Corrected: no type argument needed
        video_output = gr.Video(label="Processed Video")  # Output the processed video
        excel_output = gr.File(label="Excel File with Detected License Plates")  # Output the Excel file with detected text

    video_input.upload(process_video, inputs=video_input, outputs=[video_output, excel_output])

    demo.launch()