| import streamlit as st | |
| import cv2 | |
| import numpy as np | |
| import tensorflow as tf | |
| from tensorflow.keras.preprocessing import image | |
| from tensorflow.keras.models import load_model | |
| import pandas as pd | |
| class GradCAM: | |
| def __init__(self, model, layer_name): | |
| self.model = model | |
| self.layer_name = layer_name | |
| self.grad_model = tf.keras.models.Model( | |
| [self.model.inputs], | |
| [self.model.get_layer(layer_name).output, self.model.output] | |
| ) | |
| def __call__(self, img_array, cls): | |
| with tf.GradientTape() as tape: | |
| conv_outputs, predictions = self.grad_model(img_array) | |
| loss = predictions[:, cls] | |
| output = conv_outputs[0] | |
| grads = tape.gradient(loss, conv_outputs)[0] | |
| gate_f = tf.cast(output > 0, 'float32') | |
| gate_r = tf.cast(grads > 0, 'float32') | |
| guided_grads = gate_f * gate_r * grads | |
| weights = tf.reduce_mean(guided_grads, axis=(0, 1)) | |
| cam = np.zeros(output.shape[0:2], dtype=np.float32) | |
| for index, w in enumerate(weights): | |
| cam += w * output[:, :, index] | |
| cam = cv2.resize(cam.numpy(), (224, 224)) | |
| cam = np.maximum(cam, 0) | |
| cam = cam / cam.max() | |
| return cam | |
| def apply_heatmap(img, heatmap, heatmap_ratio=0.6): | |
| heatmap = cv2.applyColorMap(np.uint8(255 * heatmap), cv2.COLORMAP_JET) | |
| heatmap = cv2.cvtColor(heatmap, cv2.COLOR_BGR2RGB) | |
| return np.uint8(heatmap * heatmap_ratio + img * (1 - heatmap_ratio)) | |
| def load_image(img_path, df, preprocess=True, H=320, W=320): | |
| mean, std = get_mean_std_per_batch(img_path, df, H=H, W=W) | |
| x = image.load_img(img_path, target_size=(H, W)) | |
| x = image.img_to_array(x) | |
| if preprocess: | |
| x -= mean | |
| x /= std | |
| x = np.expand_dims(x, axis=0) | |
| return x | |
| def get_mean_std_per_batch(image_path, df, H=320, W=320): | |
| sample_data = [] | |
| for idx, img in enumerate(df.sample(100)["Image Index"].values): | |
| sample_data.append( | |
| np.array(image.load_img(image_path, target_size=(H, W)))) | |
| mean = np.mean(sample_data[0]) | |
| std = np.std(sample_data[0]) | |
| return mean, std | |
| def compute_gradcam(img, model, df, labels, layer_name='bn'): | |
| preprocessed_input = load_image(img, df) | |
| predictions = model.predict(preprocessed_input) | |
| top_indices = np.argsort(predictions[0])[-3:][::-1] | |
| top_labels = [labels[i] for i in top_indices] | |
| top_predictions = [predictions[0][i] for i in top_indices] | |
| original_image = load_image(img, df, preprocess=False) | |
| grad_cam = GradCAM(model, layer_name) | |
| gradcam_images = [] | |
| for i in range(3): | |
| idx = top_indices[i] | |
| label = top_labels[i] | |
| prob = top_predictions[i] | |
| gradcam = grad_cam(preprocessed_input, idx) | |
| gradcam_image = apply_heatmap(original_image, gradcam) | |
| gradcam_images.append((gradcam_image, f"{label}: p={prob:.3f}")) | |
| return gradcam_images | |
| def calculate_mse(original_image, enhanced_image): | |
| mse = np.mean((original_image - enhanced_image) ** 2) | |
| return mse | |
| def calculate_psnr(original_image, enhanced_image): | |
| mse = calculate_mse(original_image, enhanced_image) | |
| if mse == 0: | |
| return float('inf') | |
| max_pixel_value = 255.0 | |
| psnr = 20 * np.log10(max_pixel_value / np.sqrt(mse)) | |
| return psnr | |
| def calculate_maxerr(original_image, enhanced_image): | |
| maxerr = np.max((original_image - enhanced_image) ** 2) | |
| return maxerr | |
| def calculate_l2rat(original_image, enhanced_image): | |
| l2norm_ratio = np.sum(original_image ** 2) / np.sum((original_image - enhanced_image) ** 2) | |
| return l2norm_ratio | |
| def process_image(original_image, enhancement_type, fix_monochrome=True): | |
| if fix_monochrome and original_image.shape[-1] == 3: | |
| original_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY) | |
| image = original_image - np.min(original_image) | |
| image = image / np.max(original_image) | |
| image = (image * 255).astype(np.uint8) | |
| enhanced_image = enhance_image(image, enhancement_type) | |
| mse = calculate_mse(original_image, enhanced_image) | |
| psnr = calculate_psnr(original_image, enhanced_image) | |
| maxerr = calculate_maxerr(original_image, enhanced_image) | |
| l2rat = calculate_l2rat(original_image, enhanced_image) | |
| return enhanced_image, mse, psnr, maxerr, l2rat | |
| def apply_clahe(image): | |
| clahe = cv2.createCLAHE(clipLimit=40.0, tileGridSize=(8, 8)) | |
| return clahe.apply(image) | |
| def invert(image): | |
| return cv2.bitwise_not(image) | |
| def hp_filter(image, kernel=None): | |
| if kernel is None: | |
| kernel = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]]) | |
| return cv2.filter2D(image, -1, kernel) | |
| def unsharp_mask(image, radius=5, amount=2): | |
| def usm(image, radius, amount): | |
| blurred = cv2.GaussianBlur(image, (0, 0), radius) | |
| sharpened = cv2.addWeighted(image, 1.0 + amount, blurred, -amount, 0) | |
| return sharpened | |
| return usm(image, radius, amount) | |
| def hist_eq(image): | |
| return cv2.equalizeHist(image) | |
| def enhance_image(image, enhancement_type): | |
| if enhancement_type == "Invert": | |
| return invert(image) | |
| elif enhancement_type == "High Pass Filter": | |
| return hp_filter(image) | |
| elif enhancement_type == "Unsharp Masking": | |
| return unsharp_mask(image) | |
| elif enhancement_type == "Histogram Equalization": | |
| return hist_eq(image) | |
| elif enhancement_type == "CLAHE": | |
| return apply_clahe(image) | |
| else: | |
| raise ValueError(f"Unknown enhancement type: {enhancement_type}") | |
| st.title("Image Enhancement and Quality Evaluation") | |
| uploaded_file = st.file_uploader("Upload Original Image", type=["png", "jpg", "jpeg"]) | |
| enhancement_type = st.radio("Enhancement Type", ["Invert", "High Pass Filter", "Unsharp Masking", "Histogram Equalization", "CLAHE"]) | |
| if uploaded_file is not None: | |
| original_image = np.array(image.load_img(uploaded_file, color_mode='rgb' if enhancement_type == "Invert" else 'grayscale')) | |
| enhanced_image, mse, psnr, maxerr, l2rat = process_image(original_image, enhancement_type) | |
| st.image(original_image, caption='Original Image', use_column_width=True) | |
| st.image(enhanced_image, caption='Enhanced Image', use_column_width=True) | |
| st.write("MSE:", mse) | |
| st.write("PSNR:", psnr) | |
| st.write("Maxerr:", maxerr) | |
| st.write("L2Rat:", l2rat) | |
| st.title("Grad-CAM Visualization") | |
| uploaded_gradcam_file = st.file_uploader("Upload Image for Grad-CAM", type=["png", "jpg", "jpeg"], key="gradcam") | |
| if uploaded_gradcam_file is not None: | |
| df_file = st.file_uploader("Upload DataFrame for Mean/Std Calculation", type=["csv"]) | |
| labels = st.text_area("Labels", placeholder="Enter labels separated by commas") | |
| model_path = st.text_input("Model Path", 'model/densenet.hdf5') | |
| pretrained_model_path = st.text_input("Pretrained Model Path", 'model/pretrained_model.h5') | |
| if df_file and labels and model_path and pretrained_model_path: | |
| df = pd.read_csv(df_file) | |
| labels = labels.split(',') | |
| model = load_model(model_path) | |
| pretrained_model = load_model(pretrained_model_path) | |
| gradcam_images = compute_gradcam(uploaded_gradcam_file, pretrained_model, df, labels) | |
| for idx, (gradcam_image, label) in enumerate(gradcam_images): | |
| st.image(gradcam_image, caption=f'Grad-CAM {idx+1}: {label}', use_column_width=True) | |