TS447 commited on
Commit
12c2b5f
Β·
verified Β·
1 Parent(s): ead23ff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -74
app.py CHANGED
@@ -4,71 +4,52 @@ import numpy as np
4
  from PIL import Image, ImageOps
5
  import subprocess
6
 
7
- # --- 1. The Core Logic (CNC Brain V3 - Final Polish) ---
8
- def process_vector(image, mode, fill_gaps, thickness, smooth_factor):
9
  if image is None: return None, None
10
 
11
- # A. Pre-processing (Convert to Grayscale)
12
  img_np = np.array(image.convert("RGB"))
13
  gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
14
-
15
- # --- THE NEW MAGIC STEP: Smart Smoothing ---
16
- # Bilateral Filter: Ye noise hatata hai par edges ko sharp rakhta hai.
17
- # Real photos ke liye ye sabse zaroori hai.
18
- gray_blurred = cv2.bilateralFilter(gray, 9, 75, 75)
19
-
20
- # B. TRACING MODES (Improved)
21
- if mode == "1. Adaptive Scanner (Best for most photos)":
22
- # Ye lighting variations ko handle karta hai.
23
- # Block size 11, C 2 (Standard settings for clean scan)
24
- binary = cv2.adaptiveThreshold(gray_blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
25
- cv2.THRESH_BINARY_INV, 11, 2)
26
 
27
- elif mode == "2. Silhouette / Backlit (Dark Jali, Bright Back)":
28
- # Agar jali kaali dikh rahi hai aur peeche light hai.
29
- # Simple hard threshold. Value 100 se neeche sab black.
30
- _, binary = cv2.threshold(gray_blurred, 100, 255, cv2.THRESH_BINARY_INV)
31
-
32
- elif mode == "3. Solid Graphic (Perfect B&W Image)":
33
- # Agar pehle se hi saaf graphic image hai.
34
- _, binary = cv2.threshold(gray_blurred, 128, 255, cv2.THRESH_BINARY_INV)
35
 
36
- # C. POST-PROCESSING (Filling and Cleaning)
 
 
 
 
 
37
  kernel = np.ones((3,3), np.uint8)
 
 
 
 
 
 
38
 
39
- # Step C1: Fill Gaps (Agar Jali toot rahi hai ya khokhli aa rahi hai)
40
- if fill_gaps:
41
- # Morphological CLOSE: Dilate then Erode. Fills small holes inside black areas.
42
- binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=1)
43
- # Thoda sa aur bharo taaki solid lage
44
- binary = cv2.dilate(binary, kernel, iterations=1)
45
 
46
- # Step C2: Thickness Adjustment (User Controlled)
47
- if thickness > 0:
48
- # Dilate: Makes design thicker
49
- binary = cv2.dilate(binary, kernel, iterations=int(thickness))
50
- elif thickness < 0:
51
- # Erode: Makes design thinner
52
- binary = cv2.erode(binary, kernel, iterations=abs(int(thickness)))
53
 
54
- # D. Save Temp BMP for Potrace
55
  temp_bmp = "temp_trace.bmp"
56
- # Ensure it's pure black and white for Potrace
57
- (thresh, binary_final) = cv2.threshold(binary, 128, 255, cv2.THRESH_BINARY)
58
- cv2.imwrite(temp_bmp, binary_final)
59
 
60
- # E. Vectorize using Potrace
61
- output_svg = "ts_vector_design.svg"
62
 
63
- # Potrace Commands
64
- # -t 5: Thoda noise ignore karega
65
- # --longcurve: CNC ke liye lambi smooth lines banane ki koshish karega
66
  cmd = [
67
  "potrace", temp_bmp,
68
  "-s", "-o", output_svg,
69
- "-t", "5",
70
  "-a", str(smooth_factor),
71
- "--longcurve",
72
  "--opaque"
73
  ]
74
 
