WizardForest commited on
Commit
78ff8a8
·
verified ·
1 Parent(s): eb5438b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -11
app.py CHANGED
@@ -1,28 +1,82 @@
1
  import gradio as gr
2
  from ultralytics import YOLO
 
 
 
3
 
4
  model = YOLO("model.pt")
5
 
6
- def predict(img):
7
  path = img.split("\\")[-1].split(".")[0]
8
  print("path", path)
9
 
10
  results = model.predict(source=img, save=False, show_labels=False, show_conf=False)
11
-
12
- # Handle both single result and list of results
13
  if not isinstance(results, (list, tuple)):
14
  results = [results]
15
-
16
  count = 0
17
  annot_img = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  for i in results:
19
  count = len(i.boxes)
20
- annot_img = i.plot(labels=False, masks=False)
21
- # Convert BGR to RGB if needed
22
- if annot_img.shape[-1] == 3: # Check if image has 3 channels
23
- annot_img = annot_img[..., ::-1] # Reverse the color channels
24
-
25
- return str(count), annot_img
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
  # 自定義 CSS 樣式(背景改為白色、簡潔風格)
28
  custom_css = """
@@ -166,6 +220,34 @@ with gr.Blocks(
166
  )
167
  gr.HTML('</div><div style="text-align:center; margin-top:8px; color:#888;">支援 JPG/PNG,建議 640×640 以上</div>')
168
  gr.HTML('</div>')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
  with gr.Column(scale=1):
171
 
@@ -179,6 +261,11 @@ with gr.Blocks(
179
  type="numpy",
180
  elem_classes=["result-image"]
181
  )
 
 
 
 
 
182
  gr.HTML('</div>')
183
 
184
  gr.HTML("""
@@ -192,7 +279,11 @@ with gr.Blocks(
192
  </div>
193
  """)
194
 
195
- button.click(fn=predict, inputs=img, outputs=[data_output, img_output])
 
 
 
 
196
 
197
  if __name__ == "__main__":
198
  demo.launch()
 
1
  import gradio as gr
2
  from ultralytics import YOLO
3
+ from PIL import Image, ImageDraw, ImageFont
4
+ import numpy as np
5
+
6
 
7
  model = YOLO("model.pt")
8
 
9
+ def predict(img, dot_color, text_color_choice, dot_size, font_size):
10
  path = img.split("\\")[-1].split(".")[0]
11
  print("path", path)
12
 
13
  results = model.predict(source=img, save=False, show_labels=False, show_conf=False)
14
+
 
15
  if not isinstance(results, (list, tuple)):
16
  results = [results]
17
+
18
  count = 0
19
  annot_img = None
20
+ annot_img_numbered = None
21
+
22
+ # 轉換顏色文字為 RGB
23
+ if dot_color == "紅色":
24
+ dot_rgb = (255, 0, 0)
25
+ else:
26
+ dot_rgb = (57, 255, 20) # 螢光綠
27
+
28
+ if text_color_choice == "黑色":
29
+ text_rgb = (0, 0, 0)
30
+ else:
31
+ text_rgb = (255, 255, 255)
32
+
33
+ # 檢查輸入的大小是否合理
34
+ try:
35
+ r = int(dot_size)
36
+ except:
37
+ r = 10
38
+ if r < 2: r = 2
39
+
40
+ try:
41
+ fsize = int(font_size)
42
+ except:
43
+ fsize = 36
44
+ if fsize < 8: fsize = 8
45
+
46
  for i in results:
47
  count = len(i.boxes)
48
+ img_pil = Image.fromarray(i.orig_img[..., ::-1]) # BGR → RGB
49
+ img_pil_numbered = img_pil.copy()
50
+
51
+ draw = ImageDraw.Draw(img_pil)
52
+ draw_num = ImageDraw.Draw(img_pil_numbered)
53
+
54
+ # 載入字體(若無 Arial 則 fallback)
55
+ try:
56
+ font = ImageFont.truetype("arial.ttf", fsize)
57
+ except:
58
+ font = ImageFont.load_default()
59
+
60
+ for idx, box in enumerate(i.boxes.xyxy, start=1):
61
+ x1, y1, x2, y2 = box[:4].tolist()
62
+ cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
63
+
64
+ # -------- 第一張(只有圓點)--------
65
+ draw.ellipse((cx - r, cy - r, cx + r, cy + r), fill=dot_rgb, outline=None)
66
+
67
+ # -------- 第二張(圓點 + 編號)--------
68
+ draw_num.ellipse((cx - r, cy - r, cx + r, cy + r), fill=dot_rgb, outline=None)
69
+
70
+ # 最後一顆用紅字,其餘依使用者設定
71
+ num_color = (255, 0, 0) if idx == count else text_rgb
72
+
73
+ # 在圓點右上方標註數字
74
+ draw_num.text((cx + r + 4, cy - r), str(idx), fill=num_color, font=font)
75
+
76
+ annot_img = np.array(img_pil)
77
+ annot_img_numbered = np.array(img_pil_numbered)
78
+
79
+ return str(count), annot_img, annot_img_numbered
80
 
81
  # 自定義 CSS 樣式(背景改為白色、簡潔風格)
82
  custom_css = """
 
220
  )
221
  gr.HTML('</div><div style="text-align:center; margin-top:8px; color:#888;">支援 JPG/PNG,建議 640×640 以上</div>')
222
  gr.HTML('</div>')
223
+ dot_color = gr.Radio(
224
+ choices=["紅色", "螢光綠"],
225
+ value="紅色",
226
+ label="圓點顏色",
227
+ info="選擇藥錠中心圓點顏色"
228
+ )
229
+
230
+ text_color_choice = gr.Radio(
231
+ choices=["黑色", "白色"],
232
+ value="黑色",
233
+ label="文字顏色",
234
+ info="選擇編號文字顏色"
235
+ )
236
+
237
+ dot_size = gr.Textbox(
238
+ label="圓點大小",
239
+ value="10",
240
+ info="設定圓點半徑大小(建議範圍 5~20)"
241
+ )
242
+
243
+ font_size = gr.Textbox(
244
+ label="字體大小",
245
+ value="36",
246
+ info="設定編號文字大小(建議範圍 20~60)"
247
+ )
248
+
249
+
250
+
251
 
252
  with gr.Column(scale=1):
253
 
 
261
  type="numpy",
262
  elem_classes=["result-image"]
263
  )
264
+ gr.HTML('<div style="text-align:center; margin:20px 0;"><label style="font-size:14px;color:#555;">標註 + 編號結果</label></div>')
265
+ img_output_numbered = gr.Image(
266
+ type="numpy",
267
+ elem_classes=["result-image"]
268
+ )
269
  gr.HTML('</div>')
270
 
271
  gr.HTML("""
 
279
  </div>
280
  """)
281
 
282
+ button.click(
283
+ fn=predict,
284
+ inputs=[img, dot_color, text_color_choice, dot_size, font_size],
285
+ outputs=[data_output, img_output, img_output_numbered]
286
+ )
287
 
288
  if __name__ == "__main__":
289
  demo.launch()