Update app.py
Browse files
app.py
CHANGED
|
@@ -25,6 +25,7 @@ BASE_AMT = 100
|
|
| 25 |
|
| 26 |
conn = sqlite3.connect("vehicles.db", check_same_thread=False)
|
| 27 |
cursor = conn.cursor()
|
|
|
|
| 28 |
cursor.execute("""
|
| 29 |
CREATE TABLE IF NOT EXISTS vehicles (
|
| 30 |
plate TEXT,
|
|
@@ -33,9 +34,17 @@ CREATE TABLE IF NOT EXISTS vehicles (
|
|
| 33 |
time TEXT
|
| 34 |
)
|
| 35 |
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
conn.commit()
|
| 37 |
|
| 38 |
-
# -------------------- MODEL
|
| 39 |
|
| 40 |
processor = None
|
| 41 |
model = None
|
|
@@ -61,15 +70,13 @@ def get_original_image(url):
|
|
| 61 |
response = requests.get(url, stream=True)
|
| 62 |
return Image.open(response.raw).convert("RGB")
|
| 63 |
|
| 64 |
-
# --------------------
|
| 65 |
|
| 66 |
def compute_discount(vehicle_type):
|
| 67 |
if vehicle_type == "EV":
|
| 68 |
return BASE_AMT * 0.9
|
| 69 |
return BASE_AMT
|
| 70 |
|
| 71 |
-
# -------------------- PLATE COLOR CLASSIFICATION --------------------
|
| 72 |
-
|
| 73 |
def classify_plate_color(plate_img):
|
| 74 |
img = np.array(plate_img)
|
| 75 |
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
|
|
@@ -83,8 +90,6 @@ def classify_plate_color(plate_img):
|
|
| 83 |
return "Commercial"
|
| 84 |
return "Personal"
|
| 85 |
|
| 86 |
-
# -------------------- OCR --------------------
|
| 87 |
-
|
| 88 |
def read_plate(plate_img):
|
| 89 |
gray = cv2.cvtColor(np.array(plate_img), cv2.COLOR_RGB2GRAY)
|
| 90 |
gray = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)[1]
|
|
@@ -95,8 +100,6 @@ def read_plate(plate_img):
|
|
| 95 |
)
|
| 96 |
return text.strip() if text.strip() else "UNKNOWN"
|
| 97 |
|
| 98 |
-
# -------------------- YOLOS INFERENCE --------------------
|
| 99 |
-
|
| 100 |
def make_prediction(img):
|
| 101 |
processor, model = load_model()
|
| 102 |
inputs = processor(images=img, return_tensors="pt")
|
|
@@ -113,14 +116,6 @@ def make_prediction(img):
|
|
| 113 |
|
| 114 |
# -------------------- VISUALIZATION --------------------
|
| 115 |
|
| 116 |
-
def fig_to_img(fig):
|
| 117 |
-
buf = io.BytesIO()
|
| 118 |
-
fig.savefig(buf, bbox_inches="tight")
|
| 119 |
-
buf.seek(0)
|
| 120 |
-
img = Image.open(buf)
|
| 121 |
-
plt.close(fig)
|
| 122 |
-
return img
|
| 123 |
-
|
| 124 |
def visualize(img, output, id2label, threshold):
|
| 125 |
keep = output["scores"] > threshold
|
| 126 |
boxes = output["boxes"][keep]
|
|
@@ -128,7 +123,6 @@ def visualize(img, output, id2label, threshold):
|
|
| 128 |
|
| 129 |
fig, ax = plt.subplots(figsize=(8,8))
|
| 130 |
ax.imshow(img)
|
| 131 |
-
|
| 132 |
results_text = []
|
| 133 |
|
| 134 |
for box, label in zip(boxes, labels):
|
|
@@ -161,33 +155,37 @@ def visualize(img, output, id2label, threshold):
|
|
| 161 |
ax.axis("off")
|
| 162 |
|
| 163 |
if not results_text:
|
| 164 |
-
return
|
|
|
|
|
|
|
| 165 |
|
| 166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
|
| 168 |
-
|
| 169 |
|
| 170 |
-
def
|
| 171 |
-
df = pd.read_sql("SELECT * FROM
|
| 172 |
-
fig, ax = plt.subplots()
|
| 173 |
|
| 174 |
if df.empty:
|
| 175 |
-
|
| 176 |
-
ax.axis("off")
|
| 177 |
-
return fig
|
| 178 |
|
| 179 |
-
df["
|
| 180 |
-
|
| 181 |
-
return fig
|
| 182 |
|
| 183 |
-
|
|
|
|
| 184 |
|
| 185 |
-
|
| 186 |
-
if not url or not is_valid_url(url):
|
| 187 |
-
return None, "Invalid URL"
|
| 188 |
-
img = get_original_image(url)
|
| 189 |
-
output, id2label = make_prediction(img)
|
| 190 |
-
return visualize(img, output, id2label, threshold)
|
| 191 |
|
| 192 |
def detect_from_image(img, threshold):
|
| 193 |
if img is None:
|
|
@@ -198,41 +196,45 @@ def detect_from_image(img, threshold):
|
|
| 198 |
# -------------------- UI --------------------
|
| 199 |
|
| 200 |
with gr.Blocks() as demo:
|
| 201 |
-
gr.Markdown("## Smart Vehicle Classification System")
|
| 202 |
|
| 203 |
slider = gr.Slider(0.3, 1.0, 0.5, label="Confidence Threshold")
|
| 204 |
-
result_box = gr.Textbox(label="Result", lines=4)
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
gr.
|
| 236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
|
| 238 |
demo.launch()
|
|
|
|
| 25 |
|
| 26 |
conn = sqlite3.connect("vehicles.db", check_same_thread=False)
|
| 27 |
cursor = conn.cursor()
|
| 28 |
+
|
| 29 |
cursor.execute("""
|
| 30 |
CREATE TABLE IF NOT EXISTS vehicles (
|
| 31 |
plate TEXT,
|
|
|
|
| 34 |
time TEXT
|
| 35 |
)
|
| 36 |
""")
|
| 37 |
+
|
| 38 |
+
cursor.execute("""
|
| 39 |
+
CREATE TABLE IF NOT EXISTS feedback (
|
| 40 |
+
result TEXT,
|
| 41 |
+
feedback TEXT
|
| 42 |
+
)
|
| 43 |
+
""")
|
| 44 |
+
|
| 45 |
conn.commit()
|
| 46 |
|
| 47 |
+
# -------------------- MODEL --------------------
|
| 48 |
|
| 49 |
processor = None
|
| 50 |
model = None
|
|
|
|
| 70 |
response = requests.get(url, stream=True)
|
| 71 |
return Image.open(response.raw).convert("RGB")
|
| 72 |
|
| 73 |
+
# -------------------- LOGIC --------------------
|
| 74 |
|
| 75 |
def compute_discount(vehicle_type):
|
| 76 |
if vehicle_type == "EV":
|
| 77 |
return BASE_AMT * 0.9
|
| 78 |
return BASE_AMT
|
| 79 |
|
|
|
|
|
|
|
| 80 |
def classify_plate_color(plate_img):
|
| 81 |
img = np.array(plate_img)
|
| 82 |
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
|
|
|
|
| 90 |
return "Commercial"
|
| 91 |
return "Personal"
|
| 92 |
|
|
|
|
|
|
|
| 93 |
def read_plate(plate_img):
|
| 94 |
gray = cv2.cvtColor(np.array(plate_img), cv2.COLOR_RGB2GRAY)
|
| 95 |
gray = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)[1]
|
|
|
|
| 100 |
)
|
| 101 |
return text.strip() if text.strip() else "UNKNOWN"
|
| 102 |
|
|
|
|
|
|
|
| 103 |
def make_prediction(img):
|
| 104 |
processor, model = load_model()
|
| 105 |
inputs = processor(images=img, return_tensors="pt")
|
|
|
|
| 116 |
|
| 117 |
# -------------------- VISUALIZATION --------------------
|
| 118 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
def visualize(img, output, id2label, threshold):
|
| 120 |
keep = output["scores"] > threshold
|
| 121 |
boxes = output["boxes"][keep]
|
|
|
|
| 123 |
|
| 124 |
fig, ax = plt.subplots(figsize=(8,8))
|
| 125 |
ax.imshow(img)
|
|
|
|
| 126 |
results_text = []
|
| 127 |
|
| 128 |
for box, label in zip(boxes, labels):
|
|
|
|
| 155 |
ax.axis("off")
|
| 156 |
|
| 157 |
if not results_text:
|
| 158 |
+
return fig, "No plate detected"
|
| 159 |
+
|
| 160 |
+
return fig, "\n".join(results_text)
|
| 161 |
|
| 162 |
+
# -------------------- FEEDBACK --------------------
|
| 163 |
+
|
| 164 |
+
def submit_feedback(result_text, feedback_choice):
|
| 165 |
+
if not result_text:
|
| 166 |
+
return "No result to evaluate."
|
| 167 |
+
|
| 168 |
+
cursor.execute(
|
| 169 |
+
"INSERT INTO feedback VALUES (?, ?)",
|
| 170 |
+
(result_text, feedback_choice)
|
| 171 |
+
)
|
| 172 |
+
conn.commit()
|
| 173 |
|
| 174 |
+
return "Feedback recorded!"
|
| 175 |
|
| 176 |
+
def show_accuracy():
|
| 177 |
+
df = pd.read_sql("SELECT * FROM feedback", conn)
|
|
|
|
| 178 |
|
| 179 |
if df.empty:
|
| 180 |
+
return "No feedback data available."
|
|
|
|
|
|
|
| 181 |
|
| 182 |
+
correct = len(df[df["feedback"] == "Correct"])
|
| 183 |
+
total = len(df)
|
|
|
|
| 184 |
|
| 185 |
+
accuracy = (correct / total) * 100
|
| 186 |
+
return f"Model Accuracy (based on user feedback): {accuracy:.2f}%"
|
| 187 |
|
| 188 |
+
# -------------------- CALLBACKS --------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
|
| 190 |
def detect_from_image(img, threshold):
|
| 191 |
if img is None:
|
|
|
|
| 196 |
# -------------------- UI --------------------
|
| 197 |
|
| 198 |
with gr.Blocks() as demo:
|
| 199 |
+
gr.Markdown("## 🚦 Smart Vehicle Classification System")
|
| 200 |
|
| 201 |
slider = gr.Slider(0.3, 1.0, 0.5, label="Confidence Threshold")
|
| 202 |
+
result_box = gr.Textbox(label="Detection Result", lines=4)
|
| 203 |
+
|
| 204 |
+
img_input = gr.Image(type="pil")
|
| 205 |
+
img_output = gr.Plot()
|
| 206 |
+
|
| 207 |
+
detect_btn = gr.Button("Detect")
|
| 208 |
+
detect_btn.click(
|
| 209 |
+
detect_from_image,
|
| 210 |
+
inputs=[img_input, slider],
|
| 211 |
+
outputs=[img_output, result_box]
|
| 212 |
+
)
|
| 213 |
+
|
| 214 |
+
gr.Markdown("### Provide Feedback")
|
| 215 |
+
|
| 216 |
+
feedback_radio = gr.Radio(
|
| 217 |
+
["Correct", "Incorrect"],
|
| 218 |
+
label="Was the prediction correct?"
|
| 219 |
+
)
|
| 220 |
+
|
| 221 |
+
feedback_btn = gr.Button("Submit Feedback")
|
| 222 |
+
feedback_msg = gr.Textbox(label="Feedback Status")
|
| 223 |
+
|
| 224 |
+
feedback_btn.click(
|
| 225 |
+
submit_feedback,
|
| 226 |
+
inputs=[result_box, feedback_radio],
|
| 227 |
+
outputs=feedback_msg
|
| 228 |
+
)
|
| 229 |
+
|
| 230 |
+
gr.Markdown("### Model Evaluation")
|
| 231 |
+
|
| 232 |
+
accuracy_btn = gr.Button("Show Accuracy")
|
| 233 |
+
accuracy_box = gr.Textbox(label="Accuracy")
|
| 234 |
+
|
| 235 |
+
accuracy_btn.click(
|
| 236 |
+
show_accuracy,
|
| 237 |
+
outputs=accuracy_box
|
| 238 |
+
)
|
| 239 |
|
| 240 |
demo.launch()
|