Ayesha-Majeed commited on
Commit
a9389ab
Β·
verified Β·
1 Parent(s): de92524

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -63
app.py CHANGED
@@ -4,42 +4,17 @@ import cv2
4
  import time
5
  import torch
6
  import warnings
7
- import glob
8
- import os
9
- import zipfile
10
- import shutil
11
  from PIL import Image
12
 
13
  warnings.filterwarnings("ignore")
14
 
15
- # ─── ZIP Extraction on Startup ────────────────────────────────────────────────
16
- # This runs ONCE when the app starts, extracts test.zip into clean folders.
17
- def extract_zip_if_needed(zip_name, extract_to):
18
- if os.path.exists(zip_name) and not os.path.exists(extract_to):
19
- print(f"Extracting {zip_name} -> {extract_to} ...")
20
- with zipfile.ZipFile(zip_name, 'r') as zf:
21
- zf.extractall(extract_to)
22
- print("Extraction done!")
23
-
24
- extract_zip_if_needed("test.zip", "test_images")
25
- extract_zip_if_needed("cars.zip", "car_images")
26
-
27
- def get_images_from_folder(folder, limit=10):
28
- """Recursively finds all jpg/png files inside a folder."""
29
- found = []
30
- for ext in ["*.jpg", "*.jpeg", "*.png", "*.JPG", "*.JPEG", "*.PNG"]:
31
- found += glob.glob(os.path.join(folder, "**", ext), recursive=True)
32
- found = sorted(found)[:limit]
33
- if not found:
34
- return [["car.jpeg"]]
35
- return [[f] for f in found]
36
-
37
- # ─── Global Settings ──────────────────────────────────────────────────────────
38
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
39
- CONF = 0.45
40
 
41
  # ─── Helpers ──────────────────────────────────────────────────────────────────
42
  def apply_mask_overlay(img_rgb, mask_bool, color=(0, 220, 100), alpha=0.45):
 
43
  overlay = img_rgb.copy()
44
  overlay[mask_bool] = color
45
  return cv2.addWeighted(overlay, alpha, img_rgb, 1 - alpha, 0)
@@ -48,13 +23,16 @@ def draw_boxes(img_rgb, boxes, labels, color=(0, 220, 100)):
48
  out = img_rgb.copy()
49
  for box, label in zip(boxes, labels):
50
  x1, y1, x2, y2 = map(int, box)
 
51
  cv2.rectangle(out, (x1, y1), (x2, y2), color, 1)
 
52
  cv2.putText(out, label, (x1, max(y1-5, 10)),
53
  cv2.FONT_HERSHEY_SIMPLEX, 0.4, color, 1)
54
  return out
55
 
56
  # ─── Model Functions ──────────────────────────────────────────────────────────
57
  def run_yolo_generic(img_rgb, model_path, target_classes, color):
 
58
  from ultralytics import YOLO
59
  t0 = time.time()
60
  model = YOLO(model_path)
@@ -90,10 +68,11 @@ def run_yolo_generic(img_rgb, model_path, target_classes, color):
90
  def run_sam_generic(img_rgb, yolo_model_path, target_classes, color):
91
  try:
92
  from segment_anything import sam_model_registry, SamPredictor
93
- import urllib.request
94
 
95
  CKPT = "sam_vit_b_01ec64.pth"
96
  URL = "https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth"
 
97
  if not os.path.exists(CKPT):
98
  urllib.request.urlretrieve(URL, CKPT)
99
 
@@ -104,8 +83,8 @@ def run_sam_generic(img_rgb, yolo_model_path, target_classes, color):
104
  predictor.set_image(img_rgb)
105
 
106
  from ultralytics import YOLO as _YOLO
107
- yolo = _YOLO(yolo_model_path)
108
- yolo_res = yolo(img_rgb, conf=CONF, verbose=False)[0]
109
 
110
  h, w = img_rgb.shape[:2]
111
  combined_mask = np.zeros((h, w), dtype=bool)
@@ -120,7 +99,10 @@ def run_sam_generic(img_rgb, yolo_model_path, target_classes, color):
120
  if int(cls) not in target_classes:
