Sarvamangalak commited on
Commit
df0733b
·
verified ·
1 Parent(s): 8f554fb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +100 -245
app.py CHANGED
@@ -1,289 +1,144 @@
1
  import gradio as gr
2
- import matplotlib.pyplot as plt
3
- import pandas as pd
4
- import os
5
- import random
6
- from PIL import ImageDraw
7
-
8
- # ===============================
9
- # GLOBAL VARIABLES
10
- # ===============================
11
- total_vehicles = 0
12
- ev_count = 0
13
- total_co2_saved = 0
14
-
15
- DISTANCE_KM = 10
16
- CO2_PER_KM_PETROL = 0.150
17
- CO2_SAVED_PER_EV = DISTANCE_KM * CO2_PER_KM_PETROL
18
-
19
- FEEDBACK_FILE = "feedback.csv"
20
-
21
- if not os.path.exists(FEEDBACK_FILE):
22
- df_init = pd.DataFrame(columns=["Predicted_Label", "Feedback"])
23
- df_init.to_csv(FEEDBACK_FILE, index=False)
24
-
25
- # ===============================
26
- # DUMMY CLASSIFIER (Replace with YOLO)
27
- # ===============================
28
- def classify_vehicle():
29
- return random.choice([
30
- "Car",
31
- "Bus",
32
- "Truck",
33
- "Motorcycle",
34
- "Electric Vehicle"
35
- ])
36
-
37
- # ===============================
38
- # DASHBOARD
39
- # ===============================
40
- def generate_dashboard():
41
- global total_vehicles, ev_count
42
- non_ev = total_vehicles - ev_count
43
-
44
- fig, ax = plt.subplots()
45
- ax.bar(["EV", "Non-EV"], [ev_count, non_ev])
46
- ax.set_title("Vehicle Distribution")
47
- ax.set_ylabel("Count")
48
-
49
- return fig
50
-
51
- # ===============================
52
- # DETECTION FUNCTION
53
- # ===============================
54
- def detect_image(image, threshold):
55
-
56
- global total_vehicles, ev_count, total_co2_saved
57
 
58
- if image is None:
59
- return None, "Upload image first.", \
60
- "### 🚘 Total Vehicles: 0", \
61
- "### ⚡ EV Vehicles: 0", \
62
- "### 📊 EV Adoption Rate: 0%", \
63
- "### 🌱 CO₂ Saved: 0 kg", \
64
- generate_dashboard(), ""
65
-
66
- vehicle_type = classify_vehicle()
67
- plate_number = "KA01AB1234"
68
-
69
- total_vehicles += 1
70
- co2_saved_this = 0
71
-
72
- if vehicle_type == "Electric Vehicle":
73
- ev_count += 1
74
- co2_saved_this = CO2_SAVED_PER_EV
75
- total_co2_saved += co2_saved_this
76
-
77
- ev_percent = (ev_count / total_vehicles) * 100
78
-
79
- # Draw boxes
80
- img = image.copy()
81
- draw = ImageDraw.Draw(img)
82
- w, h = img.size
83
-
84
- vehicle_box = [w*0.1, h*0.2, w*0.9, h*0.8]
85
- plate_box = [w*0.4, h*0.6, w*0.7, h*0.75]
86
-
87
- draw.rectangle(vehicle_box, outline="red", width=4)
88
- draw.text((vehicle_box[0], vehicle_box[1]-20),
89
- f"Vehicle: {vehicle_type}", fill="red")
90
-
91
- draw.rectangle(plate_box, outline="green", width=4)
92
- draw.text((plate_box[0], plate_box[1]-20),
93
- f"Plate: {plate_number}", fill="green")
94
-
95
- fig, ax = plt.subplots()
96
- ax.imshow(img)
97
- ax.axis("off")
98
- ax.set_title("Detection Result")
99
-
100
- result_text = f"""
101
- Vehicle Type: {vehicle_type}
102
- Number Plate: {plate_number}
103
- Confidence Threshold: {threshold}
104
- CO₂ Saved (This Detection): {co2_saved_this:.2f} kg
105
- """
106
-
107
- total_card = f"### 🚘 Total Vehicles: {total_vehicles}"
108
- ev_card = f"### ⚡ EV Vehicles: {ev_count}"
109
- percent_card = f"### 📊 EV Adoption Rate: {ev_percent:.2f}%"
110
- co2_card = f"### 🌱 CO₂ Saved: {total_co2_saved:.2f} kg"
111
-
112
- dashboard_fig = generate_dashboard()
113
-
114
- return (
115
- fig,
116
- result_text,
117
- total_card,
118
- ev_card,
119
- percent_card,
120
- co2_card,
121
- dashboard_fig,
122
- vehicle_type
123
- )
124
-
125
- # ===============================
126
- # FEEDBACK FUNCTIONS
127
- # ===============================
128
- def save_feedback(predicted_label, feedback):
129
- df = pd.read_csv(FEEDBACK_FILE)
130
- df = pd.concat([df, pd.DataFrame(
131
- [{"Predicted_Label": predicted_label, "Feedback": feedback}]
132
- )], ignore_index=True)
133
- df.to_csv(FEEDBACK_FILE, index=False)
134
- return "✅ Feedback Saved!"
135
-
136
- def calculate_metrics():
137
 
