Kaifulimaan commited on
Commit
e303dd7
·
1 Parent(s): 53e84fb

Change attention crop to mask outside bounding boxes, fix overlapping text in zone reference

Browse files
backend/app/services/explainability_service.py CHANGED
@@ -222,17 +222,16 @@ def _generate_zone_reference_image(figsize=(5, 5)):
222
  ha='center', va='center', fontsize=11.5,
223
  color='#85C1E9', fontweight='bold', zorder=4)
224
 
225
- ax.text(0.50, 0.93, 'Periphery',
226
  ha='center', va='center', fontsize=11.5,
227
  color='#82E0AA', fontweight='bold', zorder=4)
228
- ax.text(0.50, 0.88, '(image frame)',
229
  ha='center', va='center', fontsize=10.0,
230
  color='#4A8C5C', zorder=4)
231
 
232
  # --- Title ---
233
- ax.text(0.50, 0.98, 'Spatial attention zone reference',
234
- ha='center', va='top', fontsize=11,
235
- color='#A0A0C0', fontweight='bold', zorder=4)
236
 
237
  fig.canvas.draw()
238
  buf = fig.canvas.buffer_rgba()
@@ -431,28 +430,41 @@ class HeatmapFeatureExtractor:
431
 
432
  return {'overlay_with_bbox': overlay}
433
 
434
- def get_highest_attention_crop(self, threshold_ratio=0.6, padding=10):
435
  heatmap_norm = (self.heatmap - self.heatmap.min()) / (self.heatmap.max() - self.heatmap.min() + 1e-6)
 
436
 
437
- coords = np.argwhere(heatmap_norm >= threshold_ratio * heatmap_norm.max())
438
- if len(coords) == 0:
439
- return {'composite_image': self.original_image.copy()}
440
-
441
- y1, x1 = coords.min(axis=0)
442
- y2, x2 = coords.max(axis=0)
443
-
444
- h, w = self.original_image.shape[:2]
445
- y1 = max(0, y1 - padding)
446
- x1 = max(0, x1 - padding)
447
- y2 = min(h, y2 + padding)
448
- x2 = min(w, x2 + padding)
449
-
450
- crop = self.original_image[y1:y2, x1:x2]
451
- if crop.size == 0:
452
- return {'composite_image': self.original_image.copy()}
 
 
 
 
 
 
453
 
454
- crop_resized = cv2.resize(crop, (256, 256), interpolation=cv2.INTER_CUBIC)
455
- return {'composite_image': crop_resized}
 
 
 
 
 
 
456
 
457
  # -------------------------------------------
458
  # Explainability Service
 
222
  ha='center', va='center', fontsize=11.5,
223
  color='#85C1E9', fontweight='bold', zorder=4)
224
 
225
+ ax.text(0.50, 0.90, 'Periphery',
226
  ha='center', va='center', fontsize=11.5,
227
  color='#82E0AA', fontweight='bold', zorder=4)
228
+ ax.text(0.50, 0.84, '(image frame)',
229
  ha='center', va='center', fontsize=10.0,
230
  color='#4A8C5C', zorder=4)
231
 
232
  # --- Title ---
233
+ ax.set_title('Spatial attention zone reference',
234
+ fontsize=12, color='#A0A0C0', fontweight='bold', pad=12)
 
235
 
236
  fig.canvas.draw()
237
  buf = fig.canvas.buffer_rgba()
 
430
 
431
  return {'overlay_with_bbox': overlay}
432
 
433
+ def get_highest_attention_crop(self, threshold=0.6):
434
  heatmap_norm = (self.heatmap - self.heatmap.min()) / (self.heatmap.max() - self.heatmap.min() + 1e-6)
435
+ mask = (heatmap_norm >= threshold).astype(np.uint8) * 255
436
 
437
+ contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
438
+
439
+ # Create a completely black mask for the whole image
440
+ visible_mask = np.zeros_like(self.original_image[:, :, 0])
441
+
442
+ if contours:
443
+ for cnt in contours:
444
+ if cv2.contourArea(cnt) < 50: continue
445
+ x, y, w, h = cv2.boundingRect(cnt)
446
+
447
+ # Add padding
448
+ pad = 25
449
+ x = max(0, x - pad)
450
+ y = max(0, y - pad)
451
+ w = min(self.original_image.shape[1] - x, w + 2*pad)
452
+ h = min(self.original_image.shape[0] - y, h + 2*pad)
453
+
454
+ # Fill the bounding box area with white (visible)
455
+ cv2.rectangle(visible_mask, (x, y), (x + w, y + h), 255, -1)
456
+ else:
457
+ # If no contours, show whole image
458
+ visible_mask.fill(255)
459
 
460
+ # Apply mask: where mask is 0, make image dark (20% brightness)
461
+ darkened_image = (self.original_image * 0.2).astype(np.uint8)
462
+
463
+ # Where visible_mask is 255, use original image, else use darkened_image
464
+ visible_mask_3d = np.stack([visible_mask]*3, axis=2)
465
+ composite = np.where(visible_mask_3d == 255, self.original_image, darkened_image)
466
+
467
+ return {'composite_image': composite}
468
 
469
  # -------------------------------------------
470
  # Explainability Service