Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -976,7 +976,7 @@ def predict_with_paper(image, paper_size, offset, offset_unit, finger_clearance=
|
|
| 976 |
# Mask paper area in input image first
|
| 977 |
masked_input_image = mask_paper_area_in_image(image, paper_contour)
|
| 978 |
|
| 979 |
-
#
|
| 980 |
yolo_world = get_yolo_world()
|
| 981 |
if yolo_world is None:
|
| 982 |
logger.warning("YOLOWorld model not available, proceeding with full image")
|
|
@@ -1005,13 +1005,19 @@ def predict_with_paper(image, paper_size, offset, offset_unit, finger_clearance=
|
|
| 1005 |
x_max = min(masked_input_image.shape[1], x_max + margin)
|
| 1006 |
y_max = min(masked_input_image.shape[0], y_max + margin)
|
| 1007 |
|
| 1008 |
-
#
|
| 1009 |
-
|
| 1010 |
-
|
| 1011 |
-
|
| 1012 |
-
|
| 1013 |
-
|
| 1014 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1015 |
|
| 1016 |
# Remove background from cropped image
|
| 1017 |
orig_size = image.shape[:2]
|
|
@@ -1020,7 +1026,10 @@ def predict_with_paper(image, paper_size, offset, offset_unit, finger_clearance=
|
|
| 1020 |
|
| 1021 |
# Resize mask to match cropped region and place back in original image space
|
| 1022 |
full_mask = np.zeros((orig_size[0], orig_size[1]), dtype=np.uint8)
|
| 1023 |
-
|
|
|
|
|
|
|
|
|
|
| 1024 |
full_mask[y_min:y_min+resized_mask.shape[0], x_min:x_min+resized_mask.shape[1]] = resized_mask
|
| 1025 |
|
| 1026 |
# Remove paper area from mask to focus only on objects
|
|
@@ -1045,33 +1054,6 @@ def predict_with_paper(image, paper_size, offset, offset_unit, finger_clearance=
|
|
| 1045 |
except Exception as e:
|
| 1046 |
raise gr.Error(f"Error in object detection: {str(e)}")
|
| 1047 |
|
| 1048 |
-
# Rest of the function remains unchanged...
|
| 1049 |
-
# [Keep existing code for dilation, contour extraction, DXF generation, etc.]
|
| 1050 |
-
objects_mask = remove_bg(image)
|
| 1051 |
-
processed_size = objects_mask.shape[:2]
|
| 1052 |
-
|
| 1053 |
-
# Resize mask to match original image
|
| 1054 |
-
objects_mask = cv2.resize(objects_mask, (image.shape[1], image.shape[0]))
|
| 1055 |
-
|
| 1056 |
-
# Remove paper area from mask to focus only on objects
|
| 1057 |
-
objects_mask = exclude_paper_area(objects_mask, paper_contour)
|
| 1058 |
-
|
| 1059 |
-
# Check if we actually have object pixels after paper exclusion
|
| 1060 |
-
object_pixels = np.count_nonzero(objects_mask)
|
| 1061 |
-
if object_pixels < 1000: # Minimum threshold
|
| 1062 |
-
raise NoObjectDetectedError("No significant object detected after excluding paper area")
|
| 1063 |
-
|
| 1064 |
-
# Validate single object
|
| 1065 |
-
validate_single_object(objects_mask, paper_contour)
|
| 1066 |
-
|
| 1067 |
-
except (MultipleObjectsError, NoObjectDetectedError) as e:
|
| 1068 |
-
return (
|
| 1069 |
-
None, None, None, None,
|
| 1070 |
-
f"Error: {str(e)}"
|
| 1071 |
-
)
|
| 1072 |
-
except Exception as e:
|
| 1073 |
-
raise gr.Error(f"Error in object detection: {str(e)}")
|
| 1074 |
-
|
| 1075 |
# Apply edge rounding if specified
|
| 1076 |
rounded_mask = objects_mask.copy()
|
| 1077 |
|
|
@@ -1097,8 +1079,8 @@ def predict_with_paper(image, paper_size, offset, offset_unit, finger_clearance=
|
|
| 1097 |
# Generate DXF - scaling_factor should be in mm/px for proper DXF units
|
| 1098 |
dxf, finger_polygons, original_polygons = save_dxf_spline(
|
| 1099 |
contours,
|
| 1100 |
-
scaling_factor, # This should
|
| 1101 |
-
|
| 1102 |
finger_clearance=(finger_clearance == "On")
|
| 1103 |
)
|
| 1104 |
except FingerCutOverlapError as e:
|
|
@@ -1112,7 +1094,7 @@ def predict_with_paper(image, paper_size, offset, offset_unit, finger_clearance=
|
|
| 1112 |
for poly in finger_polygons:
|
| 1113 |
try:
|
| 1114 |
coords = np.array([
|
| 1115 |
-
(int(x / scaling_factor), int(
|
| 1116 |
for x, y in poly.exterior.coords
|
| 1117 |
], np.int32).reshape((-1, 1, 2))
|
| 1118 |
|
|
|
|
| 976 |
# Mask paper area in input image first
|
| 977 |
masked_input_image = mask_paper_area_in_image(image, paper_contour)
|
| 978 |
|
| 979 |
+
# Use YOLOWorld to detect object bounding box
|
| 980 |
yolo_world = get_yolo_world()
|
| 981 |
if yolo_world is None:
|
| 982 |
logger.warning("YOLOWorld model not available, proceeding with full image")
|
|
|
|
| 1005 |
x_max = min(masked_input_image.shape[1], x_max + margin)
|
| 1006 |
y_max = min(masked_input_image.shape[0], y_max + margin)
|
| 1007 |
|
| 1008 |
+
# Validate crop region
|
| 1009 |
+
if x_max <= x_min or y_max <= y_min:
|
| 1010 |
+
logger.warning("Invalid crop region, proceeding with full image")
|
| 1011 |
+
cropped_image = masked_input_image
|
| 1012 |
+
crop_offset = (0, 0)
|
| 1013 |
+
else:
|
| 1014 |
+
# Crop the masked image
|
| 1015 |
+
cropped_image = masked_input_image[y_min:y_max, x_min:x_max]
|
| 1016 |
+
crop_offset = (x_min, y_min) # Store offset for mask realignment
|
| 1017 |
+
logger.info(f"Cropped to box: ({x_min}, {y_min}, {x_max}, {y_max})")
|
| 1018 |
+
|
| 1019 |
+
# Debug: Save cropped image
|
| 1020 |
+
cv2.imwrite("./debug/cropped_image.jpg", cropped_image)
|
| 1021 |
|
| 1022 |
# Remove background from cropped image
|
| 1023 |
orig_size = image.shape[:2]
|
|
|
|
| 1026 |
|
| 1027 |
# Resize mask to match cropped region and place back in original image space
|
| 1028 |
full_mask = np.zeros((orig_size[0], orig_size[1]), dtype=np.uint8)
|
| 1029 |
+
if cropped_image.shape[:2] != processed_size:
|
| 1030 |
+
resized_mask = cv2.resize(objects_mask, (cropped_image.shape[1], cropped_image.shape[0]))
|
| 1031 |
+
else:
|
| 1032 |
+
resized_mask = objects_mask
|
| 1033 |
full_mask[y_min:y_min+resized_mask.shape[0], x_min:x_min+resized_mask.shape[1]] = resized_mask
|
| 1034 |
|
| 1035 |
# Remove paper area from mask to focus only on objects
|
|
|
|
| 1054 |
except Exception as e:
|
| 1055 |
raise gr.Error(f"Error in object detection: {str(e)}")
|
| 1056 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1057 |
# Apply edge rounding if specified
|
| 1058 |
rounded_mask = objects_mask.copy()
|
| 1059 |
|
|
|
|
| 1079 |
# Generate DXF - scaling_factor should be in mm/px for proper DXF units
|
| 1080 |
dxf, finger_polygons, original_polygons = save_dxf_spline(
|
| 1081 |
contours,
|
| 1082 |
+
scaling_factor, # This should mm/px
|
| 1083 |
+
orig_size[0], # Use original image height instead of processed_size
|
| 1084 |
finger_clearance=(finger_clearance == "On")
|
| 1085 |
)
|
| 1086 |
except FingerCutOverlapError as e:
|
|
|
|
| 1094 |
for poly in finger_polygons:
|
| 1095 |
try:
|
| 1096 |
coords = np.array([
|
| 1097 |
+
(int(x / scaling_factor), int(orig_size[0] - y / scaling_factor))
|
| 1098 |
for x, y in poly.exterior.coords
|
| 1099 |
], np.int32).reshape((-1, 1, 2))
|
| 1100 |
|