| # import numpy as np | |
| # import cv2 | |
| # import tensorflow as tf | |
| # from tensorflow.keras.preprocessing.image import img_to_array, load_img | |
| # import matplotlib.pyplot as plt | |
| # from matplotlib.colors import LinearSegmentedColormap | |
| # def preprocess_image(img_path, target_size): | |
| # img = load_img(img_path, target_size=target_size) | |
| # img = img_to_array(img) | |
| # img = np.expand_dims(img, axis=0) | |
| # img = img / 255.0 # Normalize | |
| # return img | |
| # def make_gradcam_heatmap(model, img_tensor, last_conv_layer_name, classifier_layer_names): | |
| # grad_model = tf.keras.models.Model( | |
| # [model.inputs], [model.get_layer(last_conv_layer_name).output, model.output] | |
| # ) | |
| # with tf.GradientTape() as tape: | |
| # conv_outputs, predictions = grad_model(img_tensor) | |
| # loss = predictions[:, 1] # Targeting class 1 for pneumonia | |
| # grads = tape.gradient(loss, conv_outputs) | |
| # pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2)) | |
| # conv_outputs = conv_outputs[0] | |
| # heatmap = conv_outputs @ pooled_grads[..., tf.newaxis] | |
| # heatmap = tf.squeeze(heatmap) | |
| # heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap) | |
| # heatmap = tf.where(tf.math.is_nan(heatmap), tf.zeros_like(heatmap), heatmap) | |
| # return heatmap.numpy() | |
| # def create_custom_colormap(): | |
| # colors = ['blue', 'green', 'yellow', 'red'] | |
| # n_bins = 256 | |
| # cmap = LinearSegmentedColormap.from_list('custom', colors, N=n_bins) | |
| # return cmap | |
| # def apply_custom_colormap(heatmap, cmap): | |
| # colored_heatmap = cmap(heatmap) | |
| # colored_heatmap = np.uint8(colored_heatmap * 255) | |
| # return colored_heatmap | |
| # def enhance_heatmap(heatmap, gamma=0.7, percentile=99): | |
| # heatmap = np.power(heatmap, gamma) | |
| # heatmap = heatmap / np.percentile(heatmap, percentile) | |
| # heatmap = np.clip(heatmap, 0, 1) | |
| # return heatmap | |
| # def generate_and_merge_heatmaps(img_path, vgg_model, efficientnet_model, densenet_model, img_size=(224, 224), output_size=(5, 5)): | |
| # img_tensor = preprocess_image(img_path, img_size) | |
| # vgg_heatmap = make_gradcam_heatmap(vgg_model, img_tensor, 'block5_conv4', ['flatten', 'dense']) | |
| # efficientnet_heatmap = make_gradcam_heatmap(efficientnet_model, img_tensor, 'top_conv', ['flatten', 'dense']) | |
| # densenet_heatmap = make_gradcam_heatmap(densenet_model, img_tensor, 'conv5_block16_concat', ['flatten', 'dense']) | |
| # vgg_heatmap_resized = cv2.resize(vgg_heatmap, img_size) | |
| # efficientnet_heatmap_resized = cv2.resize(efficientnet_heatmap, img_size) | |
| # densenet_heatmap_resized = cv2.resize(densenet_heatmap, img_size) | |
| # merged_heatmap = (vgg_heatmap_resized + efficientnet_heatmap_resized + densenet_heatmap_resized) / 3.0 | |
| # enhanced_heatmap = enhance_heatmap(merged_heatmap) | |
| # custom_cmap = create_custom_colormap() | |
| # colored_heatmap = apply_custom_colormap(enhanced_heatmap, custom_cmap) | |
| # img = cv2.imread(img_path) | |
| # img = cv2.resize(img, img_size) | |
| # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) | |
| # superimposed_img = cv2.addWeighted(img, 0.6, colored_heatmap[:, :, :3], 0.4, 0) | |
| # return superimposed_img | |
| # import numpy as np | |
| # import cv2 | |
| # import tensorflow as tf | |
| # from tensorflow.keras.preprocessing.image import img_to_array, load_img | |
| # from matplotlib.colors import LinearSegmentedColormap | |
| # def preprocess_image(img_path, target_size): | |
| # img = load_img(img_path, target_size=target_size) | |
| # img = img_to_array(img) | |
| # img = np.expand_dims(img, axis=0) | |
| # img = img / 255.0 | |
| # return img | |
| # def make_gradcam_heatmap(model, img_tensor): | |
| # grad_model = tf.keras.models.Model([model.input], [model.output]) | |
| # with tf.GradientTape() as tape: | |
| # conv_outputs = model(img_tensor) | |
| # loss = conv_outputs[:, 1] # class index 1 = pneumonia | |
| # grads = tape.gradient(loss, conv_outputs) | |
| # pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2)) | |
| # conv_outputs = conv_outputs[0] | |
| # heatmap = conv_outputs @ pooled_grads[..., tf.newaxis] | |
| # heatmap = tf.squeeze(heatmap) | |
| # heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap) | |
| # heatmap = tf.where(tf.math.is_nan(heatmap), tf.zeros_like(heatmap), heatmap) | |
| # return heatmap.numpy() | |
| # def create_custom_colormap(): | |
| # colors = ['blue', 'green', 'yellow', 'red'] | |
| # cmap = LinearSegmentedColormap.from_list('custom', colors, N=256) | |
| # return cmap | |
| # def apply_custom_colormap(heatmap, cmap): | |
| # colored_heatmap = cmap(heatmap) | |
| # return np.uint8(colored_heatmap * 255) | |
| # def enhance_heatmap(heatmap, gamma=0.7, percentile=99): | |
| # heatmap = np.power(heatmap, gamma) | |
| # heatmap = heatmap / np.percentile(heatmap, percentile) | |
| # return np.clip(heatmap, 0, 1) | |
| # def generate_and_merge_heatmaps(img_path, vgg_model, efficientnet_model, densenet_model, img_size=(224, 224)): | |
| # img_tensor = preprocess_image(img_path, img_size) | |
| # vgg_heatmap = make_gradcam_heatmap(vgg_model, img_tensor) | |
| # efficientnet_heatmap = make_gradcam_heatmap(efficientnet_model, img_tensor) | |
| # densenet_heatmap = make_gradcam_heatmap(densenet_model, img_tensor) | |
| # vgg_heatmap = cv2.resize(vgg_heatmap, img_size) | |
| # efficientnet_heatmap = cv2.resize(efficientnet_heatmap, img_size) | |
| # densenet_heatmap = cv2.resize(densenet_heatmap, img_size) | |
| # merged = (vgg_heatmap + efficientnet_heatmap + densenet_heatmap) / 3.0 | |
| # enhanced = enhance_heatmap(merged) | |
| # colored = apply_custom_colormap(enhanced, create_custom_colormap()) | |
| # original = cv2.imread(img_path) | |
| # original = cv2.resize(original, img_size) | |
| # original = cv2.cvtColor(original, cv2.COLOR_BGR2RGB) | |
| # superimposed_img = cv2.addWeighted(original, 0.6, colored[:, :, :3], 0.4, 0) | |
| # return superimposed_img | |
| import numpy as np | |
| from tf_explain.core.grad_cam import GradCAM | |
| import tensorflow as tf | |
| from tensorflow.keras.preprocessing.image import img_to_array | |
| from PIL import Image | |
| def generate_heatmap_tf_explain(image_pil, model, class_index, layer_name="block5_conv4"): | |
| from tf_explain.core.grad_cam import GradCAM | |
| # Preprocess image | |
| img_array = np.array(image_pil.resize((224, 224))) / 255.0 | |
| img_array = np.expand_dims(img_array, axis=0) | |
| # Reconstruct model to include target layer | |
| from tensorflow.keras.models import Model | |
| model_for_explanation = Model(inputs=model.input, outputs=model.output) | |
| explainer = GradCAM() | |
| explanation = explainer.explain( | |
| validation_data=(img_array, None), | |
| model=model_for_explanation, | |
| class_index=class_index, | |
| layer_name=layer_name | |
| ) | |
| return Image.fromarray(explanation) | |