@@ -78,46 +59,40 @@ def process_vector(image, mode, fill_gaps, thickness, smooth_factor):
78
  print(f"Error: {e}")
79
  return None, None
80
 
81
- # Return SVG and the B&W Preview (Invert preview for better visualization if needed)
82
- return output_svg, Image.fromarray(binary_final)
83
 
84
- # --- 2. Interface Design ---
85
  custom_css = """
86
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;900&display=swap');
87
- body, .gradio-container { font-family: 'Inter', sans-serif !important; background: #1e1e2e !important; color: white !important; }
88
- #main_card { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 20px; padding: 30px; }
89
- .primary-btn { background: linear-gradient(90deg, #FF9966, #FF5E62) !important; color: white !important; border: none !important; font-size: 1.2rem !important; font-weight: bold !important; }
90
- .svelte-1g805jl img { border: 1px solid #FF9966; } /* Orange border on preview */
91
  """
92
 
93
- with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as app:
94
  with gr.Column(elem_id="main_card"):
95
- gr.Markdown("# πŸ“ TS VECTOR MASTER", elem_id="logo_text")
96
- gr.Markdown("### Professional CNC Tracer for Real Photos")
97
-
98
- gr.Markdown("ℹ️ **Pro Tip:** Best results come from photos taken straight-on (flat), not at an angle.")
99
 
100
  with gr.Row():
101
  with gr.Column():
102
- inp_img = gr.Image(type="pil", label="Upload Jali Photo", height=300)
103
 
104
- gr.Markdown("### πŸŽ›οΈ Fine-Tune Result")
105
- mode_drp = gr.Dropdown(
106
- ["1. Adaptive Scanner (Best for most photos)", "2. Silhouette / Backlit (Dark Jali, Bright Back)", "3. Solid Graphic (Perfect B&W Image)"],
107
- value="1. Adaptive Scanner (Best for most photos)",
108
- label="Tracing Mode"
109
- )
110
 
111
- fill_chk = gr.Checkbox(label="Fill Gaps & Holes (Agar design toot raha ho)", value=True)
112
- thick_sld = gr.Slider(-2, 4, value=0, step=1, label="Thickness Adjustment")
113
- smooth_sld = gr.Slider(0, 1.3, value=1.0, label="Corner Smoothing")
 
 
114
 
115
- btn = gr.Button("πŸš€ TRACE IT!", variant="primary", elem_classes=["primary-btn"])
116
 
117
  with gr.Column():
118
- preview_img = gr.Image(label="AI Vision Preview (Check quality here)", interactive=False)
119
- out_file = gr.File(label="Download Finished Vector (.SVG)")
 
120
 
121
- btn.click(process_vector, inputs=[inp_img, mode_drp, fill_chk, thick_sld, smooth_sld], outputs=[out_file, preview_img])
122
 
123
  app.launch()
 
4
  from PIL import Image, ImageOps
5
  import subprocess
6
 
7
+ # --- 1. CNC BRAIN V4 (Solid Shape Logic) ---
8
+ def process_vector(image, threshold_val, solidify_strength, smooth_factor, remove_noise):
9
  if image is None: return None, None
10
 
11
+ # Step A: Convert to Grayscale & Blur (Shine hatane ke liye)
12
  img_np = np.array(image.convert("RGB"))
13
  gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ # Strong Blur to mix Gold Highlight and Shadow
16
+ gray_blurred = cv2.GaussianBlur(gray, (5, 5), 0)
 
 
 
 
 
 
17
 
18
+ # Step B: Thresholding (Solid Black logic)
19
+ # Binary Inverse: Jali banegi WHITE, Background banega BLACK (Processing ke liye)
20
+ _, binary = cv2.threshold(gray_blurred, threshold_val, 255, cv2.THRESH_BINARY_INV)
21
+
22
+ # Step C: SOLIDIFY (Ye hai wo magic fix)
23
+ # Agar line double aa rahi hai, to hum usse "Dilate" (failayenge) taaki wo jud jaye
24
  kernel = np.ones((3,3), np.uint8)
