mmarquezsa commited on
Commit
8541ab5
·
verified ·
1 Parent(s): 1d052a1

feat: lighting quality assessment for Fitzpatrick estimation

Browse files
Files changed (1) hide show
  1. app.py +59 -2
app.py CHANGED
@@ -389,6 +389,36 @@ def generate_pdf_report(image_rgb, binary_overlay, multiclass_overlay, result):
389
  bg = FITZ_RGB.get(ftype, (229, 231, 235))
390
  fg = FITZ_TEXT_RGB.get(ftype, (50, 50, 50))
391
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  # Badge
393
  x_badge = pdf.get_x()
394
  y_badge = pdf.get_y()
@@ -408,12 +438,13 @@ def generate_pdf_report(image_rgb, binary_overlay, multiclass_overlay, result):
408
  pdf._font("", 9)
409
  det_x = x_badge + 40
410
  det_y = y_badge
 
411
  details = [
412
  ("ITA", f"{fitz.ita_angle:.1f} +/- {fitz.ita_std:.1f} grados"),
413
  ("L* medio (piel sana)", f"{fitz.l_skin_mean:.1f}"),
 
414
  ("b* medio (piel sana)", f"{fitz.b_skin_mean:.1f}"),
415
  ("Pixeles sanos", f"{fitz.healthy_pixels:,}"),
416
- ("Ratio piel sana", f"{fitz.healthy_ratio:.1%}"),
417
  ("Confianza", f"{fitz.confidence:.0%}"),
418
  ]
419
  for label, value in details:
@@ -626,7 +657,32 @@ def build_fitz_html(fitz):
626
  return "<p style='color:#6b7280;'>No se pudo estimar (insuficientes pixeles de piel sana).</p>"
627
  bg = FITZ_COLORS.get(fitz.fitzpatrick_type, "#e5e7eb")
628
  fg = FITZ_TEXT_COLORS.get(fitz.fitzpatrick_type, "#1f2937")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