121
  continue
122
  box_np = box.cpu().numpy()
123
- masks_sam, _, _ = predictor.predict(box=box_np, multimask_output=False)
 
 
 
124
  combined_mask |= masks_sam[0]
125
  boxes_list.append(box_np.tolist())
126
  class_name = "mirror" if 0 in target_classes or 1 in target_classes else "car"
@@ -140,7 +122,9 @@ def run_sam_generic(img_rgb, yolo_model_path, target_classes, color):
140
  return placeholder, "Error: segment-anything not installed"
141
 
142
  def run_maskrcnn(img_rgb):
 
143
  import torchvision
 
144
  from torchvision.models.detection import maskrcnn_resnet50_fpn, MaskRCNN_ResNet50_FPN_Weights
145
  t0 = time.time()
146
 
@@ -159,6 +143,7 @@ def run_maskrcnn(img_rgb):
159
  h, w = img_rgb.shape[:2]
160
  combined_mask = np.zeros((h, w), dtype=bool)
161
  boxes, labels = [], []
 
162
  COCO_LABELS = weights.meta["categories"]
163
 
164
  for mask, box, label, score in zip(
@@ -199,10 +184,13 @@ def run_segformer(img_rgb):
199
  logits = model(**inputs).logits
200
 
201
  h, w = img_rgb.shape[:2]
202
- upsampled = F.interpolate(logits, size=(h, w), mode="bilinear", align_corners=False)
 
 
203
  seg_map = upsampled.argmax(dim=1)[0].cpu().numpy()
204
  car_mask = seg_map == CAR_IDX
205
- elapsed = time.time() - t0
 
206
 
207
  out = apply_mask_overlay(img_rgb, car_mask, color=(255, 180, 50))
208
  contours, _ = cv2.findContours(
@@ -212,43 +200,52 @@ def run_segformer(img_rgb):
212
  n = len(contours)
213
  return out, f"Car regions: {n} | Inference Time: {elapsed:.2f}s"
214
 
215
- # ─── Gradio Process Function ───────────────────────────────────────────────────
216
  def process_image(img_rgb, model_name):
217
  if img_rgb is None:
218
  return None, "Please upload an image."
 
219
  try:
220
  if model_name == "YOLOv8x-seg (Custom Mirror)":
221
  return run_yolo_generic(img_rgb, "best.pt", target_classes=[0, 1], color=(50, 220, 100))
 
222
  elif model_name == "YOLOv8x (Pretrained Car)":
223
  return run_yolo_generic(img_rgb, "yolov8x-seg.pt", target_classes=[2], color=(0, 200, 255))
 
224
  elif model_name == "SAM + YOLO (Custom Mirror)":
225
  return run_sam_generic(img_rgb, "best.pt", target_classes=[0, 1], color=(255, 80, 160))
 
226
  elif model_name == "SAM + YOLO (Pretrained Car)":
227
  return run_sam_generic(img_rgb, "yolov8x-seg.pt", target_classes=[2], color=(200, 80, 255))
 
228
  elif model_name == "Mask R-CNN (Pretrained Car)":
229
  return run_maskrcnn(img_rgb)
 
230
  elif model_name == "SegFormer (Pretrained Car)":
231
  return run_segformer(img_rgb)
 
232
  else:
233
  return img_rgb, "Model not recognized."
234
  except Exception as e:
235
  return img_rgb, f"Error: {str(e)}"
236
 
237
- # ─── Build Example Lists (from extracted zip folders) ─────────────────────────
238
- car_examples = get_images_from_folder("car_images")
239
- mirror_examples = get_images_from_folder("test_images")
240
-
241
- # ─── Gradio UI ────────────────────────────────────────────────────────────────
242
- theme = gr.themes.Soft(primary_hue="blue", secondary_hue="indigo")
243
-
244
- with gr.Blocks(theme=theme, title="Car vs Mirror Segmentation") as demo:
245
- gr.Markdown("""
246
- # πŸš— Car vs Mirror Segmentation Comparison
247
- Compare your custom trained **Car Mirror** models against pretrained **Full Car** models.
248
- """)
249
-
250
- # ── TAB 1: Full Car (Pretrained) ──────────────────────────────────────────
251
- with gr.Tab("🚘 Test Full Cars (Pretrained Models)"):
 
 
252
  with gr.Row():
253
  with gr.Column(scale=1):
254
  input_image_car = gr.Image(type="numpy", label="Upload Car Image")
@@ -263,20 +260,27 @@ with gr.Blocks(theme=theme, title="Car vs Mirror Segmentation") as demo:
263
  label="Select Pretrained Model",
264
  info="These models are pretrained from the internet to detect full cars."
265
  )
266
- submit_btn_car = gr.Button("πŸš€ Run Segmentation", variant="primary", size="lg")
267
-
268
  with gr.Column(scale=1):
269
  output_image_car = gr.Image(label="Segmentation Result", interactive=False)
270
  output_stats_car = gr.Textbox(label="Detection Statistics", interactive=False)
271
-
 
 
 
 
 
 
 
272
  gr.Examples(
273
- examples=car_examples,
274
  inputs=[input_image_car],
275
  examples_per_page=10,
276
  outputs=[output_image_car, output_stats_car],
277
  fn=process_image,
278
  cache_examples=False,
279
- label="πŸ“Έ Click any car image to load it"
280
  )
281
 
282
  submit_btn_car.click(
@@ -285,8 +289,10 @@ with gr.Blocks(theme=theme, title="Car vs Mirror Segmentation") as demo:
285
  outputs=[output_image_car, output_stats_car]
286
  )
287
 
288
- # ── TAB 2: Car Mirrors (Custom) ───────────────────────────────────────────
289
- with gr.Tab("πŸͺž Test Car Mirrors (Custom Models)"):
 
 
290
  with gr.Row():
291
  with gr.Column(scale=1):
292
  input_image_mirror = gr.Image(type="numpy", label="Upload Mirror Image")
@@ -299,22 +305,27 @@ with gr.Blocks(theme=theme, title="Car vs Mirror Segmentation") as demo:
299
  label="Select Custom Model",
300
  info="These models are specifically trained to detect car mirrors."
301
  )
