mlbench123 commited on
Commit
4ebb124
·
verified ·
1 Parent(s): 8e43c08

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -25
app.py CHANGED
@@ -185,14 +185,14 @@ def detect_paper_contour(image: np.ndarray) -> Tuple[np.ndarray, float]:
185
  # Filter contours by area and aspect ratio to find paper-like rectangles
186
  paper_contours = []
187
  image_area = image.shape[0] * image.shape[1]
188
- min_area = image_area * 0.15 # At least 15% of image
189
- max_area = image_area * 0.95 # At most 95% of image
190
 
191
  for contour in contours:
192
  area = cv2.contourArea(contour)
193
  if min_area < area < max_area:
194
  # Approximate contour to polygon
195
- epsilon = 0.02 * cv2.arcLength(contour, True)
196
  approx = cv2.approxPolyDP(contour, epsilon, True)
197
 
198
  # Check if it's roughly rectangular (4 corners) or close to it
@@ -204,12 +204,12 @@ def detect_paper_contour(image: np.ndarray) -> Tuple[np.ndarray, float]:
204
 
205
  # Check if aspect ratio matches common paper ratios
206
  # A4: 1.414, A3: 1.414, US Letter: 1.294
207
- if 0.6 < aspect_ratio < 2.0: # More lenient tolerance
208
  # Check if contour area is close to bounding rect area (rectangularity)
209
  rect_area = w * h
210
  if rect_area > 0:
211
  extent = area / rect_area
212
- if extent > 0.7: # At least 70% rectangular
213
  paper_contours.append((contour, area, aspect_ratio, extent))
214
 
215
  if not paper_contours:
@@ -467,27 +467,31 @@ def exclude_paper_area(mask: np.ndarray, paper_contour: np.ndarray, expansion_fa
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
 
@@ -893,10 +897,9 @@ def predict_with_paper(image, paper_size, offset,offset_unit, finger_clearance=F
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
@@ -905,6 +908,11 @@ def predict_with_paper(image, paper_size, offset,offset_unit, finger_clearance=F
905
  # Remove paper area from mask to focus only on objects
906
  objects_mask = exclude_paper_area(objects_mask, paper_contour)
907
 
 
 
 
 
 
908
  # Validate single object
909
  validate_single_object(objects_mask, paper_contour)
910
 
 
185
  # Filter contours by area and aspect ratio to find paper-like rectangles
186
  paper_contours = []
187
  image_area = image.shape[0] * image.shape[1]
188
+ min_area = image_area * 0.20 # At least 15% of image
189
+ max_area = image_area * 0.85 # At most 95% of image
190
 
191
  for contour in contours:
192
  area = cv2.contourArea(contour)
193
  if min_area < area < max_area:
194
  # Approximate contour to polygon
195
+ epsilon = 0.015 * cv2.arcLength(contour, True)
196
  approx = cv2.approxPolyDP(contour, epsilon, True)
197
 
198
  # Check if it's roughly rectangular (4 corners) or close to it
 
204
 
205
  # Check if aspect ratio matches common paper ratios
206
  # A4: 1.414, A3: 1.414, US Letter: 1.294
207
+ if 1.3 < aspect_ratio < 1.5: # More lenient tolerance
208
  # Check if contour area is close to bounding rect area (rectangularity)
209
  rect_area = w * h
210
  if rect_area > 0:
211
  extent = area / rect_area
212
+ if extent > 0.85: # At least 70% rectangular
213
  paper_contours.append((contour, area, aspect_ratio, extent))
214
 
215
  if not paper_contours:
 
467
  """
468
  Remove paper area from the mask to focus only on objects
469
  """
470
+ # Get paper bounding rectangle
 
 
 
471
  rect = cv2.boundingRect(paper_contour)
 
 
 
472
  x, y, w, h = rect
 
 
 
 
 
 
473
 
474
+ # Create much more aggressive inward shrinking
475
+ shrink_x = int(w * 0.15) # Shrink 15% from each side
476
+ shrink_y = int(h * 0.15) # Shrink 15% from top/bottom
477
+
478
+ # Create inner object area (much smaller than paper)
479
+ inner_x = x + shrink_x
480
+ inner_y = y + shrink_y
481
+ inner_w = w - (2 * shrink_x)
482
+ inner_h = h - (2 * shrink_y)
483
+
484
+ # Create mask for object area only
485
+ object_area_mask = np.zeros(mask.shape[:2], dtype=np.uint8)
486
+ cv2.rectangle(object_area_mask, (inner_x, inner_y), (inner_x + inner_w, inner_y + inner_h), 255, -1)
487
+
488
+ # Apply mask: keep only pixels in the inner object area
489
+ result_mask = cv2.bitwise_and(mask, object_area_mask)
490
 
491
+ # Additional cleanup: remove small noise and fill gaps
492
+ kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
493
+ result_mask = cv2.morphologyEx(result_mask, cv2.MORPH_OPEN, kernel, iterations=1)
494
+ result_mask = cv2.morphologyEx(result_mask, cv2.MORPH_CLOSE, kernel, iterations=2)
495
 
496
  return result_mask
497
 
 
897
  # Mask paper area in input image first
898
  masked_input_image = mask_paper_area_in_image(image, paper_contour)
899
 
900
+ # Remove background from main objects
901
  orig_size = image.shape[:2]
902
+ objects_mask = remove_bg(image)
 
903
  processed_size = objects_mask.shape[:2]
904
 
905
  # Resize mask to match original image
 
908
  # Remove paper area from mask to focus only on objects
909
  objects_mask = exclude_paper_area(objects_mask, paper_contour)
910
 
911
+ # Check if we actually have object pixels after paper exclusion
912
+ object_pixels = np.count_nonzero(objects_mask)
913
+ if object_pixels < 1000: # Minimum threshold
914
+ raise NoObjectDetectedError("No significant object detected after excluding paper area")
915
+
916
  # Validate single object
917
  validate_single_object(objects_mask, paper_contour)
918