629
  return f"""
 
630
  <div style="display:flex; gap:16px; align-items:center; flex-wrap:wrap;">
631
  <div style="background:{bg}; color:{fg}; border-radius:12px; padding:18px 28px;
632
  font-size:1.5em; font-weight:700; min-width:120px; text-align:center;
@@ -636,7 +692,8 @@ def build_fitz_html(fitz):
636
  </div>
637
  <div style="font-size:0.95em; line-height:1.8;">
638
  <b>ITA:</b> {fitz.ita_angle:.1f}&deg; &plusmn; {fitz.ita_std:.1f}&deg;<br>
639
- <b>L* medio:</b> {fitz.l_skin_mean:.1f}<br>
 
640
  <b>Pixeles sanos:</b> {fitz.healthy_pixels:,}<br>
641
  <b>Confianza:</b> {fitz.confidence:.0%}
642
  </div>
 
389
  bg = FITZ_RGB.get(ftype, (229, 231, 235))
390
  fg = FITZ_TEXT_RGB.get(ftype, (50, 50, 50))
391
 
392
+ # Lighting warning in PDF
393
+ lighting_quality = getattr(fitz, "lighting_quality", "good")
394
+ lighting_warning = getattr(fitz, "lighting_warning", "")
395
+ if lighting_quality == "insufficient":
396
+ pdf.set_fill_color(254, 242, 242)
397
+ pdf.set_draw_color(252, 165, 165)
398
+ pdf.set_text_color(220, 38, 38)
399
+ pdf._font("B", 8)
400
+ y_warn = pdf.get_y()
401
+ pdf.rect(pdf.get_x(), y_warn, 185, 10, "DF")
402
+ pdf.set_xy(pdf.get_x() + 2, y_warn + 1)
403
+ pdf.cell(0, 4, "ADVERTENCIA: Iluminacion insuficiente - tipo Fitzpatrick puede estar sobreestimado", 0, 1)
404
+ pdf._font("", 7)
405
+ pdf.set_text_color(153, 27, 27)
406
+ pdf.cell(0, 3, lighting_warning, 0, 1)
407
+ pdf.ln(3)
408
+ elif lighting_quality == "low":
409
+ pdf.set_fill_color(255, 251, 235)
410
+ pdf.set_draw_color(252, 211, 77)
411
+ pdf.set_text_color(217, 119, 6)
412
+ pdf._font("B", 8)
413
+ y_warn = pdf.get_y()
414
+ pdf.rect(pdf.get_x(), y_warn, 185, 10, "DF")
415
+ pdf.set_xy(pdf.get_x() + 2, y_warn + 1)
416
+ pdf.cell(0, 4, "PRECAUCION: Iluminacion suboptima - resultado puede tener 1-2 niveles de error", 0, 1)
417
+ pdf._font("", 7)
418
+ pdf.set_text_color(146, 64, 14)
419
+ pdf.cell(0, 3, lighting_warning, 0, 1)
420
+ pdf.ln(3)
421
+
422
  # Badge
423
  x_badge = pdf.get_x()
424
  y_badge = pdf.get_y()
 
438
  pdf._font("", 9)
439
  det_x = x_badge + 40
440
  det_y = y_badge
441
+ l_scene = getattr(fitz, "l_scene_mean", 0)
442
  details = [
443
  ("ITA", f"{fitz.ita_angle:.1f} +/- {fitz.ita_std:.1f} grados"),
444
  ("L* medio (piel sana)", f"{fitz.l_skin_mean:.1f}"),
445
+ ("L* escena (global)", f"{l_scene:.1f}"),
446
  ("b* medio (piel sana)", f"{fitz.b_skin_mean:.1f}"),
447
  ("Pixeles sanos", f"{fitz.healthy_pixels:,}"),
 
448
  ("Confianza", f"{fitz.confidence:.0%}"),
449
  ]
450
  for label, value in details:
 
657
  return "<p style='color:#6b7280;'>No se pudo estimar (insuficientes pixeles de piel sana).</p>"
658
  bg = FITZ_COLORS.get(fitz.fitzpatrick_type, "#e5e7eb")
659
  fg = FITZ_TEXT_COLORS.get(fitz.fitzpatrick_type, "#1f2937")
660
+
661
+ # Lighting warning banner
662
+ warning_html = ""
663
+ lighting_warning = getattr(fitz, "lighting_warning", "")
664
+ lighting_quality = getattr(fitz, "lighting_quality", "good")
665
+ l_scene = getattr(fitz, "l_scene_mean", 0)
666
+
667
+ if lighting_quality == "insufficient":
668
+ warning_html = f"""
669
+ <div style="background:#fef2f2; border:1px solid #fca5a5; border-radius:8px;
670
+ padding:12px 16px; margin-bottom:12px; font-size:0.9em;">
671
+ <span style="color:#dc2626; font-weight:700;">&#9888; Iluminacion insuficiente</span><br>
672
+ <span style="color:#991b1b;">{lighting_warning}</span><br>
673
+ <span style="color:#6b7280; font-size:0.85em;">L* escena: {l_scene:.0f} (minimo recomendado: 35)</span>
674
+ </div>"""
675
+ elif lighting_quality == "low":
676
+ warning_html = f"""
677
+ <div style="background:#fffbeb; border:1px solid #fcd34d; border-radius:8px;
678
+ padding:12px 16px; margin-bottom:12px; font-size:0.9em;">
679
+ <span style="color:#d97706; font-weight:700;">&#9888; Iluminacion suboptima</span><br>
680
+ <span style="color:#92400e;">{lighting_warning}</span><br>
681
+ <span style="color:#6b7280; font-size:0.85em;">L* escena: {l_scene:.0f} (recomendado: >50)</span>
682
+ </div>"""
683
+
684
  return f"""
685
+ {warning_html}
686
  <div style="display:flex; gap:16px; align-items:center; flex-wrap:wrap;">
687
  <div style="background:{bg}; color:{fg}; border-radius:12px; padding:18px 28px;
688
  font-size:1.5em; font-weight:700; min-width:120px; text-align:center;
 
692
  </div>
693
  <div style="font-size:0.95em; line-height:1.8;">
694
  <b>ITA:</b> {fitz.ita_angle:.1f}&deg; &plusmn; {fitz.ita_std:.1f}&deg;<br>
695
+ <b>L* medio piel:</b> {fitz.l_skin_mean:.1f}<br>
696
+ <b>L* escena:</b> {l_scene:.1f}<br>
697
  <b>Pixeles sanos:</b> {fitz.healthy_pixels:,}<br>
698
  <b>Confianza:</b> {fitz.confidence:.0%}
699
  </div>