lolout1 commited on
Commit
ab906d7
·
1 Parent(s): 09cb59a

Updated UI to resize according to model preferred dimensions (640x640

Browse files
Files changed (1) hide show
  1. gradio_test.py +155 -123
gradio_test.py CHANGED
@@ -52,35 +52,54 @@ ONEFORMER_CONFIG = {
52
  "swin_cfg": "configs/ade20k/oneformer_swin_large_IN21k_384_bs16_160k.yaml",
53
  "swin_model": "shi-labs/oneformer_ade20k_swin_large",
54
  "swin_file": "250_16_swin_l_oneformer_ade20k_160k.pth",
55
- "width": 640
 
56
  }
57
  }
58
 
59
  BLACKSPOT_MODEL_REPO = "sww35/neuronest-blackspot"
60
  BLACKSPOT_MODEL_FILE = "model_0004999.pth"
61
 
62
- MAX_DISPLAY_SIZE = 1280
63
- MIN_DISPLAY_SIZE = 800
64
 
65
  from universal_contrast_analyzer import UniversalContrastAnalyzer
66
 
67
- def resize_for_display(image: np.ndarray, max_size: int = MAX_DISPLAY_SIZE, min_size: int = MIN_DISPLAY_SIZE) -> np.ndarray:
68
  h, w = image.shape[:2]
69
- if max(h, w) < min_size:
70
- scale = min_size / max(h, w)
71
- elif max(h, w) > max_size:
72
  scale = max_size / max(h, w)
73
- else:
74
- return image
75
  new_w = int(w * scale)
76
  new_h = int(h * scale)
77
- return cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_LINEAR)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  class OneFormerManager:
80
  def __init__(self):
81
  self.predictor = None
82
  self.metadata = None
83
  self.initialized = False
 
 
84
 
85
  def initialize(self, backbone: str = "swin"):
86
  if not ONEFORMER_AVAILABLE:
@@ -113,31 +132,25 @@ class OneFormerManager:
113
  logger.error(f"Failed to initialize OneFormer: {e}")
114
  return False
115
 
