Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -48,7 +48,7 @@ from PIL import Image
|
|
| 48 |
|
| 49 |
# ---- Friendly names (UI) ----
|
| 50 |
MODEL_NAME_TBNET = "TBNet (CNN model)"
|
| 51 |
-
MODEL_NAME_RADIO = "
|
| 52 |
|
| 53 |
# ---- Default TB/Lung weights (HF-friendly relative paths) ----
|
| 54 |
DEFAULT_TB_WEIGHTS = "weights/best.pt"
|
|
@@ -102,14 +102,14 @@ recommend **CBNAAT / GeneXpert**, sputum studies, and/or **CT chest** regardless
|
|
| 102 |
# Friendly labels still map to GREEN/YELLOW/RED logic
|
| 103 |
REPORT_LABELS = {
|
| 104 |
"GREEN": {
|
| 105 |
-
"title": "LOW TB LIKELIHOOD",
|
| 106 |
"summary": (
|
| 107 |
f"✅ **{MODEL_NAME_TBNET}** did not find patterns that strongly suggest pulmonary tuberculosis.\n\n"
|
| 108 |
"**What to do next:** If symptoms or TB risk factors are present, please seek clinician/radiologist review."
|
| 109 |
),
|
| 110 |
},
|
| 111 |
"YELLOW": {
|
| 112 |
-
"title": "INDETERMINATE — REVIEW RECOMMENDED",
|
| 113 |
"summary": (
|
| 114 |
f"⚠️ **{MODEL_NAME_TBNET}** result is **not definitive**.\n\n"
|
| 115 |
"**Common reasons:** image quality limitations, non-standard/cropped view, or non-focal attention.\n\n"
|
|
@@ -1288,78 +1288,120 @@ def build_ui():
|
|
| 1288 |
|
| 1289 |
gr.Markdown(
|
| 1290 |
f"""
|
| 1291 |
-
<
|
| 1292 |
-
|
| 1293 |
-
|
| 1294 |
-
|
| 1295 |
-
|
| 1296 |
-
|
| 1297 |
-
|
| 1298 |
-
|
| 1299 |
-
|
| 1300 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1301 |
</div>
|
| 1302 |
-
</div>
|
| 1303 |
-
|
| 1304 |
-
<div class="warnbox">
|
| 1305 |
-
<b>Clinical disclaimer:</b> Decision support only (not diagnostic). TB can be subtle (including miliary TB).
|
| 1306 |
-
If TB is clinically suspected, pursue microbiology (CBNAAT/GeneXpert, sputum) and/or CT chest regardless of AI output.
|
| 1307 |
-
</div>
|
| 1308 |
-
|
| 1309 |
-
<div class="card">
|
| 1310 |
-
<div style="font-size:16px; font-weight:900; margin-bottom:8px;">Special feature: Phone / WhatsApp Mode</div>
|
| 1311 |
-
|
| 1312 |
-
Many users upload:
|
| 1313 |
-
<ul>
|
| 1314 |
-
<li><b>WhatsApp-forwarded X-rays</b> (compressed, low contrast)</li>
|
| 1315 |
-
<li><b>Phone photos</b> of printed films or monitor screens (borders, glare, blur)</li>
|
| 1316 |
-
<li><b>Screenshots</b> with large margins / UI elements</li>
|
| 1317 |
-
</ul>
|
| 1318 |
-
|
| 1319 |
-
<b>Phone / WhatsApp Mode</b> is designed for these cases. When enabled, it applies:
|
| 1320 |
-
<ul>
|
| 1321 |
-
<li><b>Safe border crop</b> (reduces margins / screenshot framing)</li>
|
| 1322 |
-
<li><b>Conditional CLAHE</b> (boosts local contrast when underexposed / low-detail)</li>
|
| 1323 |
-
<li><b>Quality warnings</b> (blur, over/underexposure, heavy borders) to flag reduced reliability</li>
|
| 1324 |
-
</ul>
|
| 1325 |
-
|
| 1326 |
-
<blockquote>
|
| 1327 |
-
<b>Tip:</b> Enable Phone/WhatsApp Mode if your image is a phone photo, WhatsApp-forwarded, or has big borders / low contrast.<br/>
|
| 1328 |
-
Keep it <b>OFF</b> for clean digital exports to avoid unnecessary preprocessing.
|
| 1329 |
-
</blockquote>
|
| 1330 |
-
</div>
|
| 1331 |
|
| 1332 |
-
<div class="
|
| 1333 |
-
|
| 1334 |
-
|
| 1335 |
-
<
|
| 1336 |
-
|
| 1337 |
-
<li><b>Fail-safe</b>: if lung segmentation looks unreliable, TBNet scoring is disabled (shown as indeterminate).</li>
|
| 1338 |
-
<li><b>Quality scoring</b> warns when results may be less reliable (blur, compression, non-standard view).</li>
|
| 1339 |
-
</ul>
|
| 1340 |
-
</div>
|
| 1341 |
-
|
| 1342 |
-
<div class="card">
|
| 1343 |
-
<div style="font-size:16px; font-weight:900; margin-bottom:8px;">How to use</div>
|
| 1344 |
-
<ol>
|
| 1345 |
-
<li>Click <b>Continue</b> to open the interface.</li>
|
| 1346 |
-
<li>Upload one or multiple X-ray images.</li>
|
| 1347 |
-
<li>If your images come from <b>WhatsApp / phone camera / screenshots</b>, enable <b>Phone/WhatsApp Mode</b>.</li>
|
| 1348 |
-
<li>(Optional) Enable <b>{MODEL_NAME_RADIO}</b> for a second independent model + heatmaps.</li>
|
| 1349 |
-
<li>Click <b>Run Analysis</b>.</li>
|
| 1350 |
-
</ol>
|
| 1351 |
-
</div>
|
| 1352 |
|
| 1353 |
-
<
|
| 1354 |
-
|
| 1355 |
-
|
| 1356 |
-
|
| 1357 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1358 |
</div>
|
| 1359 |
-
</div>
|
| 1360 |
|
| 1361 |
-
<div class="subtitle">
|
| 1362 |
-
Device policy: <b>{DEVICE}</b> (FORCE_CPU={FORCE_CPU})
|
| 1363 |
</div>
|
| 1364 |
"""
|
| 1365 |
)
|
|
|
|
| 48 |
|
| 49 |
# ---- Friendly names (UI) ----
|
| 50 |
MODEL_NAME_TBNET = "TBNet (CNN model)"
|
| 51 |
+
MODEL_NAME_RADIO = "Nvidia/C-RADIOv4-SO400M (visual model)"
|
| 52 |
|
| 53 |
# ---- Default TB/Lung weights (HF-friendly relative paths) ----
|
| 54 |
DEFAULT_TB_WEIGHTS = "weights/best.pt"
|
|
|
|
| 102 |
# Friendly labels still map to GREEN/YELLOW/RED logic
|
| 103 |
REPORT_LABELS = {
|
| 104 |
"GREEN": {
|
| 105 |
+
"title": "LOW TB LIKELIHOOD / Pulmonary T.B not detected by A.I",
|
| 106 |
"summary": (
|
| 107 |
f"✅ **{MODEL_NAME_TBNET}** did not find patterns that strongly suggest pulmonary tuberculosis.\n\n"
|
| 108 |
"**What to do next:** If symptoms or TB risk factors are present, please seek clinician/radiologist review."
|
| 109 |
),
|
| 110 |
},
|
| 111 |
"YELLOW": {
|
| 112 |
+
"title": "INDETERMINATE — REVIEW RECOMMENDED BY A RADIOLOGIST",
|
| 113 |
"summary": (
|
| 114 |
f"⚠️ **{MODEL_NAME_TBNET}** result is **not definitive**.\n\n"
|
| 115 |
"**Common reasons:** image quality limitations, non-standard/cropped view, or non-focal attention.\n\n"
|
|
|
|
| 1288 |
|
| 1289 |
gr.Markdown(
|
| 1290 |
f"""
|
| 1291 |
+
<style>
|
| 1292 |
+
.wrap {{ max-width: 980px; margin: 0 auto; }}
|
| 1293 |
+
.hero {{
|
| 1294 |
+
padding: 14px 16px;
|
| 1295 |
+
border-radius: 14px;
|
| 1296 |
+
background: rgba(255,255,255,0.04);
|
| 1297 |
+
border: 1px solid rgba(255,255,255,0.10);
|
| 1298 |
+
}}
|
| 1299 |
+
.hero h2 {{ margin: 0 0 6px 0; font-size: 18px; font-weight: 900; }}
|
| 1300 |
+
.hero p {{ margin: 0; opacity: 0.9; font-size: 13px; line-height: 1.35; }}
|
| 1301 |
+
.chips {{ margin-top: 10px; display: flex; flex-wrap: wrap; gap: 8px; }}
|
| 1302 |
+
.chip {{
|
| 1303 |
+
font-size: 12px; padding: 6px 10px; border-radius: 999px;
|
| 1304 |
+
background: rgba(255,255,255,0.06);
|
| 1305 |
+
border: 1px solid rgba(255,255,255,0.10);
|
| 1306 |
+
opacity: 0.95;
|
| 1307 |
+
}}
|
| 1308 |
+
.warn {{
|
| 1309 |
+
margin-top: 12px;
|
| 1310 |
+
padding: 10px 12px;
|
| 1311 |
+
border-left: 5px solid #f59e0b;
|
| 1312 |
+
border-radius: 12px;
|
| 1313 |
+
background: rgba(245,158,11,0.10);
|
| 1314 |
+
font-size: 12.5px;
|
| 1315 |
+
line-height: 1.35;
|
| 1316 |
+
}}
|
| 1317 |
+
details {{
|
| 1318 |
+
margin-top: 12px;
|
| 1319 |
+
padding: 10px 12px;
|
| 1320 |
+
border-radius: 12px;
|
| 1321 |
+
background: rgba(255,255,255,0.03);
|
| 1322 |
+
border: 1px solid rgba(255,255,255,0.08);
|
| 1323 |
+
}}
|
| 1324 |
+
summary {{ cursor: pointer; font-weight: 800; font-size: 13px; }}
|
| 1325 |
+
.muted {{ opacity: 0.85; font-size: 12.5px; line-height: 1.35; margin-top: 6px; }}
|
| 1326 |
+
ul, ol {{ margin: 8px 0 0 18px; }}
|
| 1327 |
+
li {{ margin: 4px 0; }}
|
| 1328 |
+
.footer {{ margin-top: 10px; opacity: 0.70; font-size: 12px; }}
|
| 1329 |
+
</style>
|
| 1330 |
+
|
| 1331 |
+
<div class="wrap">
|
| 1332 |
+
|
| 1333 |
+
<div class="hero">
|
| 1334 |
+
<h2>TB X-ray screening assistant (research / decision support)</h2>
|
| 1335 |
+
<p>
|
| 1336 |
+
Upload chest X-rays to get an AI screening score, heatmaps, and a simple consensus output.
|
| 1337 |
+
Designed to be safer on imperfect inputs (phone photos / WhatsApp / screenshots).
|
| 1338 |
+
</p>
|
| 1339 |
+
|
| 1340 |
+
<div class="chips">
|
| 1341 |
+
<span class="chip"><b>{MODEL_NAME_TBNET}</b> + Grad-CAM</span>
|
| 1342 |
+
<span class="chip">Auto Lung Mask + fail-safe</span>
|
| 1343 |
+
<span class="chip"><b>{MODEL_NAME_RADIO}</b> RAW / MASKED</span>
|
| 1344 |
+
<span class="chip">Consensus: ✅ LOW · ⚠️ INDET · ⚠️ SCREEN+ · 🚩 TB+</span>
|
| 1345 |
+
</div>
|
| 1346 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1347 |
|
| 1348 |
+
<div class="warn">
|
| 1349 |
+
<b>Clinical disclaimer:</b> Not diagnostic. TB can be subtle (incl. miliary TB).
|
| 1350 |
+
If TB is clinically suspected, pursue microbiology (CBNAAT/GeneXpert, sputum) and/or CT chest
|
| 1351 |
+
<b>regardless of AI output</b>.
|
| 1352 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1353 |
|
| 1354 |
+
<details>
|
| 1355 |
+
<summary>Phone / WhatsApp Mode — when should I use it?</summary>
|
| 1356 |
+
<div class="muted">
|
| 1357 |
+
Use this for <b>WhatsApp-forwarded</b> images, <b>phone photos</b> of films/screens, or <b>screenshots</b> with borders.
|
| 1358 |
+
It applies:
|
| 1359 |
+
<ul>
|
| 1360 |
+
<li><b>Safe border crop</b> (only when borders are detected)</li>
|
| 1361 |
+
<li><b>Conditional CLAHE</b> (only when underexposed / low detail)</li>
|
| 1362 |
+
<li><b>Quality warnings</b> (blur, over/underexposure, heavy borders)</li>
|
| 1363 |
+
</ul>
|
| 1364 |
+
<div class="muted"><b>Tip:</b> Keep it <b>OFF</b> for clean digital exports.</div>
|
| 1365 |
+
</div>
|
| 1366 |
+
</details>
|
| 1367 |
+
|
| 1368 |
+
<details>
|
| 1369 |
+
<summary>Explainability & safety checks</summary>
|
| 1370 |
+
<div class="muted">
|
| 1371 |
+
<ul>
|
| 1372 |
+
<li><b>Grad-CAM</b> highlights regions influencing TBNet.</li>
|
| 1373 |
+
<li><b>RADIO heatmaps</b> show model attention (RAW and sometimes MASKED).</li>
|
| 1374 |
+
<li><b>Fail-safe:</b> if lung masking looks unreliable, scoring is disabled → indeterminate.</li>
|
| 1375 |
+
<li><b>Quality score</b> warns when reliability may be reduced.</li>
|
| 1376 |
+
</ul>
|
| 1377 |
+
</div>
|
| 1378 |
+
</details>
|
| 1379 |
+
|
| 1380 |
+
<details>
|
| 1381 |
+
<summary>How to use</summary>
|
| 1382 |
+
<div class="muted">
|
| 1383 |
+
<ol>
|
| 1384 |
+
<li>Click <b>Continue</b> to open the interface.</li>
|
| 1385 |
+
<li>Upload one or more X-ray images.</li>
|
| 1386 |
+
<li>Enable <b>Phone/WhatsApp Mode</b> if your images are phone/WhatsApp/screenshot.</li>
|
| 1387 |
+
<li>(Optional) Enable <b>{MODEL_NAME_RADIO}</b> for a second model + heatmaps.</li>
|
| 1388 |
+
<li>Click <b>Run Analysis</b>.</li>
|
| 1389 |
+
</ol>
|
| 1390 |
+
</div>
|
| 1391 |
+
</details>
|
| 1392 |
+
|
| 1393 |
+
<details>
|
| 1394 |
+
<summary>Privacy / processing (HF Spaces)</summary>
|
| 1395 |
+
<div class="muted">
|
| 1396 |
+
Images are processed by the Space runtime. Avoid uploading personally identifiable medical data.
|
| 1397 |
+
Prefer anonymized images when possible.
|
| 1398 |
+
</div>
|
| 1399 |
+
</details>
|
| 1400 |
+
|
| 1401 |
+
<div class="footer">
|
| 1402 |
+
Device policy: <b>{DEVICE}</b> (FORCE_CPU={FORCE_CPU})
|
| 1403 |
</div>
|
|
|
|
| 1404 |
|
|
|
|
|
|
|
| 1405 |
</div>
|
| 1406 |
"""
|
| 1407 |
)
|