LogicGoInfotechSpaces commited on
Commit
1ab24b1
·
1 Parent(s): 62974a7

fix: improve pink detection with multiple methods and add debug logging to diagnose removal issues

Browse files
Files changed (1) hide show
  1. api/main.py +41 -16
api/main.py CHANGED
@@ -394,27 +394,38 @@ def remove_pink_segments(
394
  # Pink/Magenta → white in mask (remove)
395
  # Everything else (natural image colors, including dark areas) → black in mask (keep)
396
 
397
- # Detect pink/magenta paint (RGB: R>240, G<30, B>240)
398
- magenta_detected = (
399
- (img_rgb[:, :, 0] > 240) & # Red: high
400
- (img_rgb[:, :, 1] < 30) & # Green: low
401
- (img_rgb[:, :, 2] > 240) # Blue: high
 
402
  ).astype(np.uint8) * 255
403
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  # Clean up the pink mask
405
  kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
406
- binmask = cv2.morphologyEx(magenta_detected, cv2.MORPH_CLOSE, kernel, iterations=2)
407
  binmask = cv2.morphologyEx(binmask, cv2.MORPH_OPEN, kernel, iterations=1)
408
 
409
  nonzero = int((binmask > 0).sum())
410
- log.info(f"Detected {nonzero} pink pixels to remove")
 
411
 
412
- if nonzero < 50:
413
- log.warning("Very few pink pixels detected! Trying strict magenta detection...")
414
- magenta_strict = np.all(img_rgb == [255, 0, 255], axis=2).astype(np.uint8) * 255
415
- binmask = cv2.morphologyEx(magenta_strict, cv2.MORPH_CLOSE, kernel, iterations=3)
416
- nonzero = int((binmask > 0).sum())
417
- log.info(f"Strict detection: {nonzero} pink pixels")
418
 
419
  if nonzero < 50:
420
  log.error("No pink segments detected! Returning original image.")
@@ -428,7 +439,7 @@ def remove_pink_segments(
428
  }
429
 
430
  # Create binary mask: Pink pixels → white (255), Everything else → black (0)
431
- # But we need to encode it in RGBA format that process_inpaint expects
432
  # process_inpaint does: mask = 255 - mask[:,:,3]
433
  # So: alpha=0 (transparent/pink) → becomes 255 (white/remove)
434
  # alpha=255 (opaque/keep) → becomes 0 (black/keep)
@@ -441,11 +452,25 @@ def remove_pink_segments(
441
  # 255 (opaque) everywhere else → will become black after 255-alpha
442
  mask_rgba[:, :, 3] = 255 - binmask # Invert: pink areas get alpha=0, rest get alpha=255
443
 
 
 
 
444
  total_pixels = binmask.shape[0] * binmask.shape[1]
445
- log.info(f"Created binary mask: {nonzero} pink pixels white (255) in final mask, {total_pixels - nonzero} black (0) - everything else automatically")
 
 
 
 
 
 
 
 
 
446
 
447
  # Process with invert_mask=True (default) because process_inpaint expects alpha=0 for removal
448
- result = process_inpaint(np.array(img), mask_rgba, invert_mask=True)
 
 
449
  result_name = f"output_{uuid.uuid4().hex}.png"
450
  result_path = os.path.join(OUTPUT_DIR, result_name)
451
  Image.fromarray(result).save(result_path, "PNG", optimize=False, compress_level=1)
 
394
  # Pink/Magenta → white in mask (remove)
395
  # Everything else (natural image colors, including dark areas) → black in mask (keep)
396
 
397
+ # More robust pink/magenta detection - try multiple methods
398
+ # Method 1: Detect bright magenta (RGB: R>200, G<80, B>200) - more lenient
399
+ magenta_detected_loose = (
400
+ (img_rgb[:, :, 0] > 200) & # Red: high
401
+ (img_rgb[:, :, 1] < 80) & # Green: low (allow more tolerance)
402
+ (img_rgb[:, :, 2] > 200) # Blue: high
403
  ).astype(np.uint8) * 255
404
 
405
+ # Method 2: Detect exact magenta (255, 0, 255)
406
+ magenta_strict = np.all(img_rgb == [255, 0, 255], axis=2).astype(np.uint8) * 255
407
+
408
+ # Method 3: Detect pink-ish colors (high red+blue, low green)
409
+ pink_detected = (
410
+ (img_rgb[:, :, 0] > 220) & # Red: very high
411
+ (img_rgb[:, :, 1] < 100) & # Green: low
412
+ (img_rgb[:, :, 2] > 220) # Blue: very high
413
+ ).astype(np.uint8) * 255
414
+
415
+ # Combine all detection methods
416
+ binmask = np.maximum.reduce([magenta_detected_loose, magenta_strict, pink_detected])
417
+
418
  # Clean up the pink mask
419
  kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
420
+ binmask = cv2.morphologyEx(binmask, cv2.MORPH_CLOSE, kernel, iterations=2)
421
  binmask = cv2.morphologyEx(binmask, cv2.MORPH_OPEN, kernel, iterations=1)
422
 
423
  nonzero = int((binmask > 0).sum())
424
+ total_pixels = binmask.shape[0] * binmask.shape[1]
425
+ log.info(f"Detected {nonzero} pink pixels ({100*nonzero/total_pixels:.2f}% of image) to remove")
426
 
427
+ # Debug: show detection stats
428
+ log.info(f"Detection stats - Loose: {int((magenta_detected_loose > 0).sum())}, Strict: {int((magenta_strict > 0).sum())}, Pink: {int((pink_detected > 0).sum())}")
 
 
 
 
429
 
430
  if nonzero < 50:
431
  log.error("No pink segments detected! Returning original image.")
 
439
  }
440
 
441
  # Create binary mask: Pink pixels → white (255), Everything else → black (0)
442
+ # Encode in RGBA format that process_inpaint expects
443
  # process_inpaint does: mask = 255 - mask[:,:,3]
444
  # So: alpha=0 (transparent/pink) → becomes 255 (white/remove)
445
  # alpha=255 (opaque/keep) → becomes 0 (black/keep)
 
452
  # 255 (opaque) everywhere else → will become black after 255-alpha
453
  mask_rgba[:, :, 3] = 255 - binmask # Invert: pink areas get alpha=0, rest get alpha=255
454
 
455
+ # Verify mask encoding
456
+ alpha_zero_count = int((mask_rgba[:,:,3] == 0).sum())
457
+ alpha_255_count = int((mask_rgba[:,:,3] == 255).sum())
458
  total_pixels = binmask.shape[0] * binmask.shape[1]
459
+ log.info(f"Mask encoding: {alpha_zero_count} pixels with alpha=0 (pink), {alpha_255_count} pixels with alpha=255 (keep)")
460
+ log.info(f"After 255-alpha conversion: {alpha_zero_count} will become white (255/remove), {alpha_255_count} will become black (0/keep)")
461
+
462
+ # IMPORTANT: We need to use the ORIGINAL image WITHOUT pink paint for inpainting!
463
+ # Remove pink from the original image before processing
464
+ # Create a clean version: where pink was detected, keep original image colors
465
+ img_clean = np.array(img.convert("RGBA"))
466
+ # Where pink is detected, we want to inpaint, so we can leave it (or blend it out)
467
+ # Actually, the model will inpaint over those areas, so we can pass the original
468
+ # But for better results, we might want to remove the pink overlay first
469
 
470
  # Process with invert_mask=True (default) because process_inpaint expects alpha=0 for removal
471
+ log.info(f"Starting inpainting process...")
472
+ result = process_inpaint(img_clean, mask_rgba, invert_mask=True)
473
+ log.info(f"Inpainting complete, result shape: {result.shape}")
474
  result_name = f"output_{uuid.uuid4().hex}.png"
475
  result_path = os.path.join(OUTPUT_DIR, result_name)
476
  Image.fromarray(result).save(result_path, "PNG", optimize=False, compress_level=1)