VaneshDev commited on
Commit
1736b2d
Β·
verified Β·
1 Parent(s): d0b3525

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -41
app.py CHANGED
@@ -1,9 +1,12 @@
1
  """
2
  RadiologyScan AI – X-ray & Report analyser
3
- Author : <you>
4
  """
5
 
6
- import os, re, logging, tempfile
 
 
 
 
7
  import gradio as gr
8
  from PIL import Image
9
  import torch
@@ -59,7 +62,7 @@ def analyse_xray(img: Image.Image):
59
  advice = medical_advice(LABELS[target])
60
  html = f"""
61
  <h3>AI findings</h3>
62
- <table>{rows}</table>
63
  <p><b>Advice:</b> {advice}</p>
64
  """
65
 
@@ -69,42 +72,67 @@ def analyse_xray(img: Image.Image):
69
  ADVICE = {
70
  "Pneumonia": "Consult a pulmonologist; antibiotics or antivirals as indicated.",
71
  "Cardiomegaly": "Recommend echocardiography; refer to cardiology.",
 
 
 
 
 
72
  "Fracture": "Orthopaedic consultation; consider CT if uncertain.",
73
  }
74
- def medical_advice(label): return ADVICE.get(label, "Discuss with a radiologist for next steps.")
 
 
75
 
76
  # PDF report summariser
77
- summariser = pipeline("summarization", model="sshleifer/distilbart-cnn-12-6")
 
 
 
 
78
 
79
  def analyse_report(file):
80
  if file is None: return "Please upload a PDF."
81
 
82
- with tempfile.NamedTemporaryFile(delete=False) as tmp:
83
- tmp.write(file.read())
84
- path = tmp.name
85
- doc = fitz.open(path)
86
- text = "\n".join(page.get_text() for page in doc)
87
- doc.close()
88
-
89
- disease = regex_find_disease(text)
90
- if not disease:
91
- short = summariser(text[:4000], max_length=120, min_length=30, do_sample=False)[0]["summary_text"]
92
- return f"<h3>Report summary</h3><p>{short}</p>"
93
-
94
- advice = medical_advice(disease)
95
- return f"""
96
- <h3>Disease detected:</h3><p>{disease}</p>
97
- <p><b>Recommendation:</b> {advice}</p>
98
- """
99
-
100
- def regex_find_disease(t:str):
 
 
 
 
 
 
 
 
 
101
  patterns = {
102
- "Pneumonia" : r"\bpneumonia\b",
103
- "Cardiomegaly" : r"\bcardiomegaly\b",
104
- "Fracture" : r"\bfracture\b",
 
 
 
 
105
  }
106
- for k,v in patterns.items():
107
- if re.search(v, t, flags=re.I): return k
 
108
  return None
109
 
110
  # Gradio UI
@@ -112,18 +140,28 @@ with gr.Blocks(title="🩻 RadiologyScan AI") as demo:
112
  gr.Markdown("## 🩻 RadiologyScan AI – Chest X-ray & Report Analyser")
113
 
114
  with gr.Tabs():
115
- with gr.Tab("X-ray image"):
116
- in_img = gr.Image(label="Upload chest X-ray")
117
- out_html= gr.HTML()
118
- out_cam = gr.Image(label="Explainability map")
119
- gr.Button("Analyse").click(analyse_xray, in_img, outputs=[out_html,out_cam])
120
- gr.Button("Clear").click(lambda: (None,"",None), None, [in_img,out_html,out_cam])
121
-
122
- with gr.Tab("Radiology report"):
123
- in_pdf = gr.File(label="Upload PDF report", file_types=[".pdf"])
 
 
 
 
 
124
  out_rep = gr.HTML()
125
- gr.Button("Analyse").click(analyse_report, in_pdf, out_rep)
126
- gr.Button("Clear").click(lambda: (None,""), None, [in_pdf,out_rep])
 
 
 
 
 
127
 
128
  if __name__ == "__main__":
129
- demo.launch(show_error=True, server_port=int(os.getenv("PORT",7860)))
 
1
  """
2
  RadiologyScan AI – X-ray & Report analyser
 
3
  """
4
 
5
+ import os
6
+ # Fix for PyTorch 2.6 weights_only issue
7
+ os.environ['TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD'] = '1'
8
+
9
+ import re, logging, tempfile
10
  import gradio as gr
11
  from PIL import Image
12
  import torch
 
62
  advice = medical_advice(LABELS[target])
63
  html = f"""
64
  <h3>AI findings</h3>
65
+ <table border="1"><tr><th>Condition</th><th>Probability</th></tr>{rows}</table>
66
  <p><b>Advice:</b> {advice}</p>
67
  """
