LogicGoInfotechSpaces commited on
Commit
782a2a8
·
1 Parent(s): 0e28031

feat: use fixed pink RGB bounds (lower=[150,0,100], upper=[255,120,255]) for /remove-pink and mask_is_painted in /inpaint-multipart; keep white=remove logic

Browse files
Files changed (1) hide show
  1. api/main.py +19 -35
api/main.py CHANGED
@@ -193,7 +193,7 @@ def inpaint(req: InpaintRequest, _: None = Depends(bearer_auth)) -> Dict[str, st
193
  img_rgba = _load_rgba_image(file_store[req.image_id]["path"])
194
  mask_img = Image.open(file_store[req.mask_id]["path"]) # may be RGB/gray/RGBA
195
  mask_rgba = _load_rgba_mask_from_image(mask_img)
196
-
197
  # Debug: check mask before processing
198
  white_pixels = int((mask_rgba[:,:,0] > 128).sum())
199
  log.info(f"Inpaint request: mask has {white_pixels} white pixels, invert_mask={req.invert_mask}")
@@ -279,12 +279,13 @@ def inpaint_multipart(
279
 
280
  m_rgb = cv2.cvtColor(np.array(m), cv2.COLOR_RGBA2RGB)
281
 
282
- # Method 1: Detect magenta/pink paint directly (RGB: 255, 0, 255)
283
- # Allow some tolerance for slight variations (e.g., 250-255 for R/B, 0-10 for G)
 
284
  magenta_detected = (
285
- (m_rgb[:, :, 0] > 240) & # Red channel: high (240-255)
286
- (m_rgb[:, :, 1] < 30) & # Green channel: low (0-30)
287
- (m_rgb[:, :, 2] > 240) # Blue channel: high (240-255)
288
  ).astype(np.uint8) * 255
289
 
290
  # Method 2: Also check if original image was provided to find differences
@@ -313,13 +314,8 @@ def inpaint_multipart(
313
  nonzero = int((binmask > 0).sum())
314
  log.info("Pink/magenta paint detected: %d pixels marked for removal (white)", nonzero)
315
 
316
- if nonzero < 50:
317
- log.warning("Very few pixels detected! Trying stricter magenta detection...")
318
- # Try more strict magenta detection (exact match)
319
- magenta_strict = np.all(m_rgb == [255, 0, 255], axis=2).astype(np.uint8) * 255
320
- binmask = cv2.morphologyEx(magenta_strict, cv2.MORPH_CLOSE, kernel, iterations=3)
321
- nonzero = int((binmask > 0).sum())
322
- log.info("Strict magenta detection: %d pixels", nonzero)
323
 
324
  if nonzero < 50:
325
  log.error("CRITICAL: Could not detect pink/magenta paint! Returning original image.")
@@ -344,7 +340,7 @@ def inpaint_multipart(
344
  log.info("Successfully created binary mask: %d pink pixels → white (255), %d pixels → black (0)",
345
  nonzero, binmask.shape[0] * binmask.shape[1] - nonzero)
346
  else:
347
- mask_rgba = _load_rgba_mask_from_image(m)
348
 
349
  # When mask_is_painted=true, we encode pink as alpha=0, so process_inpaint's default invert_mask=True works correctly
350
  actual_invert = invert_mask # Use default True for painted masks
@@ -394,27 +390,15 @@ 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
- # 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)
@@ -424,8 +408,8 @@ def remove_pink_segments(
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.")
 
193
  img_rgba = _load_rgba_image(file_store[req.image_id]["path"])
194
  mask_img = Image.open(file_store[req.mask_id]["path"]) # may be RGB/gray/RGBA
195
  mask_rgba = _load_rgba_mask_from_image(mask_img)
196
+
197
  # Debug: check mask before processing
198
  white_pixels = int((mask_rgba[:,:,0] > 128).sum())
199
  log.info(f"Inpaint request: mask has {white_pixels} white pixels, invert_mask={req.invert_mask}")
 
279
 
280
  m_rgb = cv2.cvtColor(np.array(m), cv2.COLOR_RGBA2RGB)
281
 
282
+ # Detect pink/magenta using fixed RGB bounds (same as /remove-pink)
283
+ lower = np.array([150, 0, 100], dtype=np.uint8)
284
+ upper = np.array([255, 120, 255], dtype=np.uint8)
285
  magenta_detected = (
286
+ (m_rgb[:, :, 0] >= lower[0]) & (m_rgb[:, :, 0] <= upper[0]) &
287
+ (m_rgb[:, :, 1] >= lower[1]) & (m_rgb[:, :, 1] <= upper[1]) &
288
+ (m_rgb[:, :, 2] >= lower[2]) & (m_rgb[:, :, 2] <= upper[2])
289
  ).astype(np.uint8) * 255
290
 
291
  # Method 2: Also check if original image was provided to find differences
 
314
  nonzero = int((binmask > 0).sum())
315
  log.info("Pink/magenta paint detected: %d pixels marked for removal (white)", nonzero)
316
 
317
+ # If very few pixels detected, assume the user may already be providing a BW mask
318
+ # and proceed without forcing strict detection
 
 
 
 
 
319
 
320
  if nonzero < 50:
321
  log.error("CRITICAL: Could not detect pink/magenta paint! Returning original image.")
 
340
  log.info("Successfully created binary mask: %d pink pixels → white (255), %d pixels → black (0)",
341
  nonzero, binmask.shape[0] * binmask.shape[1] - nonzero)
342
  else:
343
+ mask_rgba = _load_rgba_mask_from_image(m)
344
 
345
  # When mask_is_painted=true, we encode pink as alpha=0, so process_inpaint's default invert_mask=True works correctly
346
  actual_invert = invert_mask # Use default True for painted masks
 
390
  # Pink/Magenta → white in mask (remove)
391
  # Everything else (natural image colors, including dark areas) → black in mask (keep)
392
 
393
+ # Detect pink/magenta using fixed RGB bounds per requested logic
394
+ lower = np.array([150, 0, 100], dtype=np.uint8)
395
+ upper = np.array([255, 120, 255], dtype=np.uint8)
396
+ binmask = (
397
+ (img_rgb[:, :, 0] >= lower[0]) & (img_rgb[:, :, 0] <= upper[0]) &
398
+ (img_rgb[:, :, 1] >= lower[1]) & (img_rgb[:, :, 1] <= upper[1]) &
399
+ (img_rgb[:, :, 2] >= lower[2]) & (img_rgb[:, :, 2] <= upper[2])
400
  ).astype(np.uint8) * 255
401
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402
  # Clean up the pink mask
403
  kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
404
  binmask = cv2.morphologyEx(binmask, cv2.MORPH_CLOSE, kernel, iterations=2)
 
408
  total_pixels = binmask.shape[0] * binmask.shape[1]
409
  log.info(f"Detected {nonzero} pink pixels ({100*nonzero/total_pixels:.2f}% of image) to remove")
410
 
411
+ # Debug: log bounds used
412
+ log.info("Pink detection bounds used: lower=[150,0,100], upper=[255,120,255]")
413
 
414
  if nonzero < 50:
415
  log.error("No pink segments detected! Returning original image.")