DawnC commited on
Commit
d7ed8db
1 Parent(s): aff8ba5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +187 -28
app.py CHANGED
@@ -243,6 +243,93 @@ async def process_single_dog(image):
243
  return breeds_info, image, initial_state
244
 
245
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  async def predict(image):
247
  if image is None:
248
  return "Please upload an image to start.", None, None
@@ -252,63 +339,135 @@ async def predict(image):
252
  image = Image.fromarray(image)
253
 
254
  dogs = await detect_multiple_dogs(image)
255
- color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
 
256
  annotated_image = image.copy()
257
  draw = ImageDraw.Draw(annotated_image)
258
- font = ImageFont.load_default()
 
 
 
 
 
259
 
260
  dogs_info = ""
261
 
262
  for i, (cropped_image, detection_confidence, box) in enumerate(dogs):
263
  color = color_list[i % len(color_list)]
264
- draw.rectangle(box, outline=color, width=3)
265
- draw.text((box[0] + 5, box[1] + 5), f"Dog {i+1}", fill=color, font=font)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
 
267
  top1_prob, topk_breeds, relative_probs = await predict_single_dog(cropped_image)
268
  combined_confidence = detection_confidence * top1_prob
269
 
270
- dogs_info += f'<div class="dog-info" style="border-left: 5px solid {color}; margin-bottom: 20px; padding: 15px;">'
271
- dogs_info += f'<h2>Dog {i+1}</h2>'
 
 
 
 
 
272
 
273
- if combined_confidence < 0.2:
274
- dogs_info += "<p>The image is unclear or the breed is not in the dataset. Please upload a clearer image.</p>"
275
-
 
 
 
276
  elif top1_prob >= 0.45:
277
  breed = topk_breeds[0]
278
  description = get_dog_description(breed)
279
- dogs_info += format_description_html(description, breed)
280
-
 
 
 
 
 
 
281
  else:
282
  dogs_info += "<h3>Top 3 possible breeds:</h3>"
283
  for breed, prob in zip(topk_breeds, relative_probs):
284
  description = get_dog_description(breed)
285
- dogs_info += f"<div class='breed-section'>"
286
- dogs_info += f"<h4>{breed} (Confidence: {prob})</h4>"
287
- dogs_info += format_description_html(description, breed)
288
- dogs_info += "</div>"
 
 
 
 
289
 
290
  dogs_info += '</div>'
