-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImageFilterApp.py
More file actions
92 lines (75 loc) Β· 3.36 KB
/
ImageFilterApp.py
File metadata and controls
92 lines (75 loc) Β· 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import streamlit as st
import cv2
import numpy as np
from PIL import Image
st.set_page_config(page_title="πΌοΈ Image Blurring & Sharpening App", layout="centered")
st.title("π§ͺ Image Filtering Playground")
st.markdown("""
Welcome to the **Image Blurring and Sharpening App**!
Here you can upload an image and explore how different filters affect it.
π _Great for learning computer vision basics!_
""")
uploaded_file = st.file_uploader("π€ Upload an image", type=["jpg", "png", "jpeg"])
if uploaded_file:
file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
img = cv2.imdecode(file_bytes, 1)
st.markdown("## π οΈ Choose a Filter")
filter_type = st.selectbox(
"Select Filter", ["None", "Gaussian Blur", "Median Blur", "Sharpening"]
)
result_img = img.copy()
if filter_type == "Gaussian Blur":
st.info(
"π Gaussian Blur: Averages neighboring pixel values to smooth image and remove noise."
)
kx = st.slider("Kernel Size X", 1, 31, 3, step=2)
ky = st.slider("Kernel Size Y", 1, 31, 3, step=2)
sigma = st.slider("Sigma (Blur Strength)", 0.0, 5.0, 1.0)
result_img = cv2.GaussianBlur(img, (kx, ky), sigma)
elif filter_type == "Median Blur":
st.info(
"π― Median Blur: Uses the **median** of surrounding pixels β great for salt & pepper noise!"
)
k = st.slider("Kernel Size", 1, 31, 3, step=2)
result_img = cv2.medianBlur(img, k)
elif filter_type == "Sharpening":
st.info("βοΈ Sharpening Filter: Enhances edges and brings out details.")
ddepth_map = {
"Same as input (-1)": -1,
"8-bit unsigned (CV_8U)": cv2.CV_8U,
"16-bit signed (CV_16S)": cv2.CV_16S,
"32-bit float (CV_32F)": cv2.CV_32F,
}
ddepth_label = st.selectbox("Select Output Depth", list(ddepth_map.keys()))
ddepth = ddepth_map[ddepth_label]
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
result_img = cv2.filter2D(img, ddepth, kernel)
# Handle visualization of higher-depth outputs (CV_16S, CV_32F)
if ddepth in [cv2.CV_16S, cv2.CV_32F]:
# Normalize to 0β255 and convert back to uint8
norm_img = cv2.normalize(result_img, None, 0, 255, cv2.NORM_MINMAX)
result_img = np.uint8(norm_img)
if filter_type != "None":
st.markdown("### π Original vs. Processed Image")
col1, col2 = st.columns(2)
with col1:
st.image(img[:, :, ::-1], caption="Original", use_container_width=True)
with col2:
st.image(
result_img[:, :, ::-1],
caption=f"{filter_type} Applied",
use_container_width=True,
)
result_pil = Image.fromarray(cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB))
st.download_button(
"π₯ Download Processed Image",
data=result_pil.tobytes(),
file_name="processed_image.jpg",
mime="image/jpeg",
)
else:
st.image(img[:, :, ::-1], caption="Original Image", use_container_width=True)
st.markdown("---")
st.caption("Built with β€οΈ using OpenCV + Streamlit")
else:
st.warning("π Upload an image to begin.")