Sarvamangalak commited on
Commit
edc41c1
·
verified ·
1 Parent(s): bbd9259

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +134 -241
app.py CHANGED
@@ -1,289 +1,182 @@
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 passed here
289
  demo.launch(theme=gr.themes.Soft())
 
1
  import gradio as gr
2
+ import cv2
3
+ import numpy as np
4
  import os
5
+ import pandas as pd
6
+ from datetime import datetime
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
+ # Store evaluation data
9
+ feedback_data = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ ##############################################
12
+ # Utility: Detect plate color and vehicle type
13
+ ##############################################
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ def classify_vehicle_by_plate_color(roi):
 
 
 
 
 
 
 
 
 
16
 
17
+ hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
18
 
19
+ # Masks for colors
20
+ masks = {}
21
 
22
+ # White
23
+ masks["white"] = cv2.inRange(hsv, np.array([0, 0, 180]), np.array([180, 60, 255]))
24
 
25
+ # Yellow
26
+ masks["yellow"] = cv2.inRange(hsv, np.array([15, 80, 80]), np.array([40, 255, 255]))
 
27
 
28
+ # Green
29
+ masks["green"] = cv2.inRange(hsv, np.array([35, 50, 50]), np.array([85, 255, 255]))
30
 
31
+ # Red
32
+ masks["red1"] = cv2.inRange(hsv, np.array([0, 70, 50]), np.array([10, 255, 255]))
33
+ masks["red2"] = cv2.inRange(hsv, np.array([170, 70, 50]), np.array([180, 255, 255]))
34
+ masks["red"] = masks["red1"] + masks["red2"]
35
 
36
+ # Blue
37
+ masks["blue"] = cv2.inRange(hsv, np.array([90, 50, 50]), np.array([130, 255, 255]))
38
 
39
+ # Count pixels
40
+ color_counts = {color: np.sum(mask) for color, mask in masks.items()}
 
41
 
42
+ dominant_color = max(color_counts, key=color_counts.get)
 
 
43
 
44
+ # Classification logic
45
+ if dominant_color == "white":
46
+ return "Private Vehicle"
47
+ elif dominant_color == "yellow":
48
+ return "Commercial Vehicle"
49
+ elif dominant_color == "green":
50
+ return "Electric Vehicle (EV)"
51
+ elif dominant_color == "red":
52
+ return "Temporary Registration Vehicle"
53
+ elif dominant_color == "blue":
54
+ return "Diplomatic Vehicle"
55
+ else:
56
+ return "Unknown Vehicle Type"
57
 
58
+ ##############################################
59
+ # Main Detection Function
60
+ ##############################################
61
 
62
+ def detect_vehicles(image):
63
 
64
+ if image is None:
65
+ return None, "No image uploaded."
66
 
67
+ img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
68
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
 
69
 
70
+ # Simple plate-like contour detection
71
+ edges = cv2.Canny(gray, 100, 200)
72
+ contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
73
 
74
+ detected_info = []
75
+ count = 0
76
+
77
+ for cnt in contours:
78
+ x, y, w, h = cv2.boundingRect(cnt)
79
+
80
+ # Plate aspect ratio filter
81
+ if 2 < w / h < 6 and w > 100:
82
+ plate_roi = img[y:y+h, x:x+w]
83
+ vehicle_type = classify_vehicle_by_plate_color(plate_roi)
84
 
85
+ cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
86
+ cv2.putText(img, vehicle_type,
87
+ (x, y-10),
88
+ cv2.FONT_HERSHEY_SIMPLEX,
89
+ 0.6,
90
+ (0, 255, 0),
91
+ 2)
92
 
93
+ detected_info.append(vehicle_type)
94
+ count += 1
95
 
96
+ if count == 0:
97
+ summary = "No vehicles detected."
98
+ else:
99
+ summary = f"{count} Vehicle(s) Detected: " + ", ".join(detected_info)
100
 
101
+ img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 
 
102
 
103
+ return img, summary
104
 
 
 
 
 
 
105
 
106
+ ##############################################
107
+ # Feedback System
108
+ ##############################################
109
 
110
+ def submit_feedback(is_correct):
111
+ global feedback_data
112
 
113
+ feedback_data.append({
114
+ "timestamp": datetime.now(),
115
+ "correct": is_correct
116
+ })
117
 
118
+ return generate_summary()
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
 
120
 
121
+ def generate_summary():
122
+ total = len(feedback_data)
123
+ if total == 0:
124
+ return "No evaluations yet."
125
 
126
+ correct = sum(1 for f in feedback_data if f["correct"])
127
+ accuracy = (correct / total) * 100
 
 
 
128
 
129
+ return f"""
130
+ 📊 Evaluation Summary
131
+ Total Samples: {total}
132
+ Correct: {correct}
133
+ Accuracy: {accuracy:.2f}%
134
+ """
135
+
136
+
137
+ ##############################################
138
+ # Gradio UI
139
+ ##############################################
140
+
141
+ with gr.Blocks() as demo:
142
 
143
+ gr.Markdown("## Smart Traffic Vehicle Classification System")
 
 
 
144
 
145
+ with gr.Row():
146
 
147
+ with gr.Column(scale=2):
 
148
 
149
+ image_input = gr.Image(type="pil", label="Upload Vehicle Image")
150
 
151
+ detect_btn = gr.Button("Detect", size="sm")
 
 
 
152
 
153
+ output_image = gr.Image(label="Output Image")
154
+ output_text = gr.Textbox(label="Detection Summary")
155
 
156
+ with gr.Column(scale=1):
 
157
 
158
+ gr.Markdown("### Feedback")
 
 
 
159
 
160
+ correct_btn = gr.Button("Correct", size="sm")
161
+ incorrect_btn = gr.Button("Incorrect", size="sm")
162
 
163
+ summary_box = gr.Textbox(label="Evaluation Summary")
 
164
 
165
+ # Button actions
166
+ detect_btn.click(
167
+ fn=detect_vehicles,
168
+ inputs=image_input,
169
+ outputs=[output_image, output_text]
170
+ )
171
+
172
+ correct_btn.click(
173
+ fn=lambda: submit_feedback(True),
174
+ outputs=summary_box
175
+ )
176
+
177
+ incorrect_btn.click(
178
+ fn=lambda: submit_feedback(False),
179
+ outputs=summary_box
180
+ )
181
 
 
182
  demo.launch(theme=gr.themes.Soft())