68
 
 
72
  ADVICE = {
73
  "Pneumonia": "Consult a pulmonologist; antibiotics or antivirals as indicated.",
74
  "Cardiomegaly": "Recommend echocardiography; refer to cardiology.",
75
+ "Atelectasis": "Further imaging may be needed; consult pulmonologist.",
76
+ "Consolidation": "Likely infection or inflammation; seek medical attention.",
77
+ "Pleural_Thickening": "Monitor for progression; pulmonology consultation.",
78
+ "Edema": "Evaluate for heart failure; cardiology consultation.",
79
+ "Effusion": "Thoracentesis may be needed; pulmonology consultation.",
80
  "Fracture": "Orthopaedic consultation; consider CT if uncertain.",
81
  }
82
+
83
+ def medical_advice(label):
84
+ return ADVICE.get(label, "Discuss with a radiologist for next steps.")
85
 
86
  # PDF report summariser
87
+ try:
88
+ summariser = pipeline("summarization", model="sshleifer/distilbart-cnn-12-6")
89
+ except:
90
+ summariser = None
91
+ log.warning("Could not load summarization model")
92
 
93
  def analyse_report(file):
94
  if file is None: return "Please upload a PDF."
95
 
96
+ try:
97
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp:
98
+ tmp.write(file.read())
99
+ tmp_path = tmp.name
100
+
101
+ doc = fitz.open(tmp_path)
102
+ text = "\n".join(page.get_text() for page in doc)
103
+ doc.close()
104
+ os.unlink(tmp_path)
105
+
106
+ disease = regex_find_disease(text)
107
+ if disease:
108
+ advice = medical_advice(disease)
109
+ return f"""
110
+ <h3>Disease detected:</h3><p>{disease}</p>
111
+ <p><b>Recommendation:</b> {advice}</p>
112
+ """
113
+ elif summariser:
114
+ # fallback LLM summary
115
+ short_text = text[:4000] if len(text) > 4000 else text
116
+ summary = summariser(short_text, max_length=120, min_length=30, do_sample=False)
117
+ return f"<h3>Report summary</h3><p>{summary[0]['summary_text']}</p>"
118
+ else:
119
+ return "<h3>Report processed</h3><p>No specific conditions detected. Please consult with a medical professional for interpretation.</p>"
120
+ except Exception as e:
121
+ return f"Error processing PDF: {str(e)}"
122
+
123
+ def regex_find_disease(text: str):
124
  patterns = {
125
+ "Pneumonia": r"\b(pneumonia|lung infection)\b",
126
+ "Cardiomegaly": r"\b(cardiomegaly|enlarged heart)\b",
127
+ "Atelectasis": r"\b(atelectasis|lung collapse)\b",
128
+ "Consolidation": r"\b(consolidation|lung consolidation)\b",
129
+ "Fracture": r"\b(fracture|broken bone|break)\b",
130
+ "Edema": r"\b(edema|fluid buildup)\b",
131
+ "Effusion": r"\b(effusion|fluid collection)\b",
132
  }
133
+ for condition, pattern in patterns.items():
134
+ if re.search(pattern, text, flags=re.I):
135
+ return condition
136
  return None
137
 
138
  # Gradio UI
 
140
  gr.Markdown("## 🩻 RadiologyScan AI – Chest X-ray & Report Analyser")
141
 
142
  with gr.Tabs():
143
+ with gr.Tab("X-ray Analysis"):
144
+ in_img = gr.Image(label="Upload chest X-ray", type="pil")
145
+ out_html = gr.HTML()
146
+ out_cam = gr.Image(label="Attention Map")
147
+
148
+ with gr.Row():
149
+ analyze_btn = gr.Button("Analyze X-ray", variant="primary")
150
+ clear_btn = gr.Button("Clear")
151
+
152
+ analyze_btn.click(analyse_xray, inputs=in_img, outputs=[out_html, out_cam])
153
+ clear_btn.click(lambda: (None, "", None), inputs=None, outputs=[in_img, out_html, out_cam])
154
+
155
+ with gr.Tab("Report Analysis"):
156
+ in_pdf = gr.File(label="Upload PDF report", file_types=[".pdf"])
157
  out_rep = gr.HTML()
158
+
159
+ with gr.Row():
160
+ analyze_rep_btn = gr.Button("Analyze Report", variant="primary")
161
+ clear_rep_btn = gr.Button("Clear")
162
+
163
+ analyze_rep_btn.click(analyse_report, inputs=in_pdf, outputs=out_rep)
164
+ clear_rep_btn.click(lambda: (None, ""), inputs=None, outputs=[in_pdf, out_rep])
165
 
166
  if __name__ == "__main__":
167
+ demo.launch(show_error=True, server_port=int(os.getenv("PORT", 7860)))