VaneshDev commited on
Commit
04f8061
·
verified ·
1 Parent(s): 11ecb78

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +132 -78
app.py CHANGED
@@ -2,88 +2,116 @@ import gradio as gr
2
  from PIL import Image
3
  import torch
4
  from torchvision import models, transforms
5
- import PyPDF2 # For reading patient reports (PDFs)
 
6
 
7
- # Load the pre-trained model (ResNet18 with new weight parameter)
8
- model = models.resnet18(weights="IMAGENET1K_V1") # Updated to the new weight parameter in torchvision 0.13+
 
 
 
 
 
 
9
  model.eval()
10
 
11
- # Define image preprocessing function
 
 
 
 
12
  def preprocess_image(image):
13
  transform = transforms.Compose([
14
  transforms.Resize((224, 224)),
15
  transforms.ToTensor(),
 
16
  ])
17
- return transform(image).unsqueeze(0)
 
 
18
 
19
  # Define a prediction function for X-ray images with detailed output
20
  def predict_xray(image):
21
- image_tensor = preprocess_image(image)
22
- with torch.no_grad():
23
- outputs = model(image_tensor)
24
- probs = torch.nn.functional.softmax(outputs[0], dim=0)
25
-
26
- # Define the conditions (replace these with the actual conditions your model predicts)
27
- conditions = ["Normal", "Pneumonia", "Cancer", "TB", "Other"]
28
- results = {conditions[i]: float(probs[i]) for i in range(len(conditions))}
29
-
30
- # Determine the most likely condition and provide detailed feedback
31
- most_likely_condition = max(results, key=results.get)
32
- confidence = results[most_likely_condition] * 100 # Convert to percentage
33
-
34
- # Provide a more detailed summary of the results
35
- summary = f"**Summary**: Based on the X-ray analysis, the most likely diagnosis is: <b>{most_likely_condition}</b> with a confidence of <b>{confidence:.2f}%</b>."
36
-
37
- # Additional detailed descriptions and recommendations for each condition
38
- condition_details = {
39
- "Normal": {
40
- "description": "The X-ray shows no abnormal signs, and the lungs appear healthy.",
41
- "recommendation": "No further tests are required. Continue with regular health check-ups."
42
- },
43
- "Pneumonia": {
44
- "description": "Pneumonia is an infection that causes inflammation in the lungs. It can be caused by bacteria, viruses, or fungi.",
45
- "recommendation": "Consult a healthcare provider immediately for possible antibiotics and further treatment."
46
- },
47
- "Cancer": {
48
- "description": "Lung cancer can manifest in the form of abnormal growths in the lungs. It may require more advanced diagnostic tools like biopsies.",
49
- "recommendation": "Consult an oncologist for further tests and treatment options."
50
- },
51
- "TB": {
52
- "description": "Tuberculosis (TB) is a serious bacterial infection that mainly affects the lungs. It is treatable but requires proper care.",
53
- "recommendation": "Seek immediate medical attention for a proper treatment plan, which may include antibiotics."
54
- },
55
- "Other": {
56
- "description": "The X-ray may show signs of other possible conditions that need further investigation.",
57
- "recommendation": "Consult with a doctor to rule out any other serious conditions."
 
 
 
 
 
58
  }
59
- }
60
-
61
- # Displaying the results in a structured way (bullet points)
62
- detailed_results = "<ul>"
63
- for condition, prob in results.items():
64
- detailed_results += f"<li><b>{condition}:</b> {prob*100:.2f}%</li>"
65
- detailed_results += "</ul>"
66
-
67
- # Additional advice based on the most likely condition
68
- additional_feedback = condition_details.get(most_likely_condition, "Please consult with a doctor for further details.")
69
-
70
- return summary, detailed_results, additional_feedback
 
 
 
 
71
 
72
  # Define a function to read and analyze patient reports (PDFs)
73
  def analyze_report(file):
74
  text = ""
75
- if file.name.endswith(".pdf"):
76
- pdf_reader = PyPDF2.PdfReader(file)
77
- for page in pdf_reader.pages:
78
- text += page.extract_text()
79
- # For simplicity, we are just summarizing the first 300 characters
80
- report_summary = f"Patient Report (Preview): {text[:300]}..."
 
 
 
 
 
81
  return report_summary
82
 
83
  # Gradio Interface with enhanced UI
84
  def create_interface():
85
  with gr.Blocks() as demo:
86
- # Custom CSS for UI
87
  custom_css = """
88
  .gradio-container {
89
  background-color: #f4f6f9;
@@ -96,12 +124,18 @@ def create_interface():
96
  font-size: 30px;
97
  text-align: center;
98
  color: #4C6A92;
 
99
  }
100
  .gradio-button {
101
  background-color: #3B82F6;
102
  color: white;
103
  border-radius: 10px;
104
- padding: 15px;
 
 
 
 
 
105
  }
106
  .result-box {
107
  background-color: #ffffff;
@@ -109,43 +143,63 @@ def create_interface():
109
  padding: 20px;
110
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
111
  margin-top: 20px;
 
112
  }
113
  .result-list {
114
  padding-left: 20px;
 
115
  }
116
  .result-summary {
117
  font-size: 18px;
118
  color: #2F4F4F;
 
 
 
 
 
 
 
 
119
  }
120
  """
