Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -286,36 +286,52 @@ def polygon_to_exterior_coords(poly: Polygon):
|
|
286 |
return []
|
287 |
return list(poly.exterior.coords)
|
288 |
|
289 |
-
def place_finger_cut_adjusted(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
import random
|
291 |
needed_center_distance = circle_diameter + min_gap
|
292 |
radius = circle_diameter / 2.0
|
293 |
attempts = 0
|
294 |
indices = list(range(len(points_inch)))
|
295 |
-
random.shuffle(indices) # Shuffle indices for randomness
|
296 |
|
297 |
for i in indices:
|
298 |
if attempts >= max_attempts:
|
299 |
break
|
300 |
cx, cy = points_inch[i]
|
301 |
-
# Try small adjustments around the
|
302 |
for dx in np.linspace(-0.1, 0.1, 5):
|
303 |
for dy in np.linspace(-0.1, 0.1, 5):
|
304 |
candidate_center = (cx + dx, cy + dy)
|
305 |
# Check distance from already placed centers
|
306 |
if any(np.hypot(candidate_center[0] - ex, candidate_center[1] - ey) < needed_center_distance for ex, ey in existing_centers):
|
307 |
continue
|
|
|
308 |
circle_poly = Point(candidate_center).buffer(radius, resolution=64)
|
|
|
|
|
|
|
|
|
309 |
union_poly = tool_polygon.union(circle_poly)
|
|
|
|
|
|
|
|
|
310 |
overlap = False
|
311 |
-
# Check against other tool polygons for overlap or proximity issues
|
312 |
for poly in all_polygons:
|
313 |
if union_poly.intersects(poly) or circle_poly.buffer(min_gap).intersects(poly):
|
314 |
overlap = True
|
315 |
break
|
316 |
if overlap:
|
317 |
continue
|
318 |
-
#
|
319 |
existing_centers.append(candidate_center)
|
320 |
return union_poly, candidate_center
|
321 |
attempts += 1
|
@@ -411,8 +427,12 @@ def add_rectangular_boundary(doc, polygons_inch, boundary_length, boundary_width
|
|
411 |
msp.add_lwpolyline(rect_coords, close=True, dxfattribs={"layer": "BOUNDARY"})
|
412 |
|
413 |
text_top = boundary_polygon.bounds[1] + 1
|
414 |
-
if
|
415 |
-
|
|
|
|
|
|
|
|
|
416 |
|
417 |
return boundary_polygon
|
418 |
|
@@ -675,10 +695,8 @@ def predict(
|
|
675 |
text_y_img = int(processed_size[0] - (text_y_in / scaling_factor))
|
676 |
org = (text_x_img - int(len(annotation_text.strip()) * 6), text_y_img)
|
677 |
|
678 |
-
#
|
679 |
-
# Draw thicker outline
|
680 |
temp_img = np.zeros_like(output_img)
|
681 |
-
|
682 |
cv2.putText(
|
683 |
temp_img,
|
684 |
annotation_text.strip().upper(),
|
@@ -689,21 +707,18 @@ def predict(
|
|
689 |
4, # Thicker outline
|
690 |
cv2.LINE_AA
|
691 |
)
|
692 |
-
|
693 |
cv2.putText(
|
694 |
temp_img,
|
695 |
annotation_text.strip().upper(),
|
696 |
org,
|
697 |
cv2.FONT_HERSHEY_SIMPLEX,
|
698 |
2,
|
699 |
-
(0, 0, 0), # Black to create hole
|
700 |
2, # Thinner inner part
|
701 |
cv2.LINE_AA
|
702 |
)
|
703 |
-
|
704 |
outline_mask = cv2.cvtColor(temp_img, cv2.COLOR_BGR2GRAY)
|
705 |
_, outline_mask = cv2.threshold(outline_mask, 1, 255, cv2.THRESH_BINARY)
|
706 |
-
|
707 |
output_img[outline_mask > 0] = temp_img[outline_mask > 0]
|
708 |
|
709 |
cv2.putText(
|
@@ -716,7 +731,6 @@ def predict(
|
|
716 |
4, # Thicker outline
|
717 |
cv2.LINE_AA
|
718 |
)
|
719 |
-
|
720 |
cv2.putText(
|
721 |
new_outlines,
|
722 |
annotation_text.strip().upper(),
|
|
|
286 |
return []
|
287 |
return list(poly.exterior.coords)
|
288 |
|
289 |
+
def place_finger_cut_adjusted(
|
290 |
+
tool_polygon,
|
291 |
+
points_inch,
|
292 |
+
existing_centers,
|
293 |
+
all_polygons,
|
294 |
+
circle_diameter=1.0,
|
295 |
+
min_gap=0.25,
|
296 |
+
max_attempts=30
|
297 |
+
):
|
298 |
import random
|
299 |
needed_center_distance = circle_diameter + min_gap
|
300 |
radius = circle_diameter / 2.0
|
301 |
attempts = 0
|
302 |
indices = list(range(len(points_inch)))
|
303 |
+
random.shuffle(indices) # Shuffle candidate indices for randomness
|
304 |
|
305 |
for i in indices:
|
306 |
if attempts >= max_attempts:
|
307 |
break
|
308 |
cx, cy = points_inch[i]
|
309 |
+
# Try small adjustments around the candidate point
|
310 |
for dx in np.linspace(-0.1, 0.1, 5):
|
311 |
for dy in np.linspace(-0.1, 0.1, 5):
|
312 |
candidate_center = (cx + dx, cy + dy)
|
313 |
# Check distance from already placed centers
|
314 |
if any(np.hypot(candidate_center[0] - ex, candidate_center[1] - ey) < needed_center_distance for ex, ey in existing_centers):
|
315 |
continue
|
316 |
+
# Build the circle polygon
|
317 |
circle_poly = Point(candidate_center).buffer(radius, resolution=64)
|
318 |
+
# Ensure the circle actually intersects the tool polygon
|
319 |
+
if not circle_poly.intersects(tool_polygon):
|
320 |
+
continue
|
321 |
+
# Compute the union
|
322 |
union_poly = tool_polygon.union(circle_poly)
|
323 |
+
# If the union is a MultiPolygon, then the circle is not fused with the tool
|
324 |
+
if union_poly.geom_type == "MultiPolygon":
|
325 |
+
continue
|
326 |
+
# Check overlap with other tools
|
327 |
overlap = False
|
|
|
328 |
for poly in all_polygons:
|
329 |
if union_poly.intersects(poly) or circle_poly.buffer(min_gap).intersects(poly):
|
330 |
overlap = True
|
331 |
break
|
332 |
if overlap:
|
333 |
continue
|
334 |
+
# Accept candidate if all checks pass
|
335 |
existing_centers.append(candidate_center)
|
336 |
return union_poly, candidate_center
|
337 |
attempts += 1
|
|
|
427 |
msp.add_lwpolyline(rect_coords, close=True, dxfattribs={"layer": "BOUNDARY"})
|
428 |
|
429 |
text_top = boundary_polygon.bounds[1] + 1
|
430 |
+
if (annotation_text.strip()==0):
|
431 |
+
if boundary_width_in <= inner_width + 2 * clearance_side or boundary_length_in <= inner_length + 2 * clearance_tb:
|
432 |
+
raise BoundaryOverlapError("Error: The specified boundary dimensions are too small and overlap with the inner contours. Please provide larger values.")
|
433 |
+
else:
|
434 |
+
if text_top > (min_y - 0.75):
|
435 |
+
raise TextOverlapError("Error: The Text is overlapping the inner contours of the object.")
|
436 |
|
437 |
return boundary_polygon
|
438 |
|
|
|
695 |
text_y_img = int(processed_size[0] - (text_y_in / scaling_factor))
|
696 |
org = (text_x_img - int(len(annotation_text.strip()) * 6), text_y_img)
|
697 |
|
698 |
+
# Draw thicker outline using a temporary image for dual-thickness text
|
|
|
699 |
temp_img = np.zeros_like(output_img)
|
|
|
700 |
cv2.putText(
|
701 |
temp_img,
|
702 |
annotation_text.strip().upper(),
|
|
|
707 |
4, # Thicker outline
|
708 |
cv2.LINE_AA
|
709 |
)
|
|
|
710 |
cv2.putText(
|
711 |
temp_img,
|
712 |
annotation_text.strip().upper(),
|
713 |
org,
|
714 |
cv2.FONT_HERSHEY_SIMPLEX,
|
715 |
2,
|
716 |
+
(0, 0, 0), # Black to create inner hole
|
717 |
2, # Thinner inner part
|
718 |
cv2.LINE_AA
|
719 |
)
|
|
|
720 |
outline_mask = cv2.cvtColor(temp_img, cv2.COLOR_BGR2GRAY)
|
721 |
_, outline_mask = cv2.threshold(outline_mask, 1, 255, cv2.THRESH_BINARY)
|
|
|
722 |
output_img[outline_mask > 0] = temp_img[outline_mask > 0]
|
723 |
|
724 |
cv2.putText(
|
|
|
731 |
4, # Thicker outline
|
732 |
cv2.LINE_AA
|
733 |
)
|
|
|
734 |
cv2.putText(
|
735 |
new_outlines,
|
736 |
annotation_text.strip().upper(),
|