harsh-dev commited on
Commit
c53edcc
·
unverified ·
1 Parent(s): dd0d71a

Add Bounding Box vs Segment Overlay output style option in Gradio UI

Browse files
Files changed (2) hide show
  1. app.py +9 -3
  2. diff_ai.py +28 -17
app.py CHANGED
@@ -18,7 +18,7 @@ from describe import describe_change
18
 
19
  import gradio as gr
20
 
21
- def gradio_compare(img1, img2):
22
  if img1 is None or img2 is None:
23
  return None, None, "Please upload both images.", {}
24
 
@@ -39,7 +39,8 @@ def gradio_compare(img1, img2):
39
  # Run comparison pipeline
40
  pipeline_used = "AI Pipeline"
41
  try:
42
- result_data = compare_images_ai(path1, path2, output_path, heatmap_path)
 
43
  except Exception as e:
44
  print(f"[Gradio] AI pipeline failed ({e}); falling back to classical")
45
  result_data = compare_images(path1, path2, output_path, heatmap_path)
@@ -109,6 +110,11 @@ with gr.Blocks() as demo:
109
  gr.Markdown("### Input Images")
110
  img1_input = gr.Image(label="Before Image", type="numpy")
111
  img2_input = gr.Image(label="After Image", type="numpy")
 
 
 
 
 
112
  submit_btn = gr.Button("Compare & Analyze", variant="primary", size="lg")
113
 
114
  with gr.Column(scale=1):
@@ -123,7 +129,7 @@ with gr.Blocks() as demo:
123
 
124
  submit_btn.click(
125
  fn=gradio_compare,
126
- inputs=[img1_input, img2_input],
127
  outputs=[result_img_output, heatmap_img_output, desc_output, metrics_output]
128
  )
129
 
 
18
 
19
  import gradio as gr
20
 
21
+ def gradio_compare(img1, img2, style_option="Segment Overlay"):
22
  if img1 is None or img2 is None:
23
  return None, None, "Please upload both images.", {}
24
 
 
39
  # Run comparison pipeline
40
  pipeline_used = "AI Pipeline"
41
  try:
42
+ draw_style = "box" if style_option == "Bounding Boxes Only" else "overlay"
43
+ result_data = compare_images_ai(path1, path2, output_path, heatmap_path, draw_style=draw_style)
44
  except Exception as e:
45
  print(f"[Gradio] AI pipeline failed ({e}); falling back to classical")
46
  result_data = compare_images(path1, path2, output_path, heatmap_path)
 
110
  gr.Markdown("### Input Images")
111
  img1_input = gr.Image(label="Before Image", type="numpy")
112
  img2_input = gr.Image(label="After Image", type="numpy")
113
+ style_input = gr.Radio(
114
+ choices=["Segment Overlay", "Bounding Boxes Only"],
115
+ value="Segment Overlay",
116
+ label="Visualization Output Style"
117
+ )
118
  submit_btn = gr.Button("Compare & Analyze", variant="primary", size="lg")
119
 
120
  with gr.Column(scale=1):
 
129
 
130
  submit_btn.click(
131
  fn=gradio_compare,
132
+ inputs=[img1_input, img2_input, style_input],
133
  outputs=[result_img_output, heatmap_img_output, desc_output, metrics_output]
134
  )
135
 
diff_ai.py CHANGED
@@ -458,7 +458,7 @@ def _composite_object(base, object_img, mask, bbox, color):
458
  # MAIN ENTRY
459
  # =====================================================================
460
 
461
- def _compare_images_ai_impl(img1_path, img2_path, output_path, heatmap_path):
462
  """End-to-end change-region-driven AI pipeline. Raises RuntimeError
463
  if any required model is unavailable."""
464
  if not _get_loftr() or not _get_sam() or not _get_dinov2():
@@ -611,18 +611,29 @@ def _compare_images_ai_impl(img1_path, img2_path, output_path, heatmap_path):
611
  n_total = n_added + n_removed + n_moved
612
  severity = "HIGH" if n_total > 0 else "NONE"
613
 