138
- df = pd.read_csv(FEEDBACK_FILE)
 
 
139
 
140
- if len(df) == 0:
141
- return "No feedback data available.", None
 
142
 
143
- tp = len(df[df["Feedback"] == "Correct"])
144
- fp = len(df[df["Feedback"] == "Incorrect"])
145
- total = len(df)
146
 
147
- precision = tp / (tp + fp) if (tp + fp) else 0
148
- recall = tp / total if total else 0
149
 
150
- metrics_text = f"""
151
- Total Samples: {total}
152
 
153
- True Positives: {tp}
154
- False Positives: {fp}
155
 
156
- Precision: {precision:.2f}
157
- Recall: {recall:.2f}
158
- """
159
 
160
- fig, ax = plt.subplots()
161
- matrix = [[tp, fp], [0, 0]]
162
- ax.imshow(matrix)
163
 
164
- ax.set_xticks([0,1])
165
- ax.set_yticks([0,1])
166
- ax.set_xticklabels(["Correct", "Incorrect"])
167
- ax.set_yticklabels(["Predicted"])
168
 
169
- for i in range(2):
170
- for j in range(2):
171
- ax.text(j, i, matrix[i][j], ha="center", va="center")
 
 
172
 
173
- ax.set_title("Confusion Matrix")
 
174
 
175
- return metrics_text, fig
 
 
 
 
 
 
 
176
 
177
- def reset_database():
178
- df = pd.DataFrame(columns=["Predicted_Label", "Feedback"])
179
- df.to_csv(FEEDBACK_FILE, index=False)
180
- return "🗑 Database Reset Successfully!"
181
 
182
- def download_feedback():
183
- return FEEDBACK_FILE
 
184
 
185
- # ===============================
186
- # GRADIO UI
187
- # ===============================
188
- with gr.Blocks() as demo:
189
 
190
- # ----------------------------
191
- # DETECTION TAB
192
- # ----------------------------
193
- with gr.Tab("🚦 Detection System"):
194
 
195
- gr.Markdown("## Smart Vehicle Classification & EV CO₂ Dashboard")
196
 
197
- slider = gr.Slider(0.3, 1.0, 0.5, step=0.05,
198
- label="Confidence Threshold")
199
 
200
- with gr.Row():
201
- img_input = gr.Image(type="pil", label="Upload Vehicle Image")
202
- img_output = gr.Plot(label="Detection Output")
203
 
204
- result_box = gr.Textbox(label="Detection Result", lines=6)
205
 
