HeshamAI commited on
Commit
30cbfa0
·
verified ·
1 Parent(s): 2c41c6c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -37
app.py CHANGED
@@ -4,7 +4,9 @@ import numpy as np
4
  import pandas as pd
5
  import pydicom
6
  import io
 
7
  from PIL import Image
 
8
 
9
  class DicomAnalyzer:
10
  def __init__(self):
@@ -43,9 +45,6 @@ class DicomAnalyzer:
43
  if len(image_display.shape) == 2:
44
  image_display = cv2.cvtColor(image_display, cv2.COLOR_GRAY2BGR)
45
 
46
- print(f"DICOM image loaded. Shape: {image.shape}, Data type: {image.dtype}")
47
- print(f"Pixel spacing: {dicom_data.PixelSpacing}")
48
-
49
  return original_image, image_display, dicom_data
50
  except Exception as e:
51
  print(f"Error loading DICOM file: {str(e)}")
@@ -71,8 +70,6 @@ class DicomAnalyzer:
71
  min_val = np.min(pixels)
72
  max_val = np.max(pixels)
73
 
74
- print(f"Analysis results - Area: {area_mm2:.3f}, Mean: {mean:.3f}, StdDev: {stddev:.3f}")
75
-
76
  return {
77
  'Area (mm²)': f"{area_mm2:.3f}",
78
  'Mean': f"{mean:.3f}",
@@ -137,18 +134,16 @@ class DicomAnalyzer:
137
 
138
  try:
139
  x, y = evt.index
140
- print(f"Clicked at ({x}, {y}) on Image 1")
141
-
142
  marked_image = self.draw_circle(self.image_display1, x, y, is_image1=True)
 
143
 
144
  results = self.analyze_point(self.current_image1, self.dicom_data1, x, y)
145
  if results:
146
  results['Image'] = "Image 1"
147
  results['Point'] = f"({x}, {y})"
148
  self.results.append(results)
149
- print(f"Added results for Image 1: {results}")
150
 
151
- return marked_image, self.format_results()
152
  except Exception as e:
153
  print(f"Error in handle_click1: {str(e)}")
154
  return self.image_display1, f"Error: {str(e)}"
@@ -159,18 +154,16 @@ class DicomAnalyzer:
159
 
160
  try:
161
  x, y = evt.index
162
- print(f"Clicked at ({x}, {y}) on Image 2")
163
-
164
  marked_image = self.draw_circle(self.image_display2, x, y, is_image1=False)
 
165
 
166
  results = self.analyze_point(self.current_image2, self.dicom_data2, x, y)
167
  if results:
168
  results['Image'] = "Image 2"
169
  results['Point'] = f"({x}, {y})"
170
  self.results.append(results)
171
- print(f"Added results for Image 2: {results}")
172
 
173
- return marked_image, self.format_results()
174
  except Exception as e:
175
  print(f"Error in handle_click2: {str(e)}")
176
  return self.image_display2, f"Error: {str(e)}"
@@ -185,17 +178,17 @@ class DicomAnalyzer:
185
  self.results = []
186
  self.marks1 = []
187
  self.marks2 = []
188
- if self.image_display1 is not None:
189
  self.image_display1 = cv2.cvtColor(
190
  cv2.normalize(self.current_image1, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8),
191
  cv2.COLOR_GRAY2BGR
192
  )
193
- if self.image_display2 is not None:
194
  self.image_display2 = cv2.cvtColor(
195
  cv2.normalize(self.current_image2, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8),
196
  cv2.COLOR_GRAY2BGR
197
  )
198
- return "Results cleared"
199
 
200
  def add_blank_row(self):
201
  self.results.append({
@@ -211,7 +204,6 @@ class DicomAnalyzer:
211
 
212
  def update_circle_diameter(self, value):
213
  self.circle_diameter = value
214
- print(f"Circle diameter updated to: {value}")
215
  return f"Circle diameter set to {value}"
216
 
217
  def save_results(self):
@@ -221,13 +213,14 @@ class DicomAnalyzer:
221
 
222
  df = pd.DataFrame(self.results)
223
 
224
- # Create Excel file in memory
225
- output = io.BytesIO()
226
- with pd.ExcelWriter(output, engine='openpyxl') as writer:
227
- df.to_excel(writer, index=False)
228
- output.seek(0)
 
229
 
230
- return output, "Results ready for download"
231
  except Exception as e:
232
  print(f"Error saving results: {str(e)}")
233
  return None, f"Error saving results: {str(e)}"
@@ -241,12 +234,12 @@ def create_interface():
241
  with gr.Row():
242
  with gr.Column():
243
  file1 = gr.File(label="Upload first DICOM file")
244
- image1 = gr.Image(label="Image 1", interactive=True)
245
  file1.change(fn=analyzer.process_image1, inputs=file1, outputs=image1)
246
 
247
  with gr.Column():
248
  file2 = gr.File(label="Upload second DICOM file")
249
- image2 = gr.Image(label="Image 2", interactive=True)
250
  file2.change(fn=analyzer.process_image2, inputs=file2, outputs=image2)
251
 
252
  with gr.Row():
@@ -257,11 +250,6 @@ def create_interface():
257
  step=1,
258
  label="Circle Diameter"
259
  )
260
- circle_diameter.change(
261
- fn=analyzer.update_circle_diameter,
262
- inputs=circle_diameter,
263
- outputs=gr.Textbox(label="Status")
264
- )
265
 
266
  with gr.Row():
267
  clear_btn = gr.Button("Clear Results")
@@ -269,15 +257,40 @@ def create_interface():
269
  save_btn = gr.Button("Save Results")
270
 
271
  results = gr.Textbox(label="Results", interactive=False)
272
- download_file = gr.File(label="Download Results", visible=True)
273
- status = gr.Textbox(label="Status", visible=True)
274
 
275
  # Connect events
276
- image1.select(fn=analyzer.handle_click1, outputs=[image1, results])
277
- image2.select(fn=analyzer.handle_click2, outputs=[image2, results])
278
- clear_btn.click(fn=analyzer.clear_results, outputs=[results])
279
- blank_row_btn.click(fn=analyzer.add_blank_row, outputs=results)
280
- save_btn.click(fn=analyzer.save_results, outputs=[download_file, status])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
 
282
  return interface
283
 
 
4
  import pandas as pd
5
  import pydicom
6
  import io
7
+ import os
8
  from PIL import Image
9
+ import tempfile
10
 
11
  class DicomAnalyzer:
12
  def __init__(self):
 
45
  if len(image_display.shape) == 2:
46
  image_display = cv2.cvtColor(image_display, cv2.COLOR_GRAY2BGR)
47
 
 
 
 
48
  return original_image, image_display, dicom_data
49
  except Exception as e:
50
  print(f"Error loading DICOM file: {str(e)}")
 
70
  min_val = np.min(pixels)
71
  max_val = np.max(pixels)
72
 
 
 
73
  return {
74
  'Area (mm²)': f"{area_mm2:.3f}",
75
  'Mean': f"{mean:.3f}",
 
134
 
135
  try:
136
  x, y = evt.index
 
 
137
  marked_image = self.draw_circle(self.image_display1, x, y, is_image1=True)
138
+ self.image_display1 = marked_image
139
 
140
  results = self.analyze_point(self.current_image1, self.dicom_data1, x, y)
141
  if results:
142
  results['Image'] = "Image 1"
143
  results['Point'] = f"({x}, {y})"
144
  self.results.append(results)
 
145
 
146
+ return self.image_display1, self.format_results()
147
  except Exception as e:
148
  print(f"Error in handle_click1: {str(e)}")
149
  return self.image_display1, f"Error: {str(e)}"
 
154
 
155
  try:
156
  x, y = evt.index
 
 
157
  marked_image = self.draw_circle(self.image_display2, x, y, is_image1=False)
158
+ self.image_display2 = marked_image
159
 
160
  results = self.analyze_point(self.current_image2, self.dicom_data2, x, y)
161
  if results:
162
  results['Image'] = "Image 2"
163
  results['Point'] = f"({x}, {y})"
164
  self.results.append(results)
 
165
 
166
+ return self.image_display2, self.format_results()
167
  except Exception as e:
168
  print(f"Error in handle_click2: {str(e)}")
169
  return self.image_display2, f"Error: {str(e)}"
 
178
  self.results = []
179
  self.marks1 = []
180
  self.marks2 = []
181
+ if self.current_image1 is not None:
182
  self.image_display1 = cv2.cvtColor(
183
  cv2.normalize(self.current_image1, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8),
184
  cv2.COLOR_GRAY2BGR
185
  )
186
+ if self.current_image2 is not None:
187
  self.image_display2 = cv2.cvtColor(
188
  cv2.normalize(self.current_image2, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8),
189
  cv2.COLOR_GRAY2BGR
190
  )
191
+ return "Results cleared", self.image_display1, self.image_display2
192
 
193
  def add_blank_row(self):
194
  self.results.append({
 
204
 
205
  def update_circle_diameter(self, value):
206
  self.circle_diameter = value
 
207
  return f"Circle diameter set to {value}"
208
 
209
  def save_results(self):
 
213
 
214
  df = pd.DataFrame(self.results)
215
 
216
+ # Create temporary file
217
+ temp_dir = tempfile.gettempdir()
218
+ temp_file = os.path.join(temp_dir, "analysis_results.xlsx")
219
+
220
+ # Save to Excel
221
+ df.to_excel(temp_file, index=False, engine='openpyxl')
222
 
223
+ return temp_file, "Results saved successfully. Click to download."
224
  except Exception as e:
225
  print(f"Error saving results: {str(e)}")
226
  return None, f"Error saving results: {str(e)}"
 
234
  with gr.Row():
235
  with gr.Column():
236
  file1 = gr.File(label="Upload first DICOM file")
237
+ image1 = gr.Image(label="Image 1", interactive=True, type="numpy")
238
  file1.change(fn=analyzer.process_image1, inputs=file1, outputs=image1)
239
 
240
  with gr.Column():
241
  file2 = gr.File(label="Upload second DICOM file")
242
+ image2 = gr.Image(label="Image 2", interactive=True, type="numpy")
243
  file2.change(fn=analyzer.process_image2, inputs=file2, outputs=image2)
244
 
245
  with gr.Row():
 
250
  step=1,
251
  label="Circle Diameter"
252
  )
 
 
 
 
 
253
 
254
  with gr.Row():
255
  clear_btn = gr.Button("Clear Results")
 
257
  save_btn = gr.Button("Save Results")
258
 
259
  results = gr.Textbox(label="Results", interactive=False)
260
+ file_output = gr.File(label="Download Results")
261
+ status = gr.Textbox(label="Status")
262
 
263
  # Connect events
264
+ circle_diameter.change(
265
+ fn=analyzer.update_circle_diameter,
266
+ inputs=circle_diameter,
267
+ outputs=status
268
+ )
269
+
270
+ image1.select(
271
+ fn=analyzer.handle_click1,
272
+ outputs=[image1, results]
273
+ )
274
+
275
+ image2.select(
276
+ fn=analyzer.handle_click2,
277
+ outputs=[image2, results]
278
+ )
279
+
280
+ clear_btn.click(
281
+ fn=analyzer.clear_results,
282
+ outputs=[status, image1, image2]
283
+ )
284
+
285
+ blank_row_btn.click(
286
+ fn=analyzer.add_blank_row,
287
+ outputs=results
288
+ )
289
+
290
+ save_btn.click(
291
+ fn=analyzer.save_results,
292
+ outputs=[file_output, status]
293
+ )
294
 
295
  return interface
296