Spaces:
Sleeping
Sleeping
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(),
|