206
- with gr.Row():
207
- total_card = gr.Markdown("### 🚘 Total Vehicles: 0")
208
- ev_card = gr.Markdown("### ⚡ EV Vehicles: 0")
209
- percent_card = gr.Markdown("### 📊 EV Adoption Rate: 0%")
210
- co2_card = gr.Markdown("### 🌱 CO₂ Saved: 0 kg")
211
 
212
- dashboard_plot = gr.Plot(label="Analytics Dashboard")
 
213
 
214
- predicted_label_state = gr.State()
215
 
216
- detect_btn = gr.Button("🔍 Detect Vehicle")
 
217
 
218
- detect_btn.click(
219
- fn=detect_image,
220
- inputs=[img_input, slider],
221
- outputs=[
222
- img_output,
223
- result_box,
224
- total_card,
225
- ev_card,
226
- percent_card,
227
- co2_card,
228
- dashboard_plot,
229
- predicted_label_state
230
- ]
231
- )
232
 
233
- gr.Markdown("### Provide Feedback")
234
 
235
- correct_btn = gr.Button("✔ Correct")
236
- incorrect_btn = gr.Button(" Incorrect")
237
- feedback_status = gr.Textbox(label="Feedback Status")
 
238
 
239
- correct_btn.click(
240
- fn=save_feedback,
241
- inputs=[predicted_label_state, gr.State("Correct")],
242
- outputs=feedback_status
243
- )
244
 
245
- incorrect_btn.click(
246
- fn=save_feedback,
247
- inputs=[predicted_label_state, gr.State("Incorrect")],
248
- outputs=feedback_status
249
- )
 
 
250
 
251
- # ----------------------------
252
- # ADMIN DASHBOARD TAB
253
- # ----------------------------
254
- with gr.Tab("📊 Admin Dashboard"):
255
 
256
- gr.Markdown("## Model Evaluation Dashboard")
 
 
 
257
 
258
- metrics_box = gr.Textbox(label="Evaluation Metrics", lines=10)
259
- confusion_plot = gr.Plot()
260
 
261
- evaluate_btn = gr.Button("Calculate Metrics")
262
 
263
- evaluate_btn.click(
264
- fn=calculate_metrics,
265
- outputs=[metrics_box, confusion_plot]
266
- )
267
 
268
- gr.Markdown("### Download Feedback CSV")
 
 
269
 
270
- download_button = gr.Button("Download CSV")
271
- download_file = gr.File()
272
 
273
- download_button.click(
274
- fn=download_feedback,
275
- outputs=download_file
276
- )
277
 
278
- gr.Markdown("### Reset Database")
 
279
 
280
- reset_btn = gr.Button("Reset Database")
281
- reset_output = gr.Textbox()
282
 
283
- reset_btn.click(
284
- fn=reset_database,
285
- outputs=reset_output
286
- )
 
287
 
288
- # Gradio 6 theme must be passed here
289
  demo.launch(theme=gr.themes.Soft())
 
1
  import gradio as gr
