DawnC commited on
Commit
f8d361b
1 Parent(s): 65b44b5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +233 -120
app.py CHANGED
@@ -252,63 +252,159 @@ async def process_single_dog(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}
@@ -339,10 +435,12 @@ async def predict(image):
339
  image = Image.fromarray(image)
340
 
341
  dogs = await detect_multiple_dogs(image)
342
- color_list = ['#FF3B30', '#34C759', '#007AFF', '#FF9500', '#5856D6', '#FF2D55', '#5AC8FA', '#FFCC00']
 
 
343
  annotated_image = image.copy()
344
  draw = ImageDraw.Draw(annotated_image)
345
-
346
  try:
347
  font = ImageFont.truetype("arial.ttf", 24)
348
  except:
@@ -351,34 +449,14 @@ async def predict(image):
351
  dogs_info = ""
352
 
353
  for i, (cropped_image, detection_confidence, box) in enumerate(dogs):
354
- color = color_list[i % len(color_list)]
355
-
356
- # 優化圖片上的標記
357
- draw.rectangle(box, outline=color, width=4)
358
- label = f"Dog {i+1}"
359
- label_bbox = draw.textbbox((0, 0), label, font=font)
360
- label_width = label_bbox[2] - label_bbox[0]
361
- label_height = label_bbox[3] - label_bbox[1]
362
-
363
- label_x = box[0] + 5
364
- label_y = box[1] + 5
365
- draw.rectangle(
366
- [label_x - 2, label_y - 2, label_x + label_width + 4, label_y + label_height + 4],
367
- fill='white',
368
- outline=color,
369
- width=2
370
- )
371
- draw.text((label_x, label_y), label, fill=color, font=font)
372
-
373
- top1_prob, topk_breeds, relative_probs = await predict_single_dog(cropped_image)
374
- combined_confidence = detection_confidence * top1_prob
375
-
376
- # 開始資訊卡片
377
- dogs_info += f'<div class="dog-info-card" style="border-left: 6px solid {color};">'
378
 
 
 
379
  if combined_confidence < 0.15:
380
  dogs_info += f'''
381
- <div class="dog-info-header" style="background-color: {color}20;">
382
  <span class="dog-label" style="color: {color};">Dog {i+1}</span>
383
  </div>
384
  <div class="breed-info">
@@ -389,108 +467,142 @@ async def predict(image):
389
  breed = topk_breeds[0]
390
  description = get_dog_description(breed)
391
  dogs_info += f'''
392
- <div class="dog-info-header" style="background-color: {color}20;">
393
  <span class="dog-label" style="color: {color};">{breed}</span>
394
  </div>
395
  <div class="breed-info">