121
 
122
- # Title section
123
  gr.Markdown("<h1 class='title'>RadiologyScan AI</h1>")
 
124
 
125
- # Upload X-ray image section
126
  with gr.Row():
127
- xray_input = gr.Image(label="Upload Chest X-ray", type="pil")
128
- report_input = gr.File(label="Upload Patient Report (PDF)", file_count="single")
 
 
129
 
130
  # Buttons for analysis
131
  with gr.Row():
132
  predict_button = gr.Button("Analyze X-ray", elem_classes="gradio-button")
133
  report_button = gr.Button("Analyze Report", elem_classes="gradio-button")
134
 
135
- # Results section for the X-ray image
136
- xray_output = gr.HTML(label="X-ray Diagnosis Summary", elem_classes="result-box") # Removed interactive=False
137
- xray_result = gr.HTML(label="Detailed X-ray Results", elem_classes="result-box") # Removed interactive=False
138
- additional_feedback = gr.Textbox(label="Additional Feedback", interactive=False, elem_classes="result-box")
139
-
140
- # Results section for the patient report
141
- report_output = gr.Textbox(label="Report Summary", interactive=False, elem_classes="result-box")
142
-
143
- # Event handlers for buttons
144
- predict_button.click(predict_xray, inputs=xray_input, outputs=[xray_output, xray_result, additional_feedback])
145
- report_button.click(analyze_report, inputs=report_input, outputs=report_output)
 
 
 
 
 
 
 
146
 
147
  return demo
148
 
149
  # Launch the Gradio interface
150
  demo = create_interface()
151
- demo.launch(share=True)
 
2
  from PIL import Image
3
  import torch
4
  from torchvision import models, transforms
5
+ import PyPDF2
6
+ import logging
7
 
8
+ # Set up logging
9
+ logging.basicConfig(level=logging.DEBUG)
10
+ logger = logging.getLogger(__name__)
11
+
12
+ # Load the pre-trained model (DenseNet121, suitable for medical imaging)
13
+ model = models.densenet121(pretrained=True) # Using ImageNet weights as a starting point
14
+ num_features = model.classifier.in_features
15
+ model.classifier = torch.nn.Linear(num_features, 5) # Output layer for 5 conditions
16
  model.eval()
17
 
18
+ # Define device (CPU or GPU)
19
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
20
+ model = model.to(device)
21
+
22
+ # Define image preprocessing function with normalization
23
  def preprocess_image(image):
24
  transform = transforms.Compose([
25
  transforms.Resize((224, 224)),
26
  transforms.ToTensor(),
27
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), # ImageNet normalization
28
  ])
29
+ image_tensor = transform(image).unsqueeze(0).to(device)
30
+ logger.debug(f"Preprocessed image tensor shape: {image_tensor.shape}")
31
+ return image_tensor
32
 
33
  # Define a prediction function for X-ray images with detailed output
34
  def predict_xray(image):
35
+ try:
36
+ if image is None:
37
+ return "Error: No image uploaded.", "", ""
38
+
39
+ image_tensor = preprocess_image(image)
40
+ with torch.no_grad():
41
+ outputs = model(image_tensor)
42
+ probs = torch.nn.functional.softmax(outputs, dim=1)[0] # Softmax over the 5 classes
43
+
44
+ # Define the conditions
45
+ conditions = ["Normal", "Pneumonia", "Cancer", "TB", "Other"]
46
+ results = {conditions[i]: float(probs[i].cpu().numpy()) * 100 for i in range(5)}
47
+
48
+ # Determine the most likely condition and confidence
49
+ most_likely_condition = max(results, key=results.get)
50
+ confidence = results[most_likely_condition]
51
+
52
+ # Generate summary
53
+ summary = f"**Summary**: Based on the X-ray analysis, the most likely diagnosis is: <b>{most_likely_condition}</b> with a confidence of <b>{confidence:.2f}%</b>."
54
+
55
+ # Condition details with enhanced descriptions
56
+ condition_details = {
57
+ "Normal": {
58
+ "description": "The X-ray shows no abnormal signs, indicating healthy lung tissue with clear structures.",
59
+ "recommendation": "No immediate action required. Schedule routine check-ups to monitor lung health."
60
+ },
61
+ "Pneumonia": {
62
+ "description": "Pneumonia is detected, showing lung inflammation, possibly due to bacterial or viral infection, with visible opacities.",
63
+ "recommendation": "Seek medical attention promptly; treatment may include antibiotics or antiviral medication."
64
+ },
65
+ "Cancer": {
66
+ "description": "Suspicious masses or nodules suggest lung cancer, requiring advanced imaging (e.g., CT) for confirmation.",
67
+ "recommendation": "Urgently consult an oncologist for a biopsy and personalized treatment plan."
68
+ },
69
+ "TB": {
70
+ "description": "Tuberculosis is indicated by cavitary lesions or consolidation, a contagious bacterial infection.",
71
+ "recommendation": "Contact a healthcare provider immediately for a treatment regimen, likely involving multiple antibiotics."
72
+ },
73
+ "Other": {
74
+ "description": "Unclear abnormalities detected; could indicate conditions like fibrosis or heart-related issues.",
75
+ "recommendation": "Refer to a radiologist for specialized imaging and diagnosis."
76
+ }
77
  }