2
+ import cv2
3
+ import numpy as np
4
+ import easyocr
5
+ from ultralytics import YOLO
6
+ import re
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
+ # Load models
9
+ model = YOLO("best.pt") # your trained number plate model
10
+ reader = easyocr.Reader(['en'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ ############################################################
13
+ # Image Enhancement for Night Images
14
+ ############################################################
15
 
16
+ def enhance_image(image):
17
+ lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
18
+ l, a, b = cv2.split(lab)
19
 
20
+ clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
21
+ cl = clahe.apply(l)
 
22
 
23
+ enhanced = cv2.merge((cl,a,b))
24
+ enhanced = cv2.cvtColor(enhanced, cv2.COLOR_LAB2BGR)
25
 
26
+ return enhanced
 
27
 
 
 
28
 
29
+ ############################################################
30
+ # Indian Plate Colour Classification
31
+ ############################################################
32
 
33
+ def classify_plate_color(roi):
 
 
34
 
35
+ hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
 
 
 
36
 
37
+ masks = {
38
+ "white": cv2.inRange(hsv, np.array([0,0,180]), np.array([180,60,255])),
39
+ "yellow": cv2.inRange(hsv, np.array([15,80,80]), np.array([40,255,255])),
40
+ "green": cv2.inRange(hsv, np.array([35,50,50]), np.array([85,255,255]))
41
+ }
42
 
43
+ color_counts = {color: np.sum(mask) for color, mask in masks.items()}
44
+ dominant_color = max(color_counts, key=color_counts.get)
45
 
46
+ if dominant_color == "white":
47
+ return "Private Vehicle", False
48
+ elif dominant_color == "yellow":
49
+ return "Commercial Vehicle", False
50
+ elif dominant_color == "green":
51
+ return "Electric Vehicle (EV)", True
52
+ else:
53
+ return "Unknown", False
54
 
 
 
 
 
55
 
56
+ ############################################################
57
+ # Main Detection Pipeline
58
+ ############################################################
59
 
60
+ def detect_number_plates(image):
 
 
 
61
 
62
+ if image is None:
63
+ return None, "Upload image first."
 
 
64
 
65
+ img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
66
 
67
+ # Night enhancement
68
+ img = enhance_image(img)
69
 
70
+ results = model(img)
 
 
71
 
72
+ detected_info = []
73
 
74
+ for result in results:
75
+ boxes = result.boxes.xyxy.cpu().numpy()
 
 
 
76
 
77
+ for box in boxes:
78
+ x1, y1, x2, y2 = map(int, box)
79
 
80
+ plate_roi = img[y1:y2, x1:x2]
81
 
82
+ # OCR
83
+ ocr_results = reader.readtext(plate_roi)
84
 
85
+ plate_number = "Unknown"
86
+ for res in ocr_results:
87
+ text = re.sub(r'[^A-Z0-9]', '', res[1].upper())
88
+ if len(text) >= 8:
89
+ plate_number = text
90
+ break
 
 
 
 
 
 
 
 
91
 
92
+ vehicle_type, is_ev = classify_plate_color(plate_roi)
93
 
94
+ if is_ev:
95
+ benefit = "EV Benefits: Toll & Parking Discount"
96
+ else:
97
+ benefit = "No EV Benefits"
98
 
99
+ # Draw bounding box
100
+ cv2.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2)
 
 
 
101
 
102
+ label = f"{plate_number} | {vehicle_type}"
103
+ cv2.putText(img, label,
104
+ (x1, y1-10),
105
+ cv2.FONT_HERSHEY_SIMPLEX,
106
+ 0.7,
107
+ (0,255,0),
108
+ 2)
109
 
110
+ detected_info.append(
111
+ f"Plate: {plate_number}\nType: {vehicle_type}\n{benefit}"
112
+ )
 
113
 
114
+ if len(detected_info) == 0:
115
+ summary = "No number plates detected."
116
+ else:
117
+ summary = "\n\n".join(detected_info)
118
 
119
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 
120
 
121
+ return img, summary
122
 
 
 
 
 
123
 
124
+ ############################################################
125
+ # Gradio UI
126
+ ############################################################
127
 
128
+ with gr.Blocks() as demo:
 
129
 
130
+ gr.Markdown("## 🚦 Smart Traffic CCTV Number Plate Detection System")
 
 
 
131
 
132
+ image_input = gr.Image(type="pil", label="Upload CCTV Image")
133
+ detect_btn = gr.Button("Detect Plates", size="sm")
134
 
135
+ output_image = gr.Image(label="Detection Output")
136
+ output_text = gr.Textbox(label="Detection Summary")
137
 
138
+ detect_btn.click(
139
+ fn=detect_number_plates,
140
+ inputs=image_input,
141
+ outputs=[output_image, output_text]
142
+ )
143
 
 
144
  demo.launch(theme=gr.themes.Soft())