302
- submit_btn_mirror = gr.Button("πŸš€ Run Segmentation", variant="primary", size="lg")
303
-
304
  with gr.Column(scale=1):
305
  output_image_mirror = gr.Image(label="Segmentation Result", interactive=False)
306
  output_stats_mirror = gr.Textbox(label="Detection Statistics", interactive=False)
307
-
 
 
 
 
 
308
  gr.Examples(
309
- examples=mirror_examples,
310
  inputs=[input_image_mirror],
311
  examples_per_page=10,
312
  outputs=[output_image_mirror, output_stats_mirror],
313
  fn=process_image,
314
  cache_examples=False,
315
- label="πŸ“Έ Click any mirror image to load it"
316
  )
317
-
318
  submit_btn_mirror.click(
319
  fn=process_image,
320
  inputs=[input_image_mirror, model_dropdown_mirror],
 
4
  import time
5
  import torch
6
  import warnings
 
 
 
 
7
  from PIL import Image
8
 
9
  warnings.filterwarnings("ignore")
10
 
11
+ # Global Settings
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
13
+ CONF = 0.45
14
 
15
  # ─── Helpers ──────────────────────────────────────────────────────────────────
16
  def apply_mask_overlay(img_rgb, mask_bool, color=(0, 220, 100), alpha=0.45):
17
+ """Blends binary mask with image as a colored overlay."""
18
  overlay = img_rgb.copy()
19
  overlay[mask_bool] = color
20
  return cv2.addWeighted(overlay, alpha, img_rgb, 1 - alpha, 0)
 
23
  out = img_rgb.copy()
24
  for box, label in zip(boxes, labels):
25
  x1, y1, x2, y2 = map(int, box)
26
+ # Bounding box ki thickness 2 se 1 kar di
27
  cv2.rectangle(out, (x1, y1), (x2, y2), color, 1)
28
+ # Font size 0.6 se 0.4 aur thickness 1 kar di taa ke small cars clear nazar aayein
29
  cv2.putText(out, label, (x1, max(y1-5, 10)),
30
  cv2.FONT_HERSHEY_SIMPLEX, 0.4, color, 1)
31
  return out
32
 
33
  # ─── Model Functions ──────────────────────────────────────────────────────────
34
  def run_yolo_generic(img_rgb, model_path, target_classes, color):
35
+ # pyrefly: ignore [missing-import]
36
  from ultralytics import YOLO
37
  t0 = time.time()
38
  model = YOLO(model_path)
 
68
  def run_sam_generic(img_rgb, yolo_model_path, target_classes, color):
69
  try:
70
  from segment_anything import sam_model_registry, SamPredictor
71
+ import urllib.request, os
72
 
73
  CKPT = "sam_vit_b_01ec64.pth"
74
  URL = "https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth"
75
+
76
  if not os.path.exists(CKPT):
77
  urllib.request.urlretrieve(URL, CKPT)
78
 
 
83
  predictor.set_image(img_rgb)
84
 
85
  from ultralytics import YOLO as _YOLO
86
+ yolo = _YOLO(yolo_model_path)
87
+ yolo_res = yolo(img_rgb, conf=CONF, verbose=False)[0]
88
 
89
  h, w = img_rgb.shape[:2]
90
  combined_mask = np.zeros((h, w), dtype=bool)
 
99
  if int(cls) not in target_classes:
100
  continue
101
  box_np = box.cpu().numpy()
102
+ masks_sam, _, _ = predictor.predict(
103
+ box=box_np,
104
+ multimask_output=False
105
+ )
106
  combined_mask |= masks_sam[0]
107
  boxes_list.append(box_np.tolist())
108
  class_name = "mirror" if 0 in target_classes or 1 in target_classes else "car"
 
122
  return placeholder, "Error: segment-anything not installed"
123
 
124
  def run_maskrcnn(img_rgb):
125
+ # pyrefly: ignore [missing-import]
126
  import torchvision
127
+ # pyrefly: ignore [missing-import]
128
  from torchvision.models.detection import maskrcnn_resnet50_fpn, MaskRCNN_ResNet50_FPN_Weights
129
  t0 = time.time()
130
 
 
143
  h, w = img_rgb.shape[:2]
144
  combined_mask = np.zeros((h, w), dtype=bool)
145
  boxes, labels = [], []
146
+
147
  COCO_LABELS = weights.meta["categories"]
148
 
149
  for mask, box, label, score in zip(
 
184
  logits = model(**inputs).logits
185
 
186
  h, w = img_rgb.shape[:2]
187
+ upsampled = F.interpolate(
188
+ logits, size=(h, w), mode="bilinear", align_corners=False
189
+ )
190
  seg_map = upsampled.argmax(dim=1)[0].cpu().numpy()
191
  car_mask = seg_map == CAR_IDX
192
+
193
+ elapsed = time.time() - t0
194
 
195
  out = apply_mask_overlay(img_rgb, car_mask, color=(255, 180, 50))
196
  contours, _ = cv2.findContours(
 
200
  n = len(contours)
201
  return out, f"Car regions: {n} | Inference Time: {elapsed:.2f}s"
202
 
203
+ # ─── Gradio Interface ─────────────────────────────────────────────────────────
204
  def process_image(img_rgb, model_name):
205
  if img_rgb is None:
206
  return None, "Please upload an image."
207
+
208
  try:
209
  if model_name == "YOLOv8x-seg (Custom Mirror)":
210
  return run_yolo_generic(img_rgb, "best.pt", target_classes=[0, 1], color=(50, 220, 100))
211
+
212
  elif model_name == "YOLOv8x (Pretrained Car)":
213
  return run_yolo_generic(img_rgb, "yolov8x-seg.pt", target_classes=[2], color=(0, 200, 255))
214
+
215
  elif model_name == "SAM + YOLO (Custom Mirror)":
216
  return run_sam_generic(img_rgb, "best.pt", target_classes=[0, 1], color=(255, 80, 160))
217
+
218
  elif model_name == "SAM + YOLO (Pretrained Car)":
219
  return run_sam_generic(img_rgb, "yolov8x-seg.pt", target_classes=[2], color=(200, 80, 255))
220
+
221
  elif model_name == "Mask R-CNN (Pretrained Car)":
222
  return run_maskrcnn(img_rgb)
223
+
224
  elif model_name == "SegFormer (Pretrained Car)":
225
  return run_segformer(img_rgb)
226
+
227
  else:
228
  return img_rgb, "Model not recognized."
229
  except Exception as e:
230
  return img_rgb, f"Error: {str(e)}"
231
 
232
+ # Define the UI theme and layout
233
+ theme = gr.themes.Soft(
234
+ primary_hue="blue",
235
+ secondary_hue="indigo",
236
+ )
237
+
238
+ with gr.Blocks(theme=theme, title="Car and Mirror Segmentation") as demo:
239
+ gr.Markdown(
240
+ """
241
+ # Car and Mirror Segmentation
242
+ """
243
+ )
244
+
245
+ # ==========================================
246
+ # TAB 1: PRETRAINED FULL CAR MODELS
247
+ # ==========================================
248
+ with gr.Tab(" Test Full Cars (Pretrained Models)"):
249
  with gr.Row():
250
  with gr.Column(scale=1):
251
  input_image_car = gr.Image(type="numpy", label="Upload Car Image")
 
260
  label="Select Pretrained Model",
261
  info="These models are pretrained from the internet to detect full cars."
262
  )
263
+ submit_btn_car = gr.Button("Run Segmentation", variant="primary", size="lg")
264
+
265
  with gr.Column(scale=1):
266
  output_image_car = gr.Image(label="Segmentation Result", interactive=False)
267
  output_stats_car = gr.Textbox(label="Detection Statistics", interactive=False)
268
+
269
+ import glob
270
+ import os
271
+ car_imgs = [f for f in glob.glob("car Images/*") if os.path.isfile(f)]
272
+ car_list = [[img] for img in car_imgs[:10]] # Pass only images to show thumbnails
273
+ if not car_list:
274
+ car_list = [["car.jpeg"]]
275
+
276
  gr.Examples(
277
+ examples=car_list,
278
  inputs=[input_image_car],
279
  examples_per_page=10,
280
  outputs=[output_image_car, output_stats_car],
281
  fn=process_image,
282
  cache_examples=False,
283
+ label="Click any image below to test (Side by side)"
284
  )
285
 
286
  submit_btn_car.click(
 
289
  outputs=[output_image_car, output_stats_car]
290
  )
291
 
292
+ # ==========================================
293
+ # TAB 2: CUSTOM MIRROR MODELS
294
+ # ==========================================
295
+ with gr.Tab(" Test Car Mirrors (Custom Models)"):
296
  with gr.Row():
297
  with gr.Column(scale=1):
298
  input_image_mirror = gr.Image(type="numpy", label="Upload Mirror Image")
 
305
  label="Select Custom Model",
306
  info="These models are specifically trained to detect car mirrors."
307
  )
308
+ submit_btn_mirror = gr.Button("Run Segmentation", variant="primary", size="lg")
309
+
310
  with gr.Column(scale=1):
311
  output_image_mirror = gr.Image(label="Segmentation Result", interactive=False)
312
  output_stats_mirror = gr.Textbox(label="Detection Statistics", interactive=False)
313
+
314
+ mirror_imgs = [f for f in glob.glob("test car windows/*") if os.path.isfile(f)]
315
+ mirror_list = [[img] for img in mirror_imgs[:10]] # Pass only images to show thumbnails
316
+ if not mirror_list:
317
+ mirror_list = [["car.jpeg"]]
318
+
319
  gr.Examples(
320
+ examples=mirror_list,
321
  inputs=[input_image_mirror],
322
  examples_per_page=10,
323
  outputs=[output_image_mirror, output_stats_mirror],
324
  fn=process_image,
325
  cache_examples=False,
326
+ label="Click any image below to test (Side by side)"
327
  )
328
+
329
  submit_btn_mirror.click(
330
  fn=process_image,
331
  inputs=[input_image_mirror, model_dropdown_mirror],