koesan commited on
Commit
322e005
·
verified ·
1 Parent(s): 0523d68

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -44
app.py CHANGED
@@ -7,6 +7,8 @@ from datetime import datetime
7
  import base64
8
  from io import BytesIO
9
  from PIL import Image
 
 
10
 
11
  # Suppress TensorFlow warnings
12
  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
@@ -17,7 +19,7 @@ from tensorflow.keras.models import load_model
17
  app = Flask(__name__)
18
  app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max
19
  app.config['UPLOAD_FOLDER'] = 'uploads'
20
- app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'mha'}
21
 
22
  # Create uploads folder with proper permissions
23
  os.makedirs(app.config['UPLOAD_FOLDER'], mode=0o777, exist_ok=True)
@@ -45,28 +47,42 @@ def allowed_file(filename):
45
  filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
46
 
47
  def preprocess_image(image_path):
48
- """Preprocess image for brain segmentation"""
49
- # Read image in grayscale
50
- img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
51
-
52
- if img is None:
53
- raise ValueError("Could not read image")
54
-
55
- # Get original shape
56
- original_shape = img.shape
57
-
58
- # Resize to model input size: 160x160 (NOT 256x256!)
59
- img_resized = cv2.resize(img, (160, 160))
60
-
61
- # Normalize to [0, 1]
62
- img_normalized = img_resized.astype(np.float32) / 255.0
63
-
64
- # Add batch and channel dimensions in channels_first format (NCHW)
65
- # Model expects: (batch, channels, height, width) = (None, 1, 160, 160)
66
- img_input = np.expand_dims(img_normalized, axis=0) # (1, 160, 160)
67
- img_input = np.expand_dims(img_input, axis=0) # (1, 1, 160, 160)
68
-
69
- return img_input, original_shape
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  def postprocess_mask(mask, original_shape):
72
  """Postprocess segmentation mask"""
@@ -144,7 +160,7 @@ def predict():
144
  return jsonify({'error': 'No file selected'}), 400
145
 
146
  if not allowed_file(file.filename):
147
- return jsonify({'error': 'Invalid file type. Please upload PNG, JPG, or JPEG'}), 400
148
 
149
  # Save uploaded file
150
  timestamp = datetime.now().strftime('%Y%m%d_%Hh%Mm%Ss')
@@ -152,24 +168,25 @@ def predict():
152
  filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
153
  file.save(filepath)
154
 
155
- # Read original image
156
- original_img = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
157
-
158
- # Preprocess
159
- img_input, original_shape = preprocess_image(filepath)
160
 
161
  # Predict
162
  print("Making prediction...")
163
  prediction = model.predict(img_input, verbose=0)
164
 
165
- # Postprocess
166
- mask = postprocess_mask(prediction[0], original_shape)
 
 
 
 
167
 
168
  # Create overlay
169
- overlay = create_overlay(original_img, mask)
170
 
171
  # Convert to base64
172
- original_base64 = img_to_base64(original_img)
173
  mask_base64 = img_to_base64(mask)
174
  overlay_base64 = img_to_base64(overlay)
175
 
@@ -196,17 +213,6 @@ def predict():
196
  traceback.print_exc()
197
  return jsonify({'error': str(e)}), 500
198
 
199
- @app.route('/example')
200
- def example():
201
- """Get example image"""
202
- example_path = 'image/20251012_09h06m52s_grim.png'
203
- if os.path.exists(example_path):
204
- with open(example_path, 'rb') as f:
205
- img_data = f.read()
206
- img_base64 = base64.b64encode(img_data).decode('utf-8')
207
- return jsonify({'image': f"data:image/png;base64,{img_base64}"})
208
- return jsonify({'error': 'Example image not found'}), 404
209
-
210
  if __name__ == '__main__':
211
  print("\n" + "="*60)
212
  print("🧠 Brain Tumor Segmentation App")
 
7
  import base64
8
  from io import BytesIO
9
  from PIL import Image
10
+ import SimpleITK as sitk
11
+ from skimage.transform import resize
12
 
