import streamlit as st import cv2 import numpy as np from PIL import Image import io # App title and emojis st.title("📸 Image Processing App 🎨") st.write("Upload an image, apply filters, and download the processed image! ✨") # Sidebar for feature selection st.sidebar.header("🎨 Filter Options") filter_type = st.sidebar.selectbox( "Select a filter:", [ "Blur", "Edge Detection (Canny)", "Grayscale", "Sharpen", "Sepia", "Invert Colors", "Brightness Adjustment", "Contrast Adjustment", ], ) # Upload image uploaded_file = st.file_uploader(".Upload an image 🖼️", type=["jpg", "jpeg", "png"]) if uploaded_file is not None: # Convert the file to an OpenCV image file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8) img = cv2.imdecode(file_bytes, 1) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Convert BGR to RGB # Display original image col1, col2 = st.columns(2) with col1: st.subheader("Original Image 📷") st.image(img, use_container_width=True) # Apply filters based on user selection processed_img = img.copy() if filter_type == "Blur": blur_type = st.sidebar.selectbox( "Blur Type", ["Gaussian Blur", "Average Blur", "Median Blur", "Bilateral Filter"] ) if blur_type == "Gaussian Blur": kernel_size = st.sidebar.slider("Kernel Size 🔍", 1, 31, 5, step=2) sigma_x = st.sidebar.slider("Sigma X (Standard Deviation)", 0, 10, 0) processed_img = cv2.GaussianBlur(processed_img, (kernel_size, kernel_size), sigma_x) elif blur_type == "Average Blur": kernel_size = st.sidebar.slider("Kernel Size 🔍", 1, 31, 5, step=2) processed_img = cv2.blur(processed_img, (kernel_size, kernel_size)) elif blur_type == "Median Blur": kernel_size = st.sidebar.slider("Kernel Size 🔍", 1, 31, 5, step=2) processed_img = cv2.medianBlur(processed_img, kernel_size) elif blur_type == "Bilateral Filter": diameter = st.sidebar.slider("Diameter", 1, 31, 9, step=2) sigma_color = st.sidebar.slider("Sigma Color", 1, 200, 75) sigma_space = st.sidebar.slider("Sigma Space", 1, 200, 75) processed_img = cv2.bilateralFilter(processed_img, diameter, sigma_color, sigma_space) elif filter_type == "Edge Detection (Canny)": lower_threshold = st.sidebar.slider("Lower Threshold ⬇️", 0, 255, 100) upper_threshold = st.sidebar.slider("Upper Threshold ⬆️", 0, 255, 200) processed_img = cv2.Canny(processed_img, lower_threshold, upper_threshold) elif filter_type == "Grayscale": grayscale_method = st.sidebar.selectbox( "Grayscale Method", ["Weighted Average", "Simple Average"] ) if grayscale_method == "Weighted Average": processed_img = cv2.cvtColor(processed_img, cv2.COLOR_RGB2GRAY) else: processed_img = np.mean(processed_img, axis=2).astype(np.uint8) elif filter_type == "Sharpen": sharpness = st.sidebar.slider("Sharpness Intensity", 1.0, 10.0, 1.0) kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]) * sharpness processed_img = cv2.filter2D(processed_img, -1, kernel) elif filter_type == "Sepia": sepia_intensity = st.sidebar.slider("Sepia Intensity", 0.1, 1.0, 1.0) sepia_filter = ( np.array( [[0.272, 0.534, 0.131], [0.349, 0.686, 0.168], [0.393, 0.769, 0.189]] ) * sepia_intensity ) processed_img = cv2.transform(processed_img, sepia_filter) processed_img = np.clip(processed_img, 0, 255) elif filter_type == "Invert Colors": blend_factor = st.sidebar.slider("Inversion Blend Factor", 0.0, 1.0, 1.0) inverted_img = 255 - processed_img processed_img = cv2.addWeighted( processed_img, 1 - blend_factor, inverted_img, blend_factor, 0 ) elif filter_type == "Brightness Adjustment": brightness = st.sidebar.slider("Brightness ☀️", -100, 100, 0) processed_img = cv2.convertScaleAbs(processed_img, alpha=1, beta=brightness) elif filter_type == "Contrast Adjustment": contrast = st.sidebar.slider("Contrast ⚡", 0.1, 3.0, 1.0, step=0.1) processed_img = cv2.convertScaleAbs(processed_img, alpha=contrast, beta=0) # Display processed image with col2: st.subheader("Processed Image 🎯") st.image(processed_img, use_container_width=True) # Download button for processed image st.markdown("---") st.subheader("Download Processed Image 💾") buf = io.BytesIO() pil_img = Image.fromarray(processed_img) pil_img.save(buf, format="PNG") byte_im = buf.getvalue() st.download_button( label="📥 Download Image", data=byte_im, file_name="processed_image.png", mime="image/png", ) else: st.info("Please upload an image to get started. 📂")