614
- # 5) Render: dark-tint background + highlight changed objects
615
- DARK_FACTOR = 0.3
616
- result_img = cv2.multiply(aligned, np.array([DARK_FACTOR] * 3, dtype=np.float64))
617
- result_img = np.clip(result_img, 0, 255).astype(np.uint8)
618
-
619
- for a in added_objects:
620
- _composite_object(result_img, aligned, a["mask"], a["bbox"], COLOR_ADDED)
621
- for r in removed_objects:
622
- _composite_object(result_img, r["source"], r["mask"], r["bbox"], COLOR_REMOVED)
623
- for m in moved_objects:
624
- _composite_object(result_img, m["from"]["source"], m["from"]["mask"], m["from"]["bbox"], COLOR_MOVED)
625
- _composite_object(result_img, aligned, m["to"]["mask"], m["to"]["bbox"], COLOR_MOVED)
 
 
 
 
 
 
 
 
 
 
 
626
 
627
  # Draw severity label in top-left
628
  label = f"{severity} +{n_added} -{n_removed} ~{n_moved}"
@@ -647,8 +658,8 @@ def _compare_images_ai_impl(img1_path, img2_path, output_path, heatmap_path):
647
 
648
  if HAS_SPACES:
649
  @spaces.GPU
650
- def compare_images_ai(img1_path, img2_path, output_path, heatmap_path):
651
- return _compare_images_ai_impl(img1_path, img2_path, output_path, heatmap_path)
652
  else:
653
- def compare_images_ai(img1_path, img2_path, output_path, heatmap_path):
654
- return _compare_images_ai_impl(img1_path, img2_path, output_path, heatmap_path)
 
458
  # MAIN ENTRY
459
  # =====================================================================
460
 
461
+ def _compare_images_ai_impl(img1_path, img2_path, output_path, heatmap_path, draw_style="overlay"):
462
  """End-to-end change-region-driven AI pipeline. Raises RuntimeError
463
  if any required model is unavailable."""
464
  if not _get_loftr() or not _get_sam() or not _get_dinov2():
 
611
  n_total = n_added + n_removed + n_moved
612
  severity = "HIGH" if n_total > 0 else "NONE"
613
 
614
+ # 5) Render output image
615
+ if draw_style == "box":
616
+ result_img = aligned.copy()
617
+ for a in added_objects:
618
+ _draw_box(result_img, a["bbox"], COLOR_ADDED, "ADDED")
619
+ for r in removed_objects:
620
+ _draw_box(result_img, r["bbox"], COLOR_REMOVED, "REMOVED")
621
+ for m in moved_objects:
622
+ _draw_box(result_img, m["from"]["bbox"], COLOR_MOVED, "MOVED")
623
+ _draw_box(result_img, m["to"]["bbox"], COLOR_MOVED, "MOVED")
624
+ else:
625
+ # Dark-tint background + highlight changed objects (overlay)
626
+ DARK_FACTOR = 0.3
627
+ result_img = cv2.multiply(aligned, np.array([DARK_FACTOR] * 3, dtype=np.float64))
628
+ result_img = np.clip(result_img, 0, 255).astype(np.uint8)
629
+
630
+ for a in added_objects:
631
+ _composite_object(result_img, aligned, a["mask"], a["bbox"], COLOR_ADDED)
632
+ for r in removed_objects:
633
+ _composite_object(result_img, r["source"], r["mask"], r["bbox"], COLOR_REMOVED)
634
+ for m in moved_objects:
635
+ _composite_object(result_img, m["from"]["source"], m["from"]["mask"], m["from"]["bbox"], COLOR_MOVED)
636
+ _composite_object(result_img, aligned, m["to"]["mask"], m["to"]["bbox"], COLOR_MOVED)
637
 
638
  # Draw severity label in top-left
639
  label = f"{severity} +{n_added} -{n_removed} ~{n_moved}"
 
658
 
659
  if HAS_SPACES:
660
  @spaces.GPU
661
+ def compare_images_ai(img1_path, img2_path, output_path, heatmap_path, draw_style="overlay"):
662
+ return _compare_images_ai_impl(img1_path, img2_path, output_path, heatmap_path, draw_style=draw_style)
663
  else:
664
+ def compare_images_ai(img1_path, img2_path, output_path, heatmap_path, draw_style="overlay"):
665
+ return _compare_images_ai_impl(img1_path, img2_path, output_path, heatmap_path, draw_style=draw_style)