Update app.py
Browse files
app.py
CHANGED
@@ -203,12 +203,12 @@ def find_last_dense_layer(model):
|
|
203 |
|
204 |
# ---- GRAD-CAM ----
|
205 |
def make_gradcam(image_pil, model, last_conv_layer_name, class_index, progress=None):
|
206 |
-
if model is None:
|
207 |
-
|
208 |
try:
|
209 |
_update_progress(progress, 0, desc="Préparation de l'image...")
|
210 |
-
input_size = model.input_shape[1:3]
|
211 |
|
|
|
212 |
if 'xception' in model.name.lower():
|
213 |
preprocessor = preprocess_xception
|
214 |
elif 'resnet50' in model.name.lower():
|
@@ -222,7 +222,7 @@ def make_gradcam(image_pil, model, last_conv_layer_name, class_index, progress=N
|
|
222 |
img_resized = cv2.resize(img_np, input_size)
|
223 |
img_array_preprocessed = preprocessor(np.expand_dims(img_resized, axis=0))
|
224 |
|
225 |
-
_update_progress(progress,
|
226 |
|
227 |
try:
|
228 |
conv_layer = model.get_layer(last_conv_layer_name)
|
@@ -230,7 +230,6 @@ def make_gradcam(image_pil, model, last_conv_layer_name, class_index, progress=N
|
|
230 |
return img_resized
|
231 |
|
232 |
dense_layer = find_last_dense_layer(model)
|
233 |
-
|
234 |
grad_model = Model(model.inputs, [conv_layer.output, model.output])
|
235 |
input_name = get_primary_input_name(model)
|
236 |
input_for_model = {input_name: img_array_preprocessed}
|
@@ -242,15 +241,16 @@ def make_gradcam(image_pil, model, last_conv_layer_name, class_index, progress=N
|
|
242 |
class_channel = preds[:, int(class_index)]
|
243 |
|
244 |
grads = tape.gradient(class_channel, last_conv_layer_output)
|
245 |
-
|
246 |
if grads is None:
|
247 |
return img_resized
|
248 |
|
249 |
-
_update_progress(progress,
|
250 |
|
251 |
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
|
252 |
last_conv_layer_output = last_conv_layer_output[0]
|
253 |
-
|
|
|
|
|
254 |
heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]
|
255 |
heatmap = tf.squeeze(heatmap)
|
256 |
heatmap = tf.maximum(heatmap, 0)
|
@@ -260,26 +260,30 @@ def make_gradcam(image_pil, model, last_conv_layer_name, class_index, progress=N
|
|
260 |
heatmap = tf.ones_like(heatmap) * 0.5
|
261 |
else:
|
262 |
heatmap = heatmap / max_val
|
263 |
-
|
264 |
-
heatmap_np = heatmap.numpy()
|
265 |
|
266 |
-
_update_progress(progress,
|
267 |
|
|
|
268 |
heatmap_np = np.clip(heatmap_np.astype(np.float32), 0, 1)
|
|
|
|
|
|
|
269 |
heatmap_resized = cv2.resize(heatmap_np, (img_resized.shape[1], img_resized.shape[0]))
|
270 |
heatmap_uint8 = np.uint8(255 * heatmap_resized)
|
271 |
heatmap_colored = cv2.applyColorMap(heatmap_uint8, cv2.COLORMAP_JET)
|
272 |
-
|
273 |
img_bgr = cv2.cvtColor(img_resized, cv2.COLOR_RGB2BGR)
|
274 |
superimposed_img = cv2.addWeighted(img_bgr, 0.6, heatmap_colored, 0.4, 0)
|
275 |
|
276 |
-
_update_progress(progress, 100, desc="✅ Grad-CAM terminé !"
|
277 |
|
278 |
return cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)
|
|
|
279 |
except Exception as e:
|
280 |
import traceback; traceback.print_exc()
|
281 |
return np.array(image_pil)
|
282 |
|
|
|
283 |
# ---- GESTION ASYNCHRONE / ÉTAT ----
|
284 |
current_image = None
|
285 |
current_predictions = None
|
|
|
203 |
|
204 |
# ---- GRAD-CAM ----
|
205 |
def make_gradcam(image_pil, model, last_conv_layer_name, class_index, progress=None):
|
206 |
+
if model is None:
|
207 |
+
return np.array(image_pil)
|
208 |
try:
|
209 |
_update_progress(progress, 0, desc="Préparation de l'image...")
|
|
|
210 |
|
211 |
+
input_size = model.input_shape[1:3]
|
212 |
if 'xception' in model.name.lower():
|
213 |
preprocessor = preprocess_xception
|
214 |
elif 'resnet50' in model.name.lower():
|
|
|
222 |
img_resized = cv2.resize(img_np, input_size)
|
223 |
img_array_preprocessed = preprocessor(np.expand_dims(img_resized, axis=0))
|
224 |
|
225 |
+
_update_progress(progress, 20, desc="Calcul des gradients...")
|
226 |
|
227 |
try:
|
228 |
conv_layer = model.get_layer(last_conv_layer_name)
|
|
|
230 |
return img_resized
|
231 |
|
232 |
dense_layer = find_last_dense_layer(model)
|
|
|
233 |
grad_model = Model(model.inputs, [conv_layer.output, model.output])
|
234 |
input_name = get_primary_input_name(model)
|
235 |
input_for_model = {input_name: img_array_preprocessed}
|
|
|
241 |
class_channel = preds[:, int(class_index)]
|
242 |
|
243 |
grads = tape.gradient(class_channel, last_conv_layer_output)
|
|
|
244 |
if grads is None:
|
245 |
return img_resized
|
246 |
|
247 |
+
_update_progress(progress, 40, desc="Pooling des gradients...")
|
248 |
|
249 |
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
|
250 |
last_conv_layer_output = last_conv_layer_output[0]
|
251 |
+
|
252 |
+
_update_progress(progress, 55, desc="Construction de la heatmap...")
|
253 |
+
|
254 |
heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]
|
255 |
heatmap = tf.squeeze(heatmap)
|
256 |
heatmap = tf.maximum(heatmap, 0)
|
|
|
260 |
heatmap = tf.ones_like(heatmap) * 0.5
|
261 |
else:
|
262 |
heatmap = heatmap / max_val
|
|
|
|
|
263 |
|
264 |
+
_update_progress(progress, 70, desc="Conversion NumPy...")
|
265 |
|
266 |
+
heatmap_np = heatmap.numpy()
|
267 |
heatmap_np = np.clip(heatmap_np.astype(np.float32), 0, 1)
|
268 |
+
|
269 |
+
_update_progress(progress, 80, desc="Application du colormap...")
|
270 |
+
|
271 |
heatmap_resized = cv2.resize(heatmap_np, (img_resized.shape[1], img_resized.shape[0]))
|
272 |
heatmap_uint8 = np.uint8(255 * heatmap_resized)
|
273 |
heatmap_colored = cv2.applyColorMap(heatmap_uint8, cv2.COLORMAP_JET)
|
274 |
+
|
275 |
img_bgr = cv2.cvtColor(img_resized, cv2.COLOR_RGB2BGR)
|
276 |
superimposed_img = cv2.addWeighted(img_bgr, 0.6, heatmap_colored, 0.4, 0)
|
277 |
|
278 |
+
_update_progress(progress, 100, desc="✅ Grad-CAM terminé !")
|
279 |
|
280 |
return cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)
|
281 |
+
|
282 |
except Exception as e:
|
283 |
import traceback; traceback.print_exc()
|
284 |
return np.array(image_pil)
|
285 |
|
286 |
+
|
287 |
# ---- GESTION ASYNCHRONE / ÉTAT ----
|
288 |
current_image = None
|
289 |
current_predictions = None
|