iammraat commited on
Commit
e6dcbb9
·
verified ·
1 Parent(s): 208d24d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -28
app.py CHANGED
@@ -460,47 +460,52 @@ device = "cuda" if torch.cuda.is_available() else "cpu"
460
  model.to(device)
461
 
462
  def get_crop(image: Image.Image, result, idx: int, padding: int = 15):
463
- img_np = np.array(image)
464
 
465
  if result.masks is not None:
466
- # Original mask (float -> bool)
467
- mask = result.masks.data[idx].cpu().numpy() # shape: (h_orig, w_orig)
468
- mask_bool = mask > 0.5
469
 
470
- # Find bounding box of the mask
471
- ys, xs = np.where(mask_bool)
472
- if len(ys) == 0:
473
- return None
474
 
475
- y_min, y_max = ys.min(), ys.max()
476
- x_min, x_max = xs.min(), xs.max()
 
477
 
478
- # Apply padding to coordinates
479
- y_min_padded = max(0, y_min - padding)
480
- y_max_padded = min(img_np.shape[0], y_max + padding + 1)
481
- x_min_padded = max(0, x_min - padding)
482
- x_max_padded = min(img_np.shape[1], x_max + padding + 1)
483
 
484
- # Extract padded RGB crop
485
- crop = img_np[y_min_padded:y_max_padded, x_min_padded:x_max_padded]
 
 
 
 
486
 
487
- # Now pad the MASK to match the padded crop size
488
- # Create full-size zero mask, place original mask in correct position
489
- full_mask = np.zeros((img_np.shape[0], img_np.shape[1]), dtype=bool)
490
- full_mask[y_min:y_max+1, x_min:x_max+1] = mask_bool
 
491
 
492
- # Slice the padded region of the mask
493
- mask_crop_padded = full_mask[y_min_padded:y_max_padded, x_min_padded:x_max_padded]
 
494
 
495
- # Now shapes match: crop.shape[:2] == mask_crop_padded.shape
496
- crop[~mask_crop_padded] = 255
497
 
498
- return Image.fromarray(crop)
499
 
500
  else:
501
- # Bounding box fallback (unchanged)
502
  xyxy = result.boxes.xyxy[idx].cpu().numpy().astype(int)
503
  x1, y1, x2, y2 = xyxy
 
504
  x1 = max(0, x1 - padding)
505
  y1 = max(0, y1 - padding)
506
  x2 = min(image.width, x2 + padding)
@@ -510,7 +515,6 @@ def get_crop(image: Image.Image, result, idx: int, padding: int = 15):
510
  return None
511
 
512
  return image.crop((x1, y1, x2, y2))
513
-
514
 
515
  def process_image(image: Image.Image):
516
  if image is None:
 
460
  model.to(device)
461
 
462
  def get_crop(image: Image.Image, result, idx: int, padding: int = 15):
463
+ img_np = np.array(image) # shape: (H_full, W_full, 3)
464
 
465
  if result.masks is not None:
466
+ # Get the ORIGINAL bounding box (before any upsampling)
467
+ box = result.boxes.xyxy[idx].cpu().numpy().astype(int) # [x1, y1, x2, y2]
468
+ x1, y1, x2, y2 = box
469
 
470
+ # Get the mask but make sure we use the mask at ORIGINAL size
471
+ # In many cases masks.data[idx] is already at input resolution → we crop it directly
472
+ mask = result.masks.data[idx].cpu().numpy() # shape likely (H_full, W_full)
473
+ mask_bool = mask > 0.5
474
 
475
+ # Crop both image and mask using the **same box coordinates**
476
+ crop_img = img_np[y1:y2, x1:x2] # shape ~ (h_box, w_box, 3)
477
+ crop_mask = mask_bool[y1:y2, x1:x2] # shape ~ (h_box, w_box)
478
 
479
+ if crop_img.size == 0 or crop_mask.size == 0:
480
+ return None
 
 
 
481
 
482
+ # Now apply **padding** around the cropped region
483
+ h, w = crop_img.shape[:2]
484
+ pad_top = min(padding, y1)
485
+ pad_bottom = min(padding, img_np.shape[0] - y2)
486
+ pad_left = min(padding, x1)
487
+ pad_right = min(padding, img_np.shape[1] - x2)
488
 
489
+ # Padded coordinates in full image
490
+ y_start = y1 - pad_top
491
+ y_end = y2 + pad_bottom
492
+ x_start = x1 - pad_left
493
+ x_end = x2 + pad_right
494
 
495
+ # Extract padded crops
496
+ padded_img = img_np[y_start:y_end, x_start:x_end]
497
+ padded_mask = mask_bool[y_start:y_end, x_start:x_end]
498
 
499
+ # Set background (outside mask) to white
500
+ padded_img[~padded_mask] = 255
501
 
502
+ return Image.fromarray(padded_img)
503
 
504
  else:
505
+ # Bounding box fallback (no mask)
506
  xyxy = result.boxes.xyxy[idx].cpu().numpy().astype(int)
507
  x1, y1, x2, y2 = xyxy
508
+
509
  x1 = max(0, x1 - padding)
510
  y1 = max(0, y1 - padding)
511
  x2 = min(image.width, x2 + padding)
 
515
  return None
516
 
517
  return image.crop((x1, y1, x2, y2))
 
518
 
519
  def process_image(image: Image.Image):
520
  if image is None: