Nighty3912 commited on
Commit
bc99e62
·
verified ·
1 Parent(s): f374cdc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +137 -24
app.py CHANGED
@@ -9,6 +9,11 @@ import numpy as np
9
  import torch
10
  import cv2
11
  import ezdxf
 
 
 
 
 
12
  import gradio as gr
13
  from PIL import Image, ImageEnhance
14
  from pathlib import Path
@@ -45,6 +50,10 @@ class BoundaryOverlapError(Exception):
45
  """Raised when the optional boundary dimensions are too small and overlap with the inner contours."""
46
  pass
47
 
 
 
 
 
48
  # ---------------------
49
  # Global Model Initialization with caching and print statements
50
  # ---------------------
@@ -146,7 +155,7 @@ def yolo_detect(image: Union[str, Path, int, Image.Image, list, tuple, np.ndarra
146
 
147
  def detect_reference_square(img: np.ndarray):
148
  t = time.time()
149
- res = reference_detector_global.predict(img, conf=0.35)
150
  if not res or len(res) == 0 or len(res[0].boxes) == 0:
151
  raise ReferenceBoxNotDetectedError("Reference box not detected in the image.")
152
  print("Reference detection completed in {:.2f} seconds".format(time.time() - t))
@@ -383,8 +392,9 @@ def add_rectangular_boundary(doc, polygons_inch, boundary_length, boundary_width
383
  clearance_tb = 0.75
384
 
385
  # Check if boundary dimensions are at least larger than inner box plus clearance
386
- if boundary_width_in <= inner_width + 2 * clearance_side or boundary_length_in <= inner_length + 2 * clearance_tb:
387
- raise BoundaryOverlapError("Error: The specified boundary dimensions are too small and overlap with the inner contours. Please provide larger values.")
 
388
 
389
  # Calculate center of inner contours
390
  center_x = (min_x + max_x) / 2
@@ -400,6 +410,11 @@ def add_rectangular_boundary(doc, polygons_inch, boundary_length, boundary_width
400
  from shapely.geometry import Polygon as ShapelyPolygon
401
  boundary_polygon = ShapelyPolygon(rect_coords)
402
  msp.add_lwpolyline(rect_coords, close=True, dxfattribs={"layer": "BOUNDARY"})
 
 
 
 
 
403
  return boundary_polygon
404
 
405
  def draw_polygons_inch(polygons_inch, image_rgb, scaling_factor, image_height, color=(0,0,255), thickness=2):
@@ -618,19 +633,40 @@ def predict(
618
  # 8) Add annotation text (if provided) in the DXF
619
  # ---------------------
620
  msp = doc.modelspace()
 
621
  if annotation_text.strip():
 
622
  text_x = ((inner_min_x + inner_max_x) / 2.0) - (int(len(annotation_text.strip()) / 2.0))
623
- text_height_dxf = 0.5
624
- text_y_dxf = inner_min_y - 0.125 - text_height_dxf
625
- text_entity = msp.add_text(
626
- annotation_text.strip(),
627
- dxfattribs={
628
- "height": text_height_dxf,
629
- "layer": "ANNOTATION",
630
- "style": "Bold"
631
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
632
  )
633
- text_entity.dxf.insert = (text_x, text_y_dxf)
634
 
635
  # Save the DXF
636
  dxf_filepath = os.path.join("./outputs", "out.dxf")
@@ -643,31 +679,109 @@ def predict(
643
  new_outlines = np.ones_like(output_img) * 255
644
  draw_polygons_inch(final_polygons_inch, new_outlines, scaling_factor, processed_size[0], color=(0, 0, 255), thickness=2)
645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
646
  if annotation_text.strip():
647
- text_height_cv = 0.50
648
  text_x_img = int(((inner_min_x + inner_max_x) / 2.0) / scaling_factor)
649
- text_y_in = inner_min_y - 0.125 - text_height_cv
650
  text_y_img = int(processed_size[0] - (text_y_in / scaling_factor))
651
  org = (text_x_img - int(len(annotation_text.strip()) * 6), text_y_img)
652
 
 
 
 
 
 
 
653
  cv2.putText(
654
- output_img,
655
- annotation_text.strip(),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  org,
657
  cv2.FONT_HERSHEY_SIMPLEX,
658
- 1.2,
659
- (0, 0, 255),
660
  2,
 
 
661
  cv2.LINE_AA
662
  )
 
663
  cv2.putText(
664
  new_outlines,
665
- annotation_text.strip(),
666
  org,
667
  cv2.FONT_HERSHEY_SIMPLEX,
668
- 1.2,
669
- (0, 0, 255),
670
  2,
 
 
671
  cv2.LINE_AA
672
  )
673
 
@@ -716,5 +830,4 @@ if __name__ == "__main__":
716
  ["./Test21.jpg", 0.075, "inches", "Yes", "Yes", 300.0, 200.0, "Tool2"]
717
  ]
718
  )
719
- iface.launch(share=True)
720
-
 
9
  import torch
10
  import cv2
11
  import ezdxf
12
+ from ezdxf.addons.text2path import make_paths_from_str
13
+ from ezdxf import path
14
+ from ezdxf.addons import text2path
15
+ from ezdxf.enums import TextEntityAlignment
16
+ from ezdxf.fonts.fonts import FontFace,get_font_face
17
  import gradio as gr
18
  from PIL import Image, ImageEnhance
19
  from pathlib import Path
 
50
  """Raised when the optional boundary dimensions are too small and overlap with the inner contours."""
51
  pass
52
 
53
+ class TextOverlapError(Exception):
54
+ """Raised when the text overlaps with the inner contours (with a margin of 0.75)."""
55
+ pass
56
+
57
  # ---------------------
58
  # Global Model Initialization with caching and print statements
59
  # ---------------------
 
155
 
156
  def detect_reference_square(img: np.ndarray):
157
  t = time.time()
158
+ res = reference_detector_global.predict(img, conf=0.05)
159
  if not res or len(res) == 0 or len(res[0].boxes) == 0:
160
  raise ReferenceBoxNotDetectedError("Reference box not detected in the image.")
161
  print("Reference detection completed in {:.2f} seconds".format(time.time() - t))
 
392
  clearance_tb = 0.75
393
 
394
  # Check if boundary dimensions are at least larger than inner box plus clearance
395
+ # if boundary_width_in <= inner_width + 2 * clearance_side or boundary_length_in <= inner_length + 2 * clearance_tb:
396
+ # raise BoundaryOverlapError("Error: The specified boundary dimensions are too small and overlap with the inner contours. Please provide larger values.")
397
+
398
 
399
  # Calculate center of inner contours
400
  center_x = (min_x + max_x) / 2
 
410
  from shapely.geometry import Polygon as ShapelyPolygon
411
  boundary_polygon = ShapelyPolygon(rect_coords)
412
  msp.add_lwpolyline(rect_coords, close=True, dxfattribs={"layer": "BOUNDARY"})
413
+
414
+ text_top=boundary_polygon.bounds[1] + 1
415
+ if text_top > (min_y-0.75):
416
+ raise TextOverlapError("Error: The Text is overlapping the inner contours of the object.")
417
+
418
  return boundary_polygon
419
 
420
  def draw_polygons_inch(polygons_inch, image_rgb, scaling_factor, image_height, color=(0,0,255), thickness=2):
 
633
  # 8) Add annotation text (if provided) in the DXF
634
  # ---------------------
635
  msp = doc.modelspace()
636
+
637
  if annotation_text.strip():
638
+
639
  text_x = ((inner_min_x + inner_max_x) / 2.0) - (int(len(annotation_text.strip()) / 2.0))
640
+ text_height_dxf = 0.75
641
+ text_y_dxf = boundary_polygon.bounds[1] + 0.25 #+ text_height_dxf#inner_min_y - 0.125 - text_height_dxf
642
+ # text_entity = msp.add_text(
643
+ # annotation_text.strip().upper(),
644
+ # dxfattribs={
645
+ # "height": text_height_dxf,
646
+ # "layer": "ANNOTATION",
647
+ # "style": "Simplex",
648
+ # }
649
+ # )
650
+ # text_entity.dxf.insert = (text_x, text_y_dxf)
651
+ font = get_font_face("Arial")
652
+ paths = text2path.make_paths_from_str(
653
+ annotation_text.strip().upper(),
654
+ font=font, # Use default font
655
+ size=text_height_dxf,
656
+ align=TextEntityAlignment.LEFT
657
+ )
658
+
659
+ # Create a translation matrix
660
+ translation = ezdxf.math.Matrix44.translate(text_x, text_y_dxf, 0)
661
+ # Apply the translation to each path
662
+ translated_paths = [p.transform(translation) for p in paths]
663
+
664
+ # Render the paths as splines and polylines
665
+ path.render_splines_and_polylines(
666
+ msp,
667
+ translated_paths,
668
+ dxfattribs={"layer": "ANNOTATION", "color": 7}
669
  )
 
670
 
671
  # Save the DXF
672
  dxf_filepath = os.path.join("./outputs", "out.dxf")
 
679
  new_outlines = np.ones_like(output_img) * 255
680
  draw_polygons_inch(final_polygons_inch, new_outlines, scaling_factor, processed_size[0], color=(0, 0, 255), thickness=2)
681
 
682
+ # if annotation_text.strip():
683
+ # text_height_cv = 0.75
684
+ # text_x_img = int(((inner_min_x + inner_max_x) / 2.0) / scaling_factor)
685
+ # text_y_in = boundary_polygon.bounds[1] + 0.25 #+ text_height_cv#inner_min_y - 0.125 - text_height_cv
686
+ # text_y_img = int(processed_size[0] - (text_y_in / scaling_factor))
687
+ # org = (text_x_img - int(len(annotation_text.strip()) * 6), text_y_img)
688
+
689
+ # cv2.putText(
690
+ # output_img,
691
+ # annotation_text.strip().upper(),
692
+ # org,
693
+ # cv2.FONT_HERSHEY_SIMPLEX,
694
+ # 1.2,
695
+ # (0, 0, 255),
696
+ # 2,
697
+ # cv2.LINE_AA
698
+ # )
699
+ # cv2.putText(
700
+ # new_outlines,
701
+ # annotation_text.strip().upper(),
702
+ # org,
703
+ # cv2.FONT_HERSHEY_SIMPLEX,
704
+ # 1.2,
705
+ # (0, 0, 255),
706
+ # 2,
707
+ # cv2.LINE_AA
708
+ # )
709
  if annotation_text.strip():
710
+ text_height_cv = 0.75
711
  text_x_img = int(((inner_min_x + inner_max_x) / 2.0) / scaling_factor)
712
+ text_y_in = boundary_polygon.bounds[1] + 0.25
713
  text_y_img = int(processed_size[0] - (text_y_in / scaling_factor))
714
  org = (text_x_img - int(len(annotation_text.strip()) * 6), text_y_img)
715
 
716
+ # Method 2: Use two different thicknesses
717
+ # Draw thicker outline
718
+ # Create a clean temporary image for drawing the text outline
719
+ temp_img = np.zeros_like(output_img)
720
+
721
+ # Draw thick text on temp image
722
  cv2.putText(
723
+ temp_img,
724
+ annotation_text.strip().upper(),
725
+ org,
726
+ cv2.FONT_HERSHEY_SIMPLEX,
727
+ 2,
728
+ (0, 0, 255), # Red color
729
+ 4, # Thicker outline
730
+ cv2.LINE_AA
731
+ )
732
+
733
+ # Draw inner text in black on temp image
734
+ cv2.putText(
735
+ temp_img,
736
+ annotation_text.strip().upper(),
737
+ org,
738
+ cv2.FONT_HERSHEY_SIMPLEX,
739
+ 2,
740
+ (0, 0, 0), # Black to create hole
741
+ 2, # Thinner inner part
742
+ cv2.LINE_AA
743
+ )
744
+
745
+ # Create a mask from the temp image
746
+ outline_mask = cv2.cvtColor(temp_img, cv2.COLOR_BGR2GRAY)
747
+ _, outline_mask = cv2.threshold(outline_mask, 1, 255, cv2.THRESH_BINARY)
748
+
749
+ # Apply only the red channel from the temp image to the output image
750
+ # This preserves the original background where the outline isn't
751
+ output_img[outline_mask > 0] = temp_img[outline_mask > 0]
752
+
753
+ # Draw inner part with background color
754
+ # cv2.putText(
755
+ # output_img,
756
+ # annotation_text.strip().upper(),
757
+ # org,
758
+ # cv2.FONT_HERSHEY_SIMPLEX,
759
+ # 2,
760
+ # (255, 255, 255), # Assuming black background, adjust as needed
761
+ # 2, # Thinner inner part
762
+ # cv2.LINE_AA
763
+ # )
764
+
765
+ # Do the same for new_outlines
766
+ cv2.putText(
767
+ new_outlines,
768
+ annotation_text.strip().upper(),
769
  org,
770
  cv2.FONT_HERSHEY_SIMPLEX,
 
 
771
  2,
772
+ (0, 0, 255), # Red color
773
+ 4, # Thicker outline
774
  cv2.LINE_AA
775
  )
776
+
777
  cv2.putText(
778
  new_outlines,
779
+ annotation_text.strip().upper(),
780
  org,
781
  cv2.FONT_HERSHEY_SIMPLEX,
 
 
782
  2,
783
+ (255, 255, 255), # Assuming black background, adjust as needed
784
+ 2, # Thinner inner part
785
  cv2.LINE_AA
786
  )
787
 
 
830
  ["./Test21.jpg", 0.075, "inches", "Yes", "Yes", 300.0, 200.0, "Tool2"]
831
  ]
832
  )
833
+ iface.launch(share=True)