Enterwar99 commited on
Commit
2b64c9a
·
verified ·
1 Parent(s): e6a11f2

Update api_app.py

Browse files
Files changed (1) hide show
  1. api_app.py +58 -2
api_app.py CHANGED
@@ -10,6 +10,8 @@ import numpy as np
10
  import os
11
  from typing import List, Dict, Any
12
  import logging # Dodajemy import modułu logging
 
 
13
 
14
  # Importy dla Grad-CAM
15
  from pytorch_grad_cam import GradCAMPlusPlus
@@ -86,6 +88,48 @@ def initialize_model():
86
  ])
87
  logger.info(f"Model BI-RADS classifier initialized successfully on device: {DEVICE}")
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  # --- Aplikacja FastAPI ---
90
  app = FastAPI(title="BI-RADS Mammography Classification API")
91
 
@@ -144,6 +188,7 @@ async def predict_image(file: UploadFile = File(...)):
144
 
145
  # Generowanie Grad-CAM
146
  grad_cam_map_serialized = None
 
147
  logger.info(f"[RequestID: {request_id}] Rozpoczynanie generowania Grad-CAM dla kategorii {birads_category}...")
148
  try:
149
  # model_instance is already in eval mode from initialize_model()
@@ -158,8 +203,19 @@ async def predict_image(file: UploadFile = File(...)):
158
 
159
  if grayscale_cam is not None:
160
  grad_cam_map_np = grayscale_cam[0, :]
161
- grad_cam_map_serialized = grad_cam_map_np.tolist()
162
  logger.info(f"[RequestID: {request_id}] Grad-CAM wygenerowany pomyślnie.")
 
 
 
 
 
 
 
 
 
 
 
 
163
  else:
164
  logger.warning(f"[RequestID: {request_id}] Wygenerowany Grad-CAM jest None.")
165
  except Exception as e:
@@ -170,7 +226,7 @@ async def predict_image(file: UploadFile = File(...)):
170
  "confidence": confidence,
171
  "interpretation": interpretation,
172
  "class_probabilities": class_probabilities,
173
- "grad_cam_map": grad_cam_map_serialized
174
  })
175
 
176
  logger.info(f"[RequestID: {request_id}] Przetwarzanie żądania /predict/ zakończone. Zwracam wyniki.")
 
10
  import os
11
  from typing import List, Dict, Any
12
  import logging # Dodajemy import modułu logging
13
+ import cv2 # Dodajemy OpenCV
14
+ import base64 # Dodajemy base64
15
 
16
  # Importy dla Grad-CAM
17
  from pytorch_grad_cam import GradCAMPlusPlus
 
88
  ])
89
  logger.info(f"Model BI-RADS classifier initialized successfully on device: {DEVICE}")
90
 
91
+ # --- Funkcja do tworzenia obrazu z nałożoną mapą Grad-CAM (zaadaptowana z app.py) ---
92
+ def create_grad_cam_overlay_image(original_pil_image: Image.Image, grayscale_cam: np.ndarray, birads_category: int, transparency: float = 0.5) -> Image.Image:
93
+ """Tworzy obraz PIL z nałożoną mapą Grad-CAM."""
94
+ logger.info(f"Rozpoczynanie tworzenia obrazu Grad-CAM overlay dla kategorii {birads_category}")
95
+ try:
96
+ img_np = np.array(original_pil_image.convert('RGB')).astype(np.float32) / 255.0
97
+ cam_resized = cv2.resize(grayscale_cam, (img_np.shape[1], img_np.shape[0]))
98
+
99
+ cam_normalized = (cam_resized - np.min(cam_resized)) / (np.max(cam_resized) - np.min(cam_resized) + 1e-8)
100
+
101
+ threshold = 0.7
102
+ cam_normalized[cam_normalized < threshold] = 0
103
+
104
+ kernel_size = 5
105
+ kernel = np.ones((kernel_size, kernel_size), np.uint8)
106
+ cam_cleaned = cv2.morphologyEx(cam_normalized, cv2.MORPH_OPEN, kernel)
107
+
108
+ birads_colors_rgb = {
109
+ 1: (0.1, 0.7, 0.1),
110
+ 2: (0.53, 0.81, 0.92),
111
+ 3: (1.0, 0.9, 0.0),
112
+ 4: (1.0, 0.5, 0.0),
113
+ 5: (0.9, 0.1, 0.1)
114
+ }
115
+ chosen_color = np.array(birads_colors_rgb.get(birads_category, (0.5, 0.5, 0.5)))
116
+
117
+ color_overlay_np = np.zeros_like(img_np)
118
+ for c in range(3):
119
+ color_overlay_np[:, :, c] = chosen_color[c]
120
+
121
+ alpha = cam_cleaned * transparency
122
+ alpha_expanded = alpha[..., np.newaxis]
123
+
124
+ highlighted_image_np = img_np * (1 - alpha_expanded) + color_overlay_np * alpha_expanded
125
+ highlighted_image_np = np.clip(highlighted_image_np, 0, 1)
126
+ final_image_np = (highlighted_image_np * 255).astype(np.uint8)
127
+ logger.info("Obraz Grad-CAM overlay pomyślnie utworzony.")
128
+ return Image.fromarray(final_image_np)
129
+ except Exception as e:
130
+ logger.error(f"Błąd podczas tworzenia obrazu Grad-CAM overlay: {e}", exc_info=True)
131
+ return None
132
+
133
  # --- Aplikacja FastAPI ---
134
  app = FastAPI(title="BI-RADS Mammography Classification API")
135
 
 
188
 
189
  # Generowanie Grad-CAM
190
  grad_cam_map_serialized = None
191
+ grad_cam_image_base64 = None
192
  logger.info(f"[RequestID: {request_id}] Rozpoczynanie generowania Grad-CAM dla kategorii {birads_category}...")
193
  try:
194
  # model_instance is already in eval mode from initialize_model()
 
203
 
204
  if grayscale_cam is not None:
205
  grad_cam_map_np = grayscale_cam[0, :]
 
206
  logger.info(f"[RequestID: {request_id}] Grad-CAM wygenerowany pomyślnie.")
207
+
208
+ # Tworzenie obrazu z nałożoną mapą Grad-CAM
209
+ overlay_image_pil = create_grad_cam_overlay_image(original_pil_image=image, # oryginalny obraz PIL
210
+ grayscale_cam=grad_cam_map_np,
211
+ birads_category=birads_category)
212
+ if overlay_image_pil:
213
+ buffered = io.BytesIO()
214
+ overlay_image_pil.save(buffered, format="PNG") # Zapisz jako PNG
215
+ grad_cam_image_base64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
216
+ logger.info(f"[RequestID: {request_id}] Obraz Grad-CAM overlay zakodowany do base64.")
217
+ else:
218
+ logger.warning(f"[RequestID: {request_id}] Nie udało się utworzyć obrazu Grad-CAM overlay.")
219
  else:
220
  logger.warning(f"[RequestID: {request_id}] Wygenerowany Grad-CAM jest None.")
221
  except Exception as e:
 
226
  "confidence": confidence,
227
  "interpretation": interpretation,
228
  "class_probabilities": class_probabilities,
229
+ "grad_cam_image_base64": grad_cam_image_base64 # Dodajemy obraz base64
230
  })
231
 
232
  logger.info(f"[RequestID: {request_id}] Przetwarzanie żądania /predict/ zakończone. Zwracam wyniki.")