291
 
 
292
  html_output = f"""
293
  <style>
294
- .dog-info {{
295
  border: 1px solid #ddd;
296
- margin-bottom: 20px;
297
- padding: 15px;
298
- border-radius: 5px;
299
- box-shadow: 0 2px 5px rgba(0,0,0,0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  }}
301
- .dog-info h2 {{
302
- background-color: #f0f0f0;
303
- padding: 10px;
304
- margin: -15px -15px 15px -15px;
305
- border-radius: 5px 5px 0 0;
306
  }}
 
307
  .breed-section {{
308
- margin-bottom: 20px;
309
- padding: 10px;
310
  background-color: #f8f8f8;
311
- border-radius: 5px;
 
 
 
 
 
 
 
 
 
 
 
 
312
  }}
313
  </style>
314
  {dogs_info}
 
243
  return breeds_info, image, initial_state
244
 
245
 
246
+ # async def predict(image):
247
+ # if image is None:
248
+ # return "Please upload an image to start.", None, None
249
+
250
+ # try:
251
+ # if isinstance(image, np.ndarray):
252
+ # image = Image.fromarray(image)
253
+
254
+ # dogs = await detect_multiple_dogs(image)
255
+ # color_list = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#800080', '#FFA500']
256
+ # annotated_image = image.copy()
257
+ # draw = ImageDraw.Draw(annotated_image)
258
+ # font = ImageFont.load_default()
259
+
260
+ # dogs_info = ""
261
+
262
+ # for i, (cropped_image, detection_confidence, box) in enumerate(dogs):
263
+ # color = color_list[i % len(color_list)]
264
+ # draw.rectangle(box, outline=color, width=3)
265
+ # draw.text((box[0] + 5, box[1] + 5), f"Dog {i+1}", fill=color, font=font)
266
+
267
+ # top1_prob, topk_breeds, relative_probs = await predict_single_dog(cropped_image)
268
+ # combined_confidence = detection_confidence * top1_prob
269
+
270
+ # dogs_info += f'<div class="dog-info" style="border-left: 5px solid {color}; margin-bottom: 20px; padding: 15px;">'
271
+ # dogs_info += f'<h2>Dog {i+1}</h2>'
272
+
273
+ # if combined_confidence < 0.2:
274
+ # dogs_info += "<p>The image is unclear or the breed is not in the dataset. Please upload a clearer image.</p>"
275
+
276
+ # elif top1_prob >= 0.45:
277
+ # breed = topk_breeds[0]
278
+ # description = get_dog_description(breed)
279
+ # dogs_info += format_description_html(description, breed)
280
+
281
+ # else:
282
+ # dogs_info += "<h3>Top 3 possible breeds:</h3>"
283
+ # for breed, prob in zip(topk_breeds, relative_probs):
284
+ # description = get_dog_description(breed)
285
+ # dogs_info += f"<div class='breed-section'>"
286
+ # dogs_info += f"<h4>{breed} (Confidence: {prob})</h4>"
287
+ # dogs_info += format_description_html(description, breed)
288
+ # dogs_info += "</div>"
289
+
290
+ # dogs_info += '</div>'
291
+
292
+ # html_output = f"""
293
+ # <style>
294
+ # .dog-info {{
295
+ # border: 1px solid #ddd;
296
+ # margin-bottom: 20px;
297
+ # padding: 15px;
298
+ # border-radius: 5px;
299
+ # box-shadow: 0 2px 5px rgba(0,0,0,0.1);
300
+ # }}
301
+ # .dog-info h2 {{
302
+ # background-color: #f0f0f0;
303
+ # padding: 10px;
304
+ # margin: -15px -15px 15px -15px;
305
+ # border-radius: 5px 5px 0 0;
306
+ # }}
307
+ # .breed-section {{
308
+ # margin-bottom: 20px;
309
+ # padding: 10px;
310
+ # background-color: #f8f8f8;
311
+ # border-radius: 5px;
312
+ # }}
313
+ # </style>
314
+ # {dogs_info}
315
+ # """
316
+
317
+ # initial_state = {
318
+ # "dogs_info": dogs_info,
319
+ # "image": annotated_image,
320
+ # "is_multi_dog": len(dogs) > 1,
321
+ # "html_output": html_output
322
+ # }
323
+
324
+ # return html_output, annotated_image, initial_state
325
+
326
+ # except Exception as e:
327
+ # error_msg = f"An error occurred: {str(e)}\n\nTraceback:\n{traceback.format_exc()}"
328
+ # print(error_msg)
329
+ # return error_msg, None, None
330
+
331
+
332
+
333
  async def predict(image):
334
  if image is None:
335
  return "Please upload an image to start.", None, None
 
339
  image = Image.fromarray(image)
340
 
341
  dogs = await detect_multiple_dogs(image)
342
+ # 更新為更容易區分的顏色組合
343
+ color_list = ['#FF3B30', '#34C759', '#007AFF', '#FF9500', '#5856D6', '#FF2D55', '#5AC8FA', '#FFCC00']
344
  annotated_image = image.copy()
345
  draw = ImageDraw.Draw(annotated_image)
346
+
347
+ # 改用更大的字體,提升可讀性
348
+ try:
349
+ font = ImageFont.truetype("arial.ttf", 24) # 優先使用 Arial
350
+ except:
351
+ font = ImageFont.load_default()
352
 
353
  dogs_info = ""
354
 
355
  for i, (cropped_image, detection_confidence, box) in enumerate(dogs):
356
  color = color_list[i % len(color_list)]