78
+
79
+ # Detailed results in a structured format
80
+ detailed_results = "<ul class='result-list'>"
81
+ for condition, prob in results.items():
82
+ detailed_results += f"<li><b>{condition}:</b> {prob:.2f}%</li>"
83
+ detailed_results += "</ul>"
84
+
85
+ # Additional feedback based on the condition
86
+ additional_feedback = condition_details.get(most_likely_condition, "Please consult a medical professional for a detailed evaluation.")
87
+
88
+ logger.info(f"Prediction: {most_likely_condition} with confidence {confidence:.2f}%")
89
+ return summary, detailed_results, additional_feedback
90
+
91
+ except Exception as e:
92
+ logger.error(f"Error in predict_xray: {str(e)}")
93
+ return f"Error: {str(e)}", "", ""
94
 
95
  # Define a function to read and analyze patient reports (PDFs)
96
  def analyze_report(file):
97
  text = ""
98
+ if file and file.name.endswith(".pdf"):
99
+ try:
100
+ pdf_reader = PyPDF2.PdfReader(file)
101
+ for page in pdf_reader.pages:
102
+ text += page.extract_text() or ""
103
+ report_summary = f"Patient Report (Preview): {text[:300]}..." if text else "No readable text found in the PDF."
104
+ except Exception as e:
105
+ logger.error(f"Error reading PDF: {str(e)}")
106
+ report_summary = f"Error processing PDF: {str(e)}"
107
+ else:
108
+ report_summary = "Please upload a valid PDF file."
109
  return report_summary
110
 
111
  # Gradio Interface with enhanced UI
112
  def create_interface():
113
  with gr.Blocks() as demo:
114
+ # Custom CSS for UI enhancement
115
  custom_css = """
116
  .gradio-container {
117
  background-color: #f4f6f9;
 
124
  font-size: 30px;
125
  text-align: center;
126
  color: #4C6A92;
127
+ margin-bottom: 20px;
128
  }
129
  .gradio-button {
130
  background-color: #3B82F6;
131
  color: white;
132
  border-radius: 10px;
133
+ padding: 15px 30px;
134
+ font-size: 16px;
135
+ transition: background-color 0.3s;
136
+ }
137
+ .gradio-button:hover {
138
+ background-color: #2563EB;
139
  }
140
  .result-box {
141
  background-color: #ffffff;
 
143
  padding: 20px;
144
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
145
  margin-top: 20px;
146
+ max-width: 100%;
147
  }
148
  .result-list {
149
  padding-left: 20px;
150
+ margin: 10px 0;
151
  }
152
  .result-summary {
153
  font-size: 18px;
154
  color: #2F4F4F;
155
+ font-weight: 500;
156
+ }
157
+ .feedback-box {
158
+ background-color: #F0FFF4;
159
+ padding: 10px;
160
+ border-left: 4px solid #38A169;
161
+ border-radius: 5px;
162
+ margin-top: 10px;
163
  }
164
  """
165
 
166
+ # Title and description
167
  gr.Markdown("<h1 class='title'>RadiologyScan AI</h1>")
168
+ gr.Markdown("<p style='text-align: center; color: #666;'>Advanced X-ray and patient report analysis powered by AI</p>")
169
 
170
+ # Upload section with layout
171
  with gr.Row():
172
+ with gr.Column(scale=1):
173
+ xray_input = gr.Image(label="Upload Chest X-ray", type="pil", elem_id="xray-input")
174
+ with gr.Column(scale=1):
175
+ report_input = gr.File(label="Upload Patient Report (PDF)", file_count="single", elem_id="report-input")
176
 
177
  # Buttons for analysis
178
  with gr.Row():
179
  predict_button = gr.Button("Analyze X-ray", elem_classes="gradio-button")
180
  report_button = gr.Button("Analyze Report", elem_classes="gradio-button")
181
 
182
+ # Results section
183
+ with gr.Column():
184
+ xray_output = gr.HTML(label="X-ray Diagnosis Summary", elem_classes="result-box")
185
+ xray_result = gr.HTML(label="Detailed X-ray Results", elem_classes="result-box")
186
+ additional_feedback = gr.HTML(label="Additional Feedback", elem_classes="result-box feedback-box")
187
+ report_output = gr.Textbox(label="Report Summary", interactive=False, elem_classes="result-box")
188
+
189
+ # Event handlers
190
+ predict_button.click(
191
+ fn=predict_xray,
192
+ inputs=xray_input,
193
+ outputs=[xray_output, xray_result, additional_feedback]
194
+ )
195
+ report_button.click(
196
+ fn=analyze_report,
197
+ inputs=report_input,
198
+ outputs=report_output
199
+ )
200
 
201
  return demo
202
 
203
  # Launch the Gradio interface
204
  demo = create_interface()
205
+ demo.launch(share=True)