# app.py
import streamlit as st
import cv2
import numpy as np
from PIL import Image
from io import BytesIO
import mediapipe as mp # NEW for background removal
# ----- Custom CSS Styling -----
def local_css():
st.markdown("""
""", unsafe_allow_html=True)
def sidebar_profiles():
st.sidebar.markdown("### ๐Author: Maria Nadeem๐")
st.sidebar.markdown("### ๐ Connect With Me")
st.sidebar.markdown("""
""", unsafe_allow_html=True)
# ----- Filters Functions -----
def apply_grayscale(img):
return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
def apply_blur(img, ksize):
return cv2.GaussianBlur(img, (ksize, ksize), 0)
def apply_canny(img, threshold1, threshold2):
return cv2.Canny(img, threshold1, threshold2)
def apply_sepia(img):
kernel = np.array([[0.272, 0.534, 0.131],
[0.349, 0.686, 0.168],
[0.393, 0.769, 0.189]])
sepia_img = cv2.transform(img, kernel)
sepia_img = np.clip(sepia_img, 0, 255)
return sepia_img
def apply_pencil_sketch(img):
if len(img.shape) == 3:
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
gray_img = img
inv_img = 255 - gray_img
blur_img = cv2.GaussianBlur(inv_img, (21, 21), 0)
sketch = cv2.divide(gray_img, 255 - blur_img, scale=256)
return sketch
def apply_invert(img):
return cv2.bitwise_not(img)
def apply_background_removal(img):
mp_selfie_segmentation = mp.solutions.selfie_segmentation
with mp_selfie_segmentation.SelfieSegmentation(model_selection=1) as selfie_segmentation:
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
results = selfie_segmentation.process(rgb_img)
mask = results.segmentation_mask
condition = mask > 0.5
bg_color = np.ones(img.shape, dtype=np.uint8) * 255
output_img = np.where(condition[..., None], img, bg_color)
return output_img
# Convert to PIL
def convert_image(img):
if len(img.shape) == 2:
return Image.fromarray(img)
else:
return Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# Downloadable image
def download_image(img):
buf = BytesIO()
img.save(buf, format="PNG")
byte_im = buf.getvalue()
return byte_im
# ----- Streamlit App Starts Here -----
def main():
st.set_page_config(page_title="Advanced Image Filter Studio", page_icon="๐จ", layout="wide")
local_css()
st.title("๐จ Advanced Image Filter Studio")
st.write("Upload an image, apply **amazing filters**, and download your creation!")
# Sidebar Profiles
sidebar_profiles()
# Sidebar
st.sidebar.header("1. Upload Image")
uploaded_file = st.sidebar.file_uploader("Choose an image", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
opencv_image = cv2.imdecode(file_bytes, 1)
# Filters Section
st.sidebar.header("2. Choose Filters")
grayscale = st.sidebar.checkbox("Grayscale")
blur = st.sidebar.checkbox("Blur")
canny = st.sidebar.checkbox("Edge Detection")
sepia = st.sidebar.checkbox("Sepia Effect")
sketch = st.sidebar.checkbox("Pencil Sketch")
invert = st.sidebar.checkbox("Invert Colors")
remove_bg = st.sidebar.checkbox("Remove Background (Simple)")
st.sidebar.header("3. Filter Parameters")
blur_strength = st.sidebar.slider("Blur Intensity (odd numbers)", 1, 49, 15, step=2)
threshold1 = st.sidebar.slider("Canny Threshold1", 50, 300, 100)
threshold2 = st.sidebar.slider("Canny Threshold2", 50, 300, 150)
# Process Image
final_image = opencv_image.copy()
with st.spinner("๐๏ธ Applying Filters..."):
if grayscale:
final_image = apply_grayscale(final_image)
if blur:
if len(final_image.shape) == 2:
final_image = cv2.cvtColor(final_image, cv2.COLOR_GRAY2BGR)
final_image = apply_blur(final_image, blur_strength)
if canny:
if len(final_image.shape) != 2:
final_image = cv2.cvtColor(final_image, cv2.COLOR_BGR2GRAY)
final_image = apply_canny(final_image, threshold1, threshold2)
if sepia:
if len(final_image.shape) == 2:
final_image = cv2.cvtColor(final_image, cv2.COLOR_GRAY2BGR)
final_image = apply_sepia(final_image)
if sketch:
if len(final_image.shape) != 2:
final_image = cv2.cvtColor(final_image, cv2.COLOR_BGR2GRAY)
final_image = apply_pencil_sketch(final_image)
if invert:
final_image = apply_invert(final_image)
if remove_bg:
if len(final_image.shape) != 3 or final_image.shape[2] != 3:
final_image = cv2.cvtColor(final_image, cv2.COLOR_GRAY2BGR)
final_image = apply_background_removal(final_image)
# Columns to show images
col1, col2 = st.columns(2)
with col1:
st.subheader("Original Image")
st.image(uploaded_file, use_column_width=True)
with col2:
st.subheader("Processed Image")
final_pil = convert_image(final_image)
st.image(final_pil, use_column_width=True)
# Download button
st.markdown("---")
st.download_button(
label="๐ฅ Download Processed Image",
data=download_image(final_pil),
file_name="processed_image.png",
mime="image/png"
)
else:
st.info("๐ Please upload an image from the sidebar to get started.")
if __name__ == "__main__":
main()