357
+
358
+ # 增強框線可見度
359
+ draw.rectangle(box, outline=color, width=4)
360
+
361
+ # 優化標籤背景
362
+ label = f"Dog {i+1}"
363
+ label_bbox = draw.textbbox((0, 0), label, font=font)
364
+ label_width = label_bbox[2] - label_bbox[0]
365
+ label_height = label_bbox[3] - label_bbox[1]
366
+
367
+ # 添���標籤背景
368
+ label_x = box[0] + 5
369
+ label_y = box[1] + 5
370
+ draw.rectangle(
371
+ [label_x - 2, label_y - 2, label_x + label_width + 4, label_y + label_height + 4],
372
+ fill='white',
373
+ outline=color,
374
+ width=2
375
+ )
376
+ draw.text((label_x, label_y), label, fill=color, font=font)
377
 
378
  top1_prob, topk_breeds, relative_probs = await predict_single_dog(cropped_image)
379
  combined_confidence = detection_confidence * top1_prob
380
 
381
+ # 優化資訊卡片樣式
382
+ dogs_info += f'''
383
+ <div class="dog-info-card" style="border-left: 6px solid {color};">
384
+ <div class="dog-info-header" style="background-color: {color}20;">
385
+ <span class="dog-label" style="color: {color};">Dog {i+1}</span>
386
+ </div>
387
+ '''
388
 
389
+ if combined_confidence < 0.15:
390
+ dogs_info += '''
391
+ <div class="warning-message">
392
+ <p>The image is unclear or the breed is not in the dataset. Please upload a clearer image.</p>
393
+ </div>
394
+ '''
395
  elif top1_prob >= 0.45:
396
  breed = topk_breeds[0]
397
  description = get_dog_description(breed)
398
+ dogs_info += f'''
399
+ <div class="breed-info">
400
+ <div class="confidence-score" style="color: {color};">
401
+ {breed} (Confidence: {relative_probs[0]})
402
+ </div>
403
+ {format_description_html(description, breed)}
404
+ </div>
405
+ '''
406
  else:
407
  dogs_info += "<h3>Top 3 possible breeds:</h3>"
408
  for breed, prob in zip(topk_breeds, relative_probs):
409
  description = get_dog_description(breed)
410
+ dogs_info += f'''
411
+ <div class="breed-section">
412
+ <div class="confidence-score" style="color: {color};">
413
+ {breed} (Confidence: {prob})
414
+ </div>
415
+ {format_description_html(description, breed)}
416
+ </div>
417
+ '''
418
 
419
  dogs_info += '</div>'
420
 
421
+ # 更新 CSS 樣式
422
  html_output = f"""
423
  <style>
424
+ .dog-info-card {{
425
  border: 1px solid #ddd;
426
+ margin-bottom: 24px;
427
+ padding: 0;
428
+ border-radius: 8px;
429
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
430
+ overflow: hidden;
431
+ transition: all 0.3s ease;
432
+ }}
433
+
434
+ .dog-info-card:hover {{
435
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
436
+ }}
437
+
438
+ .dog-info-header {{
439
+ padding: 16px 20px;
440
+ margin: 0;
441
+ font-size: 20px;
442
+ font-weight: bold;
443
+ }}
444
+
445
+ .dog-label {{
446
+ font-size: 18px;
447
+ font-weight: bold;
448
  }}
449
+
450
+ .breed-info {{
451
+ padding: 20px;
 
 
452
  }}
453
+
454
  .breed-section {{
455
+ margin: 20px;
456
+ padding: 16px;
457
  background-color: #f8f8f8;
458
+ border-radius: 6px;
459
+ }}
460
+
461
+ .confidence-score {{
462
+ font-size: 18px;
463
+ font-weight: bold;
464
+ margin-bottom: 12px;
465
+ }}
466
+
467
+ .warning-message {{
468
+ padding: 16px 20px;
469
+ color: #ff3b30;
470
+ font-weight: bold;
471
  }}
472
  </style>
473
  {dogs_info}