Ehsanul75's picture
Update app.py
2a33f17 verified
Raw
History Blame Contribute Delete
3.58 kB
import gradio as gr
import tensorflow as tf
import numpy as np
import cv2
import matplotlib.pyplot as plt
from tensorflow.keras.models import Model
# Load trained model
model = tf.keras.models.load_model("densenet_model.h5")
resize_dim = (256, 256)
classes = ["OK", "Defective"]
# Preprocessing function
def preprocess_image(img):
if img.ndim == 3 and img.shape[2] == 3:
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
elif img.ndim == 2:
gray = img
else:
raise ValueError("Unsupported image shape")
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl_img = clahe.apply(gray)
denoised = cv2.fastNlMeansDenoising(cl_img, None, h=10, templateWindowSize=7, searchWindowSize=21)
resized = cv2.resize(denoised, resize_dim)
sobel_x = cv2.Sobel(resized, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(resized, cv2.CV_64F, 0, 1, ksize=3)
sobel = np.sqrt(sobel_x**2 + sobel_y**2)
sobel = np.uint8(np.clip(sobel, 0, 255))
normalized = sobel / 255.0
normalized = normalized[..., np.newaxis]
rgb_img = np.repeat(normalized, 3, axis=-1)
return np.expand_dims(rgb_img, axis=0).astype(np.float32), rgb_img # Return both for Grad-CAM
# Grad-CAM heatmap generation
def get_gradcam_heatmap(model, img_array, layer_name='conv5_block32_concat', class_index=None):
grad_model = Model(inputs=model.input,
outputs=[model.get_layer(layer_name).output, model.output])
with tf.GradientTape() as tape:
conv_outputs, predictions = grad_model(img_array)
if class_index is None:
class_index = tf.argmax(predictions[0])
loss = predictions[:, class_index]
grads = tape.gradient(loss, conv_outputs)
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
conv_outputs = conv_outputs[0]
heatmap = tf.reduce_sum(tf.multiply(pooled_grads, conv_outputs), axis=-1)
heatmap = np.maximum(heatmap, 0)
heatmap /= tf.reduce_max(heatmap)
return heatmap.numpy()
# Overlay heatmap on image
def overlay_heatmap(img, heatmap, alpha=0.4):
heatmap_resized = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
heatmap_colored = cv2.applyColorMap(np.uint8(255 * heatmap_resized), cv2.COLORMAP_JET)
heatmap_colored = cv2.cvtColor(heatmap_colored, cv2.COLOR_BGR2RGB)
overlay = np.uint8(heatmap_colored * alpha + img * 255)
overlay = np.clip(overlay, 0, 255)
return overlay.astype(np.uint8)
# Combined prediction + Grad-CAM function
def predict_with_gradcam(img):
try:
processed_img, img_rgb = preprocess_image(img)
preds = model.predict(processed_img)[0]
class_idx = np.argmax(preds)
confidence = preds[class_idx]
heatmap = get_gradcam_heatmap(model, processed_img, class_index=class_idx)
overlay_img = overlay_heatmap(img_rgb, heatmap)
label = f"Prediction: {classes[class_idx]} (Confidence: {confidence:.2f})"
return overlay_img, label
except Exception as e:
return np.zeros((256, 256, 3), dtype=np.uint8), f"Error: {str(e)}"
# Gradio interface
iface = gr.Interface(
fn=predict_with_gradcam,
inputs=gr.Image(type="numpy", label="Upload Casting Image (Grayscale or RGB)"),
outputs=[
gr.Image(type="numpy", label="Grad-CAM Heatmap Overlay"),
gr.Textbox(label="Prediction")
],
title="Casting Defect Detection with Grad-CAM",
description="Upload a casting product image. The model classifies it and highlights image regions influencing its decision."
)
if __name__ == "__main__":
iface.launch()