Cloud-PACS-AI-Integration / app-gradio.py
Kalbe-x-Bangkit's picture
Upload 13 files
fcc071b verified
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)