396
- {format_description_html(description, breed)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
397
  </div>
398
  '''
399
  else:
400
- dogs_info += f'''
401
- <div class="dog-info-header" style="background-color: {color}20;">
402
- <span class="dog-label" style="color: {color};">Dog {i+1}</span>
403
- </div>
404
- <div class="breed-info">
405
- <div class="model-uncertainty-note">
406
- Note: The model is showing some uncertainty in its predictions.
407
- Here are the most likely breeds based on the available visual features.
408
- </div>
409
- <h3 class="breeds-title">Top 3 possible breeds:</h3>
410
- '''
411
-
412
- for j, (breed, prob) in enumerate(zip(topk_breeds, relative_probs)):
413
- description = get_dog_description(breed)
414
- dogs_info += f'''
415
- <div class="breed-section">
416
- <div class="confidence-score" style="color: {color};">{breed} (Confidence: {prob})</div>
417
- <div class="breed-info-content">
418
- {format_description_html(description, breed)}
419
- </div>
420
- </div>
421
- '''
422
- dogs_info += '</div>'
423
-
424
- dogs_info += '</div>'
425
 
426
  html_output = f"""
427
  <style>
428
  .dog-info-card {{
429
- border: 1px solid #ddd;
430
- margin-bottom: 24px;
431
  padding: 0;
432
- border-radius: 8px;
433
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
434
  overflow: hidden;
435
  transition: all 0.3s ease;
436
  }}
437
 
438
  .dog-info-card:hover {{
439
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
440
  }}
441
 
442
  .dog-info-header {{
443
- padding: 16px 20px;
444
  margin: 0;
445
- font-size: 20px;
446
  font-weight: bold;
 
447
  }}
448
 
449
- .dog-label {{
450
- font-size: 18px;
451
- font-weight: bold;
452
  }}
453
 
454
- .breed-info {{
455
- padding: 20px;
456
  }}
457
 
458
- .breeds-title {{
459
- margin: 0 0 16px 0;
460
- font-size: 18px;
461
- color: #333;
 
 
 
462
  }}
463
 
464
- .breed-section {{
465
- margin: 16px 0;
466
- padding: 16px;
467
- background-color: #f8f8f8;
 
 
 
 
 
468
  border-radius: 6px;
 
469
  }}
470
 
471
- .confidence-score {{
472
- font-size: 18px;
473
- font-weight: bold;
474
- margin-bottom: 12px;
475
  }}
476
 
477
- .breed-info-content {{
478
- margin-top: 8px;
 
479
  }}
480
 
481
- .warning-message {{
482
- color: #ff3b30;
483
- font-weight: bold;
484
- margin: 0;
485
  }}
486
-
487
- ul {{
488
- padding-left: 0;
489
- margin: 0;
 
490
  }}
491
 
492
- li {{
493
- margin-bottom: 8px;
 
 
 
 
 
 
 
 
 
 
494
  }}
495
  </style>
496
  {dogs_info}
@@ -511,6 +623,7 @@ async def predict(image):
511
  return error_msg, None, None
512
 
513
 
 
514
  def show_details_html(choice, previous_output, initial_state):
515
  if not choice:
516
  return previous_output, gr.update(visible=True), initial_state
 
252
  # image = Image.fromarray(image)
253
 
254
  # dogs = await detect_multiple_dogs(image)
255
+ # color_list = ['#FF3B30', '#34C759', '#007AFF', '#FF9500', '#5856D6', '#FF2D55', '#5AC8FA', '#FFCC00']
256
  # annotated_image = image.copy()
257
  # draw = ImageDraw.Draw(annotated_image)
258
+
259
+ # try:
260
+ # font = ImageFont.truetype("arial.ttf", 24)
261
+ # except:
262
+ # font = ImageFont.load_default()
263
 
264
  # dogs_info = ""
265
 
266
+
267
  # for i, (cropped_image, detection_confidence, box) in enumerate(dogs):
268
  # color = color_list[i % len(color_list)]
269
+
270
+ # # 優化圖片上的標記
271
+ # draw.rectangle(box, outline=color, width=4)
272
+ # label = f"Dog {i+1}"
273
+ # label_bbox = draw.textbbox((0, 0), label, font=font)
274
+ # label_width = label_bbox[2] - label_bbox[0]
275
+ # label_height = label_bbox[3] - label_bbox[1]
276
+
277
+ # label_x = box[0] + 5
278
+ # label_y = box[1] + 5
279
+ # draw.rectangle(
280
+ # [label_x - 2, label_y - 2, label_x + label_width + 4, label_y + label_height + 4],
281
+ # fill='white',
282
+ # outline=color,
283
+ # width=2
284
+ # )
285
+ # draw.text((label_x, label_y), label, fill=color, font=font)
286
 
287
  # top1_prob, topk_breeds, relative_probs = await predict_single_dog(cropped_image)
288
  # combined_confidence = detection_confidence * top1_prob
289
 
290
+ # # 開始資訊卡片
291
+ # dogs_info += f'<div class="dog-info-card" style="border-left: 6px solid {color};">'
292
 
293
+ # if combined_confidence < 0.15:
294
+ # dogs_info += f'''
295
+ # <div class="dog-info-header" style="background-color: {color}20;">
296
+ # <span class="dog-label" style="color: {color};">Dog {i+1}</span>
297
+ # </div>
298
+ # <div class="breed-info">
299
+ # <p class="warning-message">The image is unclear or the breed is not in the dataset. Please upload a clearer image.</p>
300
+ # </div>
301
+ # '''
302
  # elif top1_prob >= 0.45:
303
  # breed = topk_breeds[0]
304
  # description = get_dog_description(breed)
305
+ # dogs_info += f'''
306
+ # <div class="dog-info-header" style="background-color: {color}20;">
307
+ # <span class="dog-label" style="color: {color};">{breed}</span>
308
+ # </div>
309
+ # <div class="breed-info">
310
+ # {format_description_html(description, breed)}
311
+ # </div>
312
+ # '''
313
  # else:
314
+ # dogs_info += f'''
315
+ # <div class="dog-info-header" style="background-color: {color}20;">
316
+ # <span class="dog-label" style="color: {color};">Dog {i+1}</span>
317
+ # </div>
318
+ # <div class="breed-info">
319
+ # <div class="model-uncertainty-note">
320
+ # Note: The model is showing some uncertainty in its predictions.
321
+ # Here are the most likely breeds based on the available visual features.
322
+ # </div>
323
+ # <h3 class="breeds-title">Top 3 possible breeds:</h3>
324
+ # '''
325
+
326
+ # for j, (breed, prob) in enumerate(zip(topk_breeds, relative_probs)):
327
  # description = get_dog_description(breed)
328
+ # dogs_info += f'''
329
+ # <div class="breed-section">
330
+ # <div class="confidence-score" style="color: {color};">{breed} (Confidence: {prob})</div>
331
+ # <div class="breed-info-content">
332
+ # {format_description_html(description, breed)}
333
+ # </div>
334
+ # </div>
335
+ # '''
336
+ # dogs_info += '</div>'
337
 
338
  # dogs_info += '</div>'
339
 
340
  # html_output = f"""
341
  # <style>
342
+ # .dog-info-card {{
343
  # border: 1px solid #ddd;
344
+ # margin-bottom: 24px;
345
+ # padding: 0;
346
+ # border-radius: 8px;
347
+ # box-shadow: 0 2px 8px rgba(0,0,0,0.1);
348
+ # overflow: hidden;
349
+ # transition: all 0.3s ease;
350
  # }}
351
+
352
+ # .dog-info-card:hover {{
353
+ # box-shadow: 0 4px 12px rgba(0,0,0,0.15);
 
 
354
  # }}
355
+
356
+ # .dog-info-header {{
357
+ # padding: 16px 20px;
358
+ # margin: 0;
359
+ # font-size: 20px;
360
+ # font-weight: bold;
361
+ # }}
362
+
363
+ # .dog-label {{
364
+ # font-size: 18px;
365
+ # font-weight: bold;
366
+ # }}
367
+
368
+ # .breed-info {{
369
+ # padding: 20px;
370
+ # }}
371
+
372
+ # .breeds-title {{
373
+ # margin: 0 0 16px 0;
374
+ # font-size: 18px;
375
+ # color: #333;
376
+ # }}
377
+
378
  # .breed-section {{
379
+ # margin: 16px 0;
380
+ # padding: 16px;
381
  # background-color: #f8f8f8;
382
+ # border-radius: 6px;
383
+ # }}
384
+
385
+ # .confidence-score {{
386
+ # font-size: 18px;
387
+ # font-weight: bold;
388
+ # margin-bottom: 12px;
389
+ # }}
390
+
391
+ # .breed-info-content {{
392
+ # margin-top: 8px;
393
+ # }}
394
+
395
+ # .warning-message {{
396
+ # color: #ff3b30;
397
+ # font-weight: bold;
398
+ # margin: 0;
399
+ # }}
400
+
401
+ # ul {{
402
+ # padding-left: 0;
403
+ # margin: 0;
404
+ # }}
405
+
406
+ # li {{
407
+ # margin-bottom: 8px;
408
  # }}
409
  # </style>
410
  # {dogs_info}
 
435
  image = Image.fromarray(image)
436
 
437
  dogs = await detect_multiple_dogs(image)
438
+ # 更柔和的顏色組合
439
+ single_dog_color = '#4A90E2' # 柔和的藍色
440
+ color_list = ['#4A90E2', '#34C759', '#007AFF', '#5856D6', '#5AC8FA', '#FFB246', '#9C6ADE']
441
  annotated_image = image.copy()
442
  draw = ImageDraw.Draw(annotated_image)
443
+
444
  try:
445
  font = ImageFont.truetype("arial.ttf", 24)
446
  except:
 
449
  dogs_info = ""
450
 
451
  for i, (cropped_image, detection_confidence, box) in enumerate(dogs):
452
+ # 單狗時使用柔和的藍色
453
+ color = single_dog_color if len(dogs) == 1 else color_list[i % len(color_list)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
 
455
+ # ... (標記框和標籤的代碼保持不變) ...
456
+
457
  if combined_confidence < 0.15:
458
  dogs_info += f'''
459
+ <div class="dog-info-header" style="background-color: {color}10;">
460
  <span class="dog-label" style="color: {color};">Dog {i+1}</span>
461
  </div>
462
  <div class="breed-info">
 
467
  breed = topk_breeds[0]
468
  description = get_dog_description(breed)
469
  dogs_info += f'''
470
+ <div class="dog-info-header" style="background-color: {color}10;">
471
  <span class="dog-label" style="color: {color};">{breed}</span>
472
  </div>
473
  <div class="breed-info">
474
+ <div class="breed-details">
475
+ <div class="feature-category">
476
+ <div class="feature-title">Basic Information</div>
477
+ <div class="basic-info">
478
+ <span class="info-item"><strong>Size:</strong> {description['Size']}</span>
479
+ <span class="info-item"><strong>Lifespan:</strong> {description['Lifespan']}</span>
480
+ </div>
481
+ </div>
482
+
483
+ <div class="feature-category">
484
+ <div class="feature-title">Temperament & Personality</div>
485
+ <div class="temperament">{description['Temperament']}</div>
486
+ </div>
487
+
488
+ <div class="feature-category">
489
+ <div class="feature-title">Care Requirements</div>
490
+ <div class="care-info">
491
+ <span class="info-item"><strong>Exercise Needs:</strong> {description['Exercise Needs']}</span>
492
+ <span class="info-item"><strong>Grooming:</strong> {description['Grooming Needs']}</span>
493
+ <span class="info-item"><strong>Care Level:</strong> {description['Care Level']}</span>
494
+ </div>
495
+ </div>
496
+
497
+ <div class="feature-category">
498
+ <div class="feature-title">Family Compatibility</div>
499
+ <div class="family-info">
500
+ <span class="info-item"><strong>Good with Children:</strong> {description['Good with Children']}</span>
501
+ </div>
502
+ </div>
503
+
504
+ <div class="feature-category">
505
+ <div class="feature-title">Description</div>
506
+ <div class="description">{description.get('Description', '')}</div>
507
+ </div>
508
+ </div>
509
+ <div class="breed-footer">
510
+ <a href="{get_akc_breeds_link(breed)}" target="_blank" class="akc-link">Learn more about {breed} on the AKC website</a>
511
+ </div>
512
  </div>
513
  '''
514
  else:
515
+ # ... (中等信心度的代碼保持類似,但使用新的樣式) ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
 
517
  html_output = f"""
518
  <style>
519
  .dog-info-card {{
520
+ border: 1px solid #e1e4e8;
521
+ margin: 32px 0;
522
  padding: 0;
523
+ border-radius: 12px;
524
+ box-shadow: 0 2px 12px rgba(0,0,0,0.08);
525
  overflow: hidden;
526
  transition: all 0.3s ease;
527
  }}
528
 
529
  .dog-info-card:hover {{
530
+ box-shadow: 0 4px 16px rgba(0,0,0,0.12);
531
  }}
532
 
533
  .dog-info-header {{
534
+ padding: 20px 24px;
535
  margin: 0;
536
+ font-size: 22px;
537
  font-weight: bold;
538
+ border-bottom: 1px solid #e1e4e8;
539
  }}
540
 
541
+ .breed-info {{
542
+ padding: 24px;
543
+ line-height: 1.6;
544
  }}
545
 
546
+ .feature-category {{
547
+ margin-bottom: 24px;
548
  }}
549
 
550
+ .feature-title {{
551
+ font-size: 16px;
552
+ color: #666;
553
+ margin-bottom: 12px;
554
+ font-weight: 600;
555
+ text-transform: uppercase;
556
+ letter-spacing: 0.5px;
557
  }}
558
 
559
+ .basic-info, .care-info, .family-info {{
560
+ display: flex;
561
+ flex-wrap: wrap;
562
+ gap: 16px;
563
+ }}
564
+
565
+ .info-item {{
566
+ background: #f8f9fa;
567
+ padding: 8px 16px;
568
  border-radius: 6px;
569
+ font-size: 14px;
570
  }}
571
 
572
+ .temperament {{
573
+ font-style: italic;
574
+ color: #444;
 
575
  }}
576
 
577
+ .description {{
578
+ line-height: 1.8;
579
+ color: #444;
580
  }}
581
 
582
+ .breed-footer {{
583
+ margin-top: 24px;
584
+ padding-top: 16px;
585
+ border-top: 1px solid #e1e4e8;
586
  }}
587
+
588
+ .akc-link {{
589
+ color: #4A90E2;
590
+ text-decoration: none;
591
+ font-weight: 500;
592
  }}
593
 
594
+ .akc-link:hover {{
595
+ text-decoration: underline;
596
+ }}
597
+
598
+ .model-uncertainty-note {{
599
+ padding: 16px;
600
+ background-color: #f8f9fa;
601
+ border-left: 4px solid #6c757d;
602
+ margin-bottom: 20px;
603
+ color: #495057;
604
+ font-style: italic;
605
+ border-radius: 4px;
606
  }}
607
  </style>
608
  {dogs_info}
 
623
  return error_msg, None, None
624
 
625
 
626
+
627
  def show_details_html(choice, previous_output, initial_state):
628
  if not choice:
629
  return previous_output, gr.update(visible=True), initial_state