116
- def semantic_segmentation(self, image: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
117
  if not self.initialized:
118
  raise RuntimeError("OneFormer not initialized")
119
- original_h, original_w = image.shape[:2]
120
- width = ONEFORMER_CONFIG["ADE20K"]["width"]
121
- scale = width / original_w
122
- new_h = int(original_h * scale)
123
- image_resized = cv2.resize(image, (width, new_h), interpolation=cv2.INTER_LINEAR)
124
- predictions = self.predictor(image_resized, "semantic")
125
- seg_mask = predictions["sem_seg"].argmax(dim=0).cpu().numpy()
126
- seg_mask_original = cv2.resize(
127
- seg_mask.astype(np.uint8),
128
- (original_w, original_h),
129
- interpolation=cv2.INTER_NEAREST
130
- )
131
  visualizer = Visualizer(
132
  image[:, :, ::-1],
133
  metadata=self.metadata,
134
  instance_mode=ColorMode.IMAGE,
135
- scale=1.2
136
  )
137
- vis_output = visualizer.draw_sem_seg(seg_mask_original, alpha=0.5)
138
  vis_image = vis_output.get_image()[:, :, ::-1]
139
- vis_image_display = resize_for_display(vis_image)
140
- return seg_mask_original, vis_image_display, image
141
 
142
  def extract_floor_areas(self, segmentation: np.ndarray) -> np.ndarray:
143
  floor_mask = np.zeros_like(segmentation, dtype=bool)
@@ -275,7 +288,7 @@ class ImprovedBlackspotDetector:
275
  for mask in filtered_blackspot_masks:
276
  combined_blackspot |= mask
277
  visualization = self.create_visualization(image, floor_mask, combined_blackspot)
278
- visualization_display = resize_for_display(visualization)
279
  floor_area = int(np.sum(floor_mask))
280
  blackspot_area = int(np.sum(combined_blackspot))
281
  coverage_percentage = (blackspot_area / floor_area * 100) if floor_area > 0 else 0
@@ -304,12 +317,12 @@ class ImprovedBlackspotDetector:
304
  blackspot_contours, _ = cv2.findContours(
305
  blackspot_mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
306
  )
307
- cv2.drawContours(vis, blackspot_contours, -1, (255, 255, 0), 3)
308
  return vis
309
 
310
  def _empty_results(self, image: np.ndarray) -> Dict:
311
  empty_mask = np.zeros(image.shape[:2], dtype=bool)
312
- visualization_display = resize_for_display(image)
313
  return {
314
  'visualization': visualization_display,
315
  'floor_mask': empty_mask,
@@ -351,7 +364,7 @@ class NeuroNestApp:
351
  if not self.initialized:
352
  return {"error": "Application not properly initialized"}
353
  try:
354
- image = cv2.imread(image_path)
355
  if image is None:
356
  return {"error": "Could not load image"}
357
  image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
@@ -364,7 +377,7 @@ class NeuroNestApp:
364
  'statistics': {}
365
  }
366
  logger.info("Running semantic segmentation...")
367
- seg_mask, seg_visualization, original_sized_image = self.oneformer.semantic_segmentation(image_rgb)
368
  results['segmentation'] = {
369
  'visualization': seg_visualization,
370
  'mask': seg_mask
@@ -387,7 +400,7 @@ class NeuroNestApp:
387
  contrast_results = self.contrast_analyzer.analyze_contrast(
388
  image_rgb, seg_mask
389
  )
390
- contrast_viz_display = resize_for_display(contrast_results['visualization'])
391
  contrast_results['visualization'] = contrast_viz_display
392
  results['contrast'] = contrast_results
393
  logger.info("Contrast analysis completed")
@@ -535,105 +548,124 @@ def create_gradio_interface():
535
  - **Floor-Only Blackspot Detection**: Locates dangerous dark areas on walking surfaces
536
  - **Universal Contrast Analysis**: Evaluates visibility between ALL adjacent objects
537
 
538
- *Following WCAG 2.1 guidelines for visual accessibility*
539
  """
540
  with gr.Blocks(css="""
541
- .image-container img {
542
- max-width: 100%;
543
- height: auto;
544
- object-fit: contain;
 
 
 
 
 
 
545
  }
546
- """) as interface:
547
- gr.Markdown(f"# {title}")
548
- gr.Markdown(description)
549
- if not blackspot_ok:
550
- gr.Markdown("""
551
- ⚠️ **Note:** Blackspot detection model not available.
552
- To enable blackspot detection, upload the model to HuggingFace or ensure it's in the local directory.
553
- """)
554
- with gr.Row():
555
- enable_blackspot = gr.Checkbox(
556
- value=blackspot_ok,
557
- label="Enable Floor Blackspot Detection",
558
- interactive=blackspot_ok
559
- )
560
- blackspot_threshold = gr.Slider(
561
- minimum=0.1,
562
- maximum=0.9,
563
- value=0.5,
564
- step=0.05,
565
- label="Blackspot Sensitivity",
566
- visible=blackspot_ok
567
- )
568
- enable_contrast = gr.Checkbox(
569
- value=True,
570
- label="Enable Universal Contrast Analysis"
571
- )
572
- contrast_threshold = gr.Slider(
573
- minimum=3.0,
574
- maximum=7.0,
575
- value=4.5,
576
- step=0.1,
577
- label="WCAG Contrast Threshold"
578
- )
579
- with gr.Row():
580
- with gr.Column(scale=1):
581
- image_input = gr.Image(
582
- label="📸 Upload Room Image",
583
- type="filepath",
584
- height=400
585
- )
586
- with gr.Column(scale=1):
587
- analyze_button = gr.Button(
588
- "🔍 Analyze Environment",
589
- variant="primary",
590
- size="lg"
591
- )
592
- with gr.Row(elem_classes="image-container"):
 
 
 
 
 
 
 
 
593
  seg_display = gr.Image(
594
- label="🎯 Segmented Objects",
595
  interactive=False,
596
- show_label=True,
597
- height=600
598
- )
599
- blackspot_display = gr.Image(
600
- label="⚫ Blackspot Detection",
601
- interactive=False,
602
- visible=blackspot_ok,
603
- show_label=True,
604
- height=600
605
  )
 
 
 
 
 
 
 
 
 
 
 
606
  contrast_display = gr.Image(
607
- label="🎨 Contrast Analysis",
608
  interactive=False,
609
- show_label=True,
610
- height=600
611
  )
612
- analysis_report = gr.Markdown(
613
- value="Upload an image and click 'Analyze Environment' to begin.",
614
- elem_classes="report-container"
615
- )
616
- analyze_button.click(
617
- fn=analyze_wrapper,
618
- inputs=[
619
- image_input,
620
- blackspot_threshold,
621
- contrast_threshold,
622
- enable_blackspot,
623
- enable_contrast
624
- ],
625
- outputs=[
626
- seg_display,
627
- blackspot_display,
628
- contrast_display,
629
- analysis_report
630
- ]
631
- )
632
- gr.Markdown("""
633
- ---
634
- **NeuroNest** v2.0 - Enhanced with floor-only blackspot detection and universal contrast analysis
635
- *Creating safer environments for cognitive health through AI*
636
- """)
 
637
  return interface
638
 
639
  if __name__ == "__main__":
 
52
  "swin_cfg": "configs/ade20k/oneformer_swin_large_IN21k_384_bs16_160k.yaml",
53
  "swin_model": "shi-labs/oneformer_ade20k_swin_large",
54
  "swin_file": "250_16_swin_l_oneformer_ade20k_160k.pth",
55
+ "process_size": 640,
56
+ "max_size": 2560
57
  }
58
  }
59
 
60
  BLACKSPOT_MODEL_REPO = "sww35/neuronest-blackspot"
61
  BLACKSPOT_MODEL_FILE = "model_0004999.pth"
62
 
63
+ DISPLAY_MAX_WIDTH = 1920
64
+ DISPLAY_MAX_HEIGHT = 1080
65
 
66
  from universal_contrast_analyzer import UniversalContrastAnalyzer
67
 
68
+ def resize_image_for_processing(image: np.ndarray, target_size: int = 640, max_size: int = 2560) -> Tuple[np.ndarray, float]:
69
  h, w = image.shape[:2]
70
+ scale = target_size / min(h, w)
71
+ if scale * max(h, w) > max_size:
 
72
  scale = max_size / max(h, w)
 
 
73
  new_w = int(w * scale)
74
  new_h = int(h * scale)
75
+ new_w = (new_w // 32) * 32
76
+ new_h = (new_h // 32) * 32
77
+ resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_LANCZOS4)
78
+ return resized, scale
79
+
80
+ def resize_mask_to_original(mask: np.ndarray, original_size: Tuple[int, int]) -> np.ndarray:
81
+ return cv2.resize(mask.astype(np.uint8), (original_size[1], original_size[0]), interpolation=cv2.INTER_NEAREST)
82
+
83
+ def prepare_display_image(image: np.ndarray, max_width: int = DISPLAY_MAX_WIDTH, max_height: int = DISPLAY_MAX_HEIGHT) -> np.ndarray:
84
+ h, w = image.shape[:2]
85
+ scale = 1.0
86
+ if w > max_width:
87
+ scale = max_width / w
88
+ if h * scale > max_height:
89
+ scale = max_height / h
90
+ if scale < 1.0:
91
+ new_w = int(w * scale)
92
+ new_h = int(h * scale)
93
+ return cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_LANCZOS4)
94
+ return image
95
 
96
  class OneFormerManager:
97
  def __init__(self):
98
  self.predictor = None
99
  self.metadata = None
100
  self.initialized = False
101
+ self.process_size = ONEFORMER_CONFIG["ADE20K"]["process_size"]
102
+ self.max_size = ONEFORMER_CONFIG["ADE20K"]["max_size"]
103
 
104
  def initialize(self, backbone: str = "swin"):
105
  if not ONEFORMER_AVAILABLE:
 
132
  logger.error(f"Failed to initialize OneFormer: {e}")
133
  return False
134
 
135
+ def semantic_segmentation(self, image: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
136
  if not self.initialized:
137
  raise RuntimeError("OneFormer not initialized")
138
+ original_size = (image.shape[0], image.shape[1])
139
+ image_processed, scale = resize_image_for_processing(image, self.process_size, self.max_size)
140
+ logger.info(f"Processing image at {image_processed.shape}, scale: {scale}")
141
+ predictions = self.predictor(image_processed, "semantic")
142
+ seg_mask_processed = predictions["sem_seg"].argmax(dim=0).cpu().numpy()
143
+ seg_mask_original = resize_mask_to_original(seg_mask_processed, original_size)
 
 
 
 
 
 
144
  visualizer = Visualizer(
145
  image[:, :, ::-1],
146
  metadata=self.metadata,
147
  instance_mode=ColorMode.IMAGE,
148
+ scale=1.0
149
  )
150
+ vis_output = visualizer.draw_sem_seg(seg_mask_original, alpha=0.6)
151
  vis_image = vis_output.get_image()[:, :, ::-1]
152
+ vis_image_display = prepare_display_image(vis_image)
153
+ return seg_mask_original, vis_image_display
154
 
155
  def extract_floor_areas(self, segmentation: np.ndarray) -> np.ndarray:
156
  floor_mask = np.zeros_like(segmentation, dtype=bool)
 
288
  for mask in filtered_blackspot_masks:
289
  combined_blackspot |= mask
290
  visualization = self.create_visualization(image, floor_mask, combined_blackspot)
291
+ visualization_display = prepare_display_image(visualization)
292
  floor_area = int(np.sum(floor_mask))
293
  blackspot_area = int(np.sum(combined_blackspot))
294
  coverage_percentage = (blackspot_area / floor_area * 100) if floor_area > 0 else 0
 
317
  blackspot_contours, _ = cv2.findContours(
318
  blackspot_mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
319
  )
320
+ cv2.drawContours(vis, blackspot_contours, -1, (255, 255, 0), 4)
321
  return vis
322
 
323
  def _empty_results(self, image: np.ndarray) -> Dict:
324
  empty_mask = np.zeros(image.shape[:2], dtype=bool)
325
+ visualization_display = prepare_display_image(image)
326
  return {
327
  'visualization': visualization_display,
328
  'floor_mask': empty_mask,
 
364
  if not self.initialized:
365
  return {"error": "Application not properly initialized"}
366
  try:
367
+ image = cv2.imread(image_path, cv2.IMREAD_COLOR)
368
  if image is None:
369
  return {"error": "Could not load image"}
370
  image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
 
377
  'statistics': {}
378
  }
379
  logger.info("Running semantic segmentation...")
380
+ seg_mask, seg_visualization = self.oneformer.semantic_segmentation(image_rgb)
381
  results['segmentation'] = {
382
  'visualization': seg_visualization,
383
  'mask': seg_mask
 
400
  contrast_results = self.contrast_analyzer.analyze_contrast(
401
  image_rgb, seg_mask
402
  )
403
+ contrast_viz_display = prepare_display_image(contrast_results['visualization'])
404
  contrast_results['visualization'] = contrast_viz_display
405
  results['contrast'] = contrast_results
406
  logger.info("Contrast analysis completed")
 
548
  - **Floor-Only Blackspot Detection**: Locates dangerous dark areas on walking surfaces
549
  - **Universal Contrast Analysis**: Evaluates visibility between ALL adjacent objects
550
 
551
+ *Following WCAG 2.1 guidelines for visual accessibility | Upload a Picture. Click 'Analyze Environment'.Then scroll down.*
552
  """
553
  with gr.Blocks(css="""
554
+ .container { max-width: 100%; margin: auto; padding: 20px; }
555
+ .image-output { margin: 20px 0; }
556
+ .image-output img {
557
+ width: 100%;
558
+ height: auto;
559
+ max-width: 1920px;
560
+ margin: 0 auto;
561
+ display: block;
562
+ border: 1px solid #ddd;
563
+ border-radius: 8px;
564
  }
565
+ .controls-row { margin-bottom: 30px; background: #f5f5f5; padding: 20px; border-radius: 8px; }
566
+ .main-button { height: 80px !important; font-size: 1.3em !important; font-weight: bold !important; }
567
+ .report-box { max-width: 1200px; margin: 30px auto; padding: 30px; background: #f9f9f9; border-radius: 8px; }
568
+ h2 { margin-top: 40px; margin-bottom: 20px; color: #333; }
569
+ """, theme=gr.themes.Base()) as interface:
570
+ with gr.Column(elem_classes="container"):
571
+ gr.Markdown(f"# {title}")
572
+ gr.Markdown(description)
573
+ if not blackspot_ok:
574
+ gr.Markdown("""
575
+ ⚠️ **Note:** Blackspot detection model not available.
576
+ To enable blackspot detection, upload the model to HuggingFace or ensure it's in the local directory.
577
+ """)
578
+ with gr.Row(elem_classes="controls-row"):
579
+ with gr.Column(scale=1):
580
+ enable_blackspot = gr.Checkbox(
581
+ value=blackspot_ok,
582
+ label="Enable Floor Blackspot Detection",
583
+ interactive=blackspot_ok
584
+ )
585
+ blackspot_threshold = gr.Slider(
586
+ minimum=0.1,
587
+ maximum=0.9,
588
+ value=0.5,
589
+ step=0.05,
590
+ label="Blackspot Sensitivity",
591
+ visible=blackspot_ok
592
+ )
593
+ with gr.Column(scale=1):
594
+ enable_contrast = gr.Checkbox(
595
+ value=True,
596
+ label="Enable Universal Contrast Analysis"
597
+ )
598
+ contrast_threshold = gr.Slider(
599
+ minimum=3.0,
600
+ maximum=7.0,
601
+ value=4.5,
602
+ step=0.1,
603
+ label="WCAG Contrast Threshold"
604
+ )
605
+ with gr.Row():
606
+ with gr.Column(scale=2):
607
+ image_input = gr.Image(
608
+ label="📸 Upload Room Image",
609
+ type="filepath",
610
+ height=500
611
+ )
612
+ with gr.Column(scale=1):
613
+ analyze_button = gr.Button(
614
+ "🔍 Analyze Environment",
615
+ variant="primary",
616
+ elem_classes="main-button"
617
+ )
618
+ gr.Markdown("---")
619
+ gr.Markdown("## 🎯 Segmented Objects")
620
  seg_display = gr.Image(
621
+ label=None,
622
  interactive=False,
623
+ show_label=False,
624
+ elem_classes="image-output"
 
 
 
 
 
 
 
625
  )
626
+ if blackspot_ok:
627
+ gr.Markdown("## ⚫ Blackspot Detection")
628
+ blackspot_display = gr.Image(
629
+ label=None,
630
+ interactive=False,
631
+ show_label=False,
632
+ elem_classes="image-output"
633
+ )
634
+ else:
635
+ blackspot_display = gr.Image(visible=False)
636
+ gr.Markdown("## 🎨 Contrast Analysis")
637
  contrast_display = gr.Image(
638
+ label=None,
639
  interactive=False,
640
+ show_label=False,
641
+ elem_classes="image-output"
642
  )
643
+ gr.Markdown("---")
644
+ analysis_report = gr.Markdown(
645
+ value="Upload an image and click 'Analyze Environment' to begin.",
646
+ elem_classes="report-box"
647
+ )
648
+ analyze_button.click(
649
+ fn=analyze_wrapper,
650
+ inputs=[
651
+ image_input,
652
+ blackspot_threshold,
653
+ contrast_threshold,
654
+ enable_blackspot,
655
+ enable_contrast
656
+ ],
657
+ outputs=[
658
+ seg_display,
659
+ blackspot_display,
660
+ contrast_display,
661
+ analysis_report
662
+ ]
663
+ )
664
+ gr.Markdown("""
665
+ ---
666
+ **NeuroNest** v2.0 - Enhanced with floor-only blackspot detection and universal contrast analysis
667
+ *Creating safer environments for cognitive health through AI*
668
+ """)
669
  return interface
670
 
671
  if __name__ == "__main__":