carlosriverat's picture
Update app.py
ae2249b verified
raw
history blame
3.51 kB
import gradio as gr
import cv2
import numpy as np
from skimage.metrics import structural_similarity as ssim
def preprocess_image(image, blur_value):
# Convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply Gaussian blur to reduce noise
blurred = cv2.GaussianBlur(gray, (blur_value, blur_value), 0)
return blurred
def compare_images(image1, image2, blur_value, technique, threshold_value):
# Preprocess images
gray1 = preprocess_image(image1, blur_value)
gray2 = preprocess_image(image2, blur_value)
# Compute SSIM between the two images
score, diff = ssim(gray1, gray2, full=True)
diff = (diff * 255).astype("uint8")
if technique == "Adaptive Threshold":
_, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY_INV)
elif technique == "Otsu's Threshold":
_, thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
else: # Simple Binary
_, thresh = cv2.threshold(diff, threshold_value, 255, cv2.THRESH_BINARY)
# Find contours of differences
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Filter out small noise using contour area threshold
filtered_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > 500]
# Create a mask to isolate only the significant added object
mask = np.zeros_like(image1, dtype=np.uint8)
cv2.drawContours(mask, filtered_contours, -1, (255, 255, 255), thickness=cv2.FILLED)
# Apply the mask to highlight the object added in the second image
highlighted = cv2.bitwise_and(image2, mask)
# Create a magenta overlay where changes occurred
diff_colored = np.zeros_like(image1, dtype=np.uint8)
diff_colored[:, :, 0] = thresh # Set blue channel to zero
diff_colored[:, :, 1] = 0 # Set green channel to zero
diff_colored[:, :, 2] = thresh # Set red channel to highlight in magenta
# Combine the original image with the magenta overlay
overlayed = cv2.addWeighted(image1, 0.7, diff_colored, 0.3, 0)
return highlighted, overlayed
def update_threshold_visibility(technique):
return gr.update(visible=(technique == "Simple Binary"))
with gr.Blocks() as demo:
gr.Markdown("# Object Difference Highlighter\nUpload two images: one without an object and one with an object. The app will highlight only the newly added object and show the real differences in magenta overlayed on the original image.")
with gr.Row():
img1 = gr.Image(type="numpy", label="Image Without Object")
img2 = gr.Image(type="numpy", label="Image With Object")
blur_slider = gr.Slider(minimum=1, maximum=15, step=2, value=5, label="Gaussian Blur")
technique_dropdown = gr.Dropdown(["Adaptive Threshold", "Otsu's Threshold", "Simple Binary"], label="Thresholding Technique", value="Adaptive Threshold", interactive=True)
threshold_slider = gr.Slider(minimum=0, maximum=255, step=1, value=50, label="Threshold Value", visible=False)
technique_dropdown.change(update_threshold_visibility, inputs=[technique_dropdown], outputs=[threshold_slider])
output1 = gr.Image(type="numpy", label="Highlighted Differences")
output2 = gr.Image(type="numpy", label="Raw Difference Overlay (Magenta)")
btn = gr.Button("Process")
btn.click(compare_images, inputs=[img1, img2, blur_slider, technique_dropdown, threshold_slider], outputs=[output1, output2])
demo.launch()