25
+
26
+ if solidify_strength > 0:
27
+ # Dilate: White hissa (Jali) mota hoga aur beech ke holes bharenge
28
+ binary = cv2.dilate(binary, kernel, iterations=int(solidify_strength))
29
+ # Wapas thoda shape mein laane ke liye halka erode (Optional, balancing)
30
+ binary = cv2.erode(binary, kernel, iterations=1)
31
 
32
+ # Step D: Noise Removal (Watermark ke chote daane hatana)
33
+ if remove_noise:
34
+ # Morph Open: Chote white dots (noise) gayab karega
35
+ binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=1)
 
 
36
 
37
+ # Step E: Invert for Potrace (Potrace needs Black Shape on White)
38
+ # Ab Jali Black ho jayegi, Background White
39
+ final_binary = cv2.bitwise_not(binary)
 
 
 
 
40
 
41
+ # Save Temp
42
  temp_bmp = "temp_trace.bmp"
43
+ cv2.imwrite(temp_bmp, final_binary)
 
 
44
 
45
+ # Step F: Vectorize
46
+ output_svg = "ts_vector_solid.svg"
47
 
 
 
 
48
  cmd = [
49
  "potrace", temp_bmp,
50
  "-s", "-o", output_svg,
51
+ "-t", "10", # Despeckle level (ignore small text parts)
52
  "-a", str(smooth_factor),
 
53
  "--opaque"
54
  ]
55
 
 
59
  print(f"Error: {e}")
60
  return None, None
61
 
62
+ # Preview Image (Hum user ko wahi dikhayenge jo Potrace ne dekha)
63
+ return output_svg, Image.fromarray(final_binary)
64
 
65
+ # --- 2. Interface ---
66
  custom_css = """
67
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;900&display=swap');
68
+ body, .gradio-container { font-family: 'Inter', sans-serif !important; background: #000000 !important; color: white !important; }
69
+ #main_card { border: 1px solid #333; border-radius: 15px; padding: 20px; background: #111; }
70
+ .primary-btn { background: #FFD700 !important; color: black !important; font-weight: bold !important; }
 
71
  """
72
 
73
+ with gr.Blocks(css=custom_css, theme=gr.themes.Base(mode='dark')) as app:
74
  with gr.Column(elem_id="main_card"):
75
+ gr.Markdown("# πŸ† TS SOLID TRACER", elem_id="logo_text")
 
 
 
76
 
77
  with gr.Row():
78
  with gr.Column():
79
+ inp_img = gr.Image(type="pil", label="Upload Photo", height=300)
80
 
81
+ gr.Markdown("### πŸŽ›οΈ Settings (Adjust to fix double lines)")
 
 
 
 
 
82
 
83
+ # Controls optimized for the specific problem
84
+ thresh_sld = gr.Slider(0, 255, value=140, step=1, label="1. Darkness Threshold (Kam=Light gayab, Zyada=Sab Black)")
85
+ solid_sld = gr.Slider(0, 5, value=2, step=1, label="2. Solidify (Double Line Jodne ke liye badhao)")
86
+ noise_chk = gr.Checkbox(label="3. Clean Noise (Watermark dots hataye)", value=True)
87
+ smooth_sld = gr.Slider(0, 1.3, value=1.0, label="4. Smoothing")
88
 
89
+ btn = gr.Button("πŸ”₯ CREATE SOLID VECTOR", variant="primary", elem_classes=["primary-btn"])
90
 
91
  with gr.Column():
92
+ # Preview ab bohot important hai
93
+ preview_img = gr.Image(label="Computer Vision (Isse check karo)", interactive=False)
94
+ out_file = gr.File(label="Download SVG")
95
 
96
+ btn.click(process_vector, inputs=[inp_img, thresh_sld, solid_sld, smooth_sld, noise_chk], outputs=[out_file, preview_img])
97
 
98
  app.launch()