13
  # Suppress TensorFlow warnings
14
  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
 
19
  app = Flask(__name__)
20
  app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max
21
  app.config['UPLOAD_FOLDER'] = 'uploads'
22
+ app.config['ALLOWED_EXTENSIONS'] = {'mha'} # Only MRI .mha files
23
 
24
  # Create uploads folder with proper permissions
25
  os.makedirs(app.config['UPLOAD_FOLDER'], mode=0o777, exist_ok=True)
 
47
  filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
48
 
49
  def preprocess_image(image_path):
50
+ """Preprocess MHA image for brain segmentation (same as training)"""
51
+ try:
52
+ # Read MHA file using SimpleITK
53
+ img = sitk.ReadImage(image_path)
54
+ img = sitk.GetArrayFromImage(img)
55
+
56
+ print(f"Original MHA shape: {img.shape}")
57
+
58
+ # Resize to (155, 160, 160) - same as training
59
+ img_resized = resize(img, (155, 160, 160), preserve_range=True)
60
+
61
+ # Select middle slice (same as training uses slice 60-130)
62
+ # For single prediction, use slice 95 (middle of range)
63
+ middle_slice = 95
64
+ img_slice = img_resized[middle_slice, :, :] # (160, 160)
65
+
66
+ # Keep original for visualization
67
+ original_slice = img_slice.copy()
68
+
69
+ # Z-score normalization (same as training)
70
+ img_normalized = (img_slice - img_slice.mean()) / (img_slice.std() + 1e-8)
71
+ img_normalized = img_normalized.astype(np.float32)
72
+
73
+ print(f"Slice shape: {img_normalized.shape}")
74
+
75
+ # Add batch and channel dimensions in channels_first format (NCHW)
76
+ # Model expects: (batch, channels, height, width) = (None, 1, 160, 160)
77
+ img_input = np.expand_dims(img_normalized, axis=0) # (1, 160, 160)
78
+ img_input = np.expand_dims(img_input, axis=0) # (1, 1, 160, 160)
79
+
80
+ print(f"Model input shape: {img_input.shape}")
81
+
82
+ return img_input, original_slice
83
+
84
+ except Exception as e:
85
+ raise ValueError(f"Failed to read MHA file: {str(e)}")
86
 
87
  def postprocess_mask(mask, original_shape):
88
  """Postprocess segmentation mask"""
 
160
  return jsonify({'error': 'No file selected'}), 400
161
 
162
  if not allowed_file(file.filename):
163
+ return jsonify({'error': 'Invalid file type. Please upload .mha MRI file'}), 400
164
 
165
  # Save uploaded file
166
  timestamp = datetime.now().strftime('%Y%m%d_%Hh%Mm%Ss')
 
168
  filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
169
  file.save(filepath)
170
 
171
+ # Preprocess MHA file (returns normalized input and original slice)
172
+ img_input, original_slice = preprocess_image(filepath)
 
 
 
173
 
174
  # Predict
175
  print("Making prediction...")
176
  prediction = model.predict(img_input, verbose=0)
177
 
178
+ # Postprocess mask (returns 160x160 binary mask)
179
+ mask = postprocess_mask(prediction[0], original_slice.shape)
180
+
181
+ # Normalize original slice for display (0-255)
182
+ original_display = ((original_slice - original_slice.min()) /
183
+ (original_slice.max() - original_slice.min() + 1e-8) * 255).astype(np.uint8)
184
 
185
  # Create overlay
186
+ overlay = create_overlay(original_display, mask)
187
 
188
  # Convert to base64
189
+ original_base64 = img_to_base64(original_display)
190
  mask_base64 = img_to_base64(mask)
191
  overlay_base64 = img_to_base64(overlay)
192
 
 
213
  traceback.print_exc()
214
  return jsonify({'error': str(e)}), 500
215
 
 
 
 
 
 
 
 
 
 
 
 
216
  if __name__ == '__main__':
217
  print("\n" + "="*60)
218
  print("🧠 Brain Tumor Segmentation App")