joyjonesmark's picture
app as updated
c3a39d7
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. πŸ“‚")