Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -402,36 +402,92 @@ def remove_bg(image: np.ndarray) -> np.ndarray:
|
|
402 |
logger.error(f"Error in BiRefNet background removal: {e}")
|
403 |
raise
|
404 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
405 |
def exclude_paper_area(mask: np.ndarray, paper_contour: np.ndarray, expansion_factor: float = 1.2) -> np.ndarray:
|
406 |
"""
|
407 |
Remove paper area from the mask to focus only on objects
|
408 |
"""
|
409 |
-
# Create paper mask
|
410 |
paper_mask = np.zeros(mask.shape[:2], dtype=np.uint8)
|
411 |
|
412 |
-
# # Expand paper contour slightly
|
413 |
-
# epsilon = expansion_factor * cv2.arcLength(paper_contour, True)
|
414 |
-
# expanded_contour = cv2.approxPolyDP(paper_contour, epsilon, True)
|
415 |
-
|
416 |
-
# cv2.fillPoly(paper_mask, [expanded_contour], 255)
|
417 |
# Create a more aggressive inward shrinking of paper bounds
|
418 |
rect = cv2.boundingRect(paper_contour)
|
419 |
shrink_pixels = int(min(rect[2], rect[3]) * 0.05) # Shrink by 5% of smaller dimension
|
420 |
|
421 |
-
# Create shrunken rectangle
|
422 |
x, y, w, h = rect
|
423 |
-
|
424 |
[[x + shrink_pixels, y + shrink_pixels]],
|
425 |
[[x + w - shrink_pixels, y + shrink_pixels]],
|
426 |
[[x + w - shrink_pixels, y + h - shrink_pixels]],
|
427 |
[[x + shrink_pixels, y + h - shrink_pixels]]
|
428 |
])
|
429 |
|
430 |
-
|
|
|
431 |
|
432 |
-
#
|
433 |
-
|
434 |
-
result_mask = cv2.bitwise_and(mask, paper_mask_inv)
|
435 |
|
436 |
return result_mask
|
437 |
|
@@ -831,8 +887,16 @@ def predict_with_paper(image, paper_size, offset,offset_unit, finger_clearance=F
|
|
831 |
|
832 |
try:
|
833 |
# Remove background from main objects
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
834 |
orig_size = image.shape[:2]
|
835 |
-
objects_mask = remove_bg(
|
|
|
836 |
processed_size = objects_mask.shape[:2]
|
837 |
|
838 |
# Resize mask to match original image
|
|
|
402 |
logger.error(f"Error in BiRefNet background removal: {e}")
|
403 |
raise
|
404 |
|
405 |
+
# def exclude_paper_area(mask: np.ndarray, paper_contour: np.ndarray, expansion_factor: float = 1.2) -> np.ndarray:
|
406 |
+
# """
|
407 |
+
# Remove paper area from the mask to focus only on objects
|
408 |
+
# """
|
409 |
+
# # Create paper mask with slight expansion to ensure complete removal
|
410 |
+
# paper_mask = np.zeros(mask.shape[:2], dtype=np.uint8)
|
411 |
+
|
412 |
+
# # # Expand paper contour slightly
|
413 |
+
# # epsilon = expansion_factor * cv2.arcLength(paper_contour, True)
|
414 |
+
# # expanded_contour = cv2.approxPolyDP(paper_contour, epsilon, True)
|
415 |
+
|
416 |
+
# # cv2.fillPoly(paper_mask, [expanded_contour], 255)
|
417 |
+
# # Create a more aggressive inward shrinking of paper bounds
|
418 |
+
# rect = cv2.boundingRect(paper_contour)
|
419 |
+
# shrink_pixels = int(min(rect[2], rect[3]) * 0.05) # Shrink by 5% of smaller dimension
|
420 |
+
|
421 |
+
# # Create shrunken rectangle
|
422 |
+
# x, y, w, h = rect
|
423 |
+
# shrunken_contour = np.array([
|
424 |
+
# [[x + shrink_pixels, y + shrink_pixels]],
|
425 |
+
# [[x + w - shrink_pixels, y + shrink_pixels]],
|
426 |
+
# [[x + w - shrink_pixels, y + h - shrink_pixels]],
|
427 |
+
# [[x + shrink_pixels, y + h - shrink_pixels]]
|
428 |
+
# ])
|
429 |
+
|
430 |
+
# cv2.fillPoly(paper_mask, [shrunken_contour], 255)
|
431 |
+
|
432 |
+
# # Invert paper mask and apply to object mask
|
433 |
+
# paper_mask_inv = cv2.bitwise_not(paper_mask)
|
434 |
+
# result_mask = cv2.bitwise_and(mask, paper_mask_inv)
|
435 |
+
|
436 |
+
# return result_mask
|
437 |
+
def mask_paper_area_in_image(image: np.ndarray, paper_contour: np.ndarray) -> np.ndarray:
|
438 |
+
"""
|
439 |
+
Black out paper area in the input image before sending to BiRefNet
|
440 |
+
"""
|
441 |
+
masked_image = image.copy()
|
442 |
+
|
443 |
+
# Create more aggressive paper mask
|
444 |
+
rect = cv2.boundingRect(paper_contour)
|
445 |
+
shrink_pixels = int(min(rect[2], rect[3]) * 0.08) # 8% shrink
|
446 |
+
|
447 |
+
x, y, w, h = rect
|
448 |
+
# Create mask for everything OUTSIDE the inner paper area
|
449 |
+
outer_mask = np.ones(image.shape[:2], dtype=np.uint8) * 255
|
450 |
+
|
451 |
+
inner_contour = np.array([
|
452 |
+
[[x + shrink_pixels, y + shrink_pixels]],
|
453 |
+
[[x + w - shrink_pixels, y + shrink_pixels]],
|
454 |
+
[[x + w - shrink_pixels, y + h - shrink_pixels]],
|
455 |
+
[[x + shrink_pixels, y + h - shrink_pixels]]
|
456 |
+
])
|
457 |
+
|
458 |
+
# Black out everything outside inner paper bounds
|
459 |
+
cv2.fillPoly(outer_mask, [inner_contour], 0)
|
460 |
+
|
461 |
+
# Apply mask to image
|
462 |
+
masked_image[outer_mask == 255] = [0, 0, 0] # Black out paper areas
|
463 |
+
|
464 |
+
return masked_image
|
465 |
+
|
466 |
def exclude_paper_area(mask: np.ndarray, paper_contour: np.ndarray, expansion_factor: float = 1.2) -> np.ndarray:
|
467 |
"""
|
468 |
Remove paper area from the mask to focus only on objects
|
469 |
"""
|
470 |
+
# Create paper mask - this will be the area to EXCLUDE
|
471 |
paper_mask = np.zeros(mask.shape[:2], dtype=np.uint8)
|
472 |
|
|
|
|
|
|
|
|
|
|
|
473 |
# Create a more aggressive inward shrinking of paper bounds
|
474 |
rect = cv2.boundingRect(paper_contour)
|
475 |
shrink_pixels = int(min(rect[2], rect[3]) * 0.05) # Shrink by 5% of smaller dimension
|
476 |
|
477 |
+
# Create shrunken rectangle (area INSIDE paper bounds)
|
478 |
x, y, w, h = rect
|
479 |
+
inner_contour = np.array([
|
480 |
[[x + shrink_pixels, y + shrink_pixels]],
|
481 |
[[x + w - shrink_pixels, y + shrink_pixels]],
|
482 |
[[x + w - shrink_pixels, y + h - shrink_pixels]],
|
483 |
[[x + shrink_pixels, y + h - shrink_pixels]]
|
484 |
])
|
485 |
|
486 |
+
# Fill the INNER area as white (255) - this is where objects should be
|
487 |
+
cv2.fillPoly(paper_mask, [inner_contour], 255)
|
488 |
|
489 |
+
# Apply mask: keep only pixels that are both in original mask AND inside paper bounds
|
490 |
+
result_mask = cv2.bitwise_and(mask, paper_mask)
|
|
|
491 |
|
492 |
return result_mask
|
493 |
|
|
|
887 |
|
888 |
try:
|
889 |
# Remove background from main objects
|
890 |
+
# orig_size = image.shape[:2]
|
891 |
+
# objects_mask = remove_bg(image)
|
892 |
+
|
893 |
+
# Mask paper area in input image first
|
894 |
+
masked_input_image = mask_paper_area_in_image(image, paper_contour)
|
895 |
+
|
896 |
+
# Remove background from main objects using masked image
|
897 |
orig_size = image.shape[:2]
|
898 |
+
objects_mask = remove_bg(masked_input_image)
|
899 |
+
|
900 |
processed_size = objects_mask.shape[:2]
|
901 |
|
902 |
# Resize mask to match original image
|