Face_Blurring / src /streamlit_app.py
mohamedamgad2002's picture
Update src/streamlit_app.py
0bcca77 verified
# face_blur_app.py
import streamlit as st
from mtcnn import MTCNN
import cv2
import numpy as np
from PIL import Image
import requests
from io import BytesIO
def enhance_contrast(img_rgb_uint8):
lab = cv2.cvtColor(img_rgb_uint8, cv2.COLOR_RGB2LAB)
l_channel, a_channel, b_channel = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cl = clahe.apply(l_channel)
lab_enhanced = cv2.merge((cl, a_channel, b_channel))
img_rgb_enhanced = cv2.cvtColor(lab_enhanced, cv2.COLOR_LAB2RGB)
return img_rgb_enhanced
def detect_faces(img_rgb_uint8):
detector = MTCNN()
faces = detector.detect_faces(img_rgb_uint8)
return faces
def blur_faces_on_image(img_rgb_uint8, faces):
img_copy = img_rgb_uint8.copy()
for face in faces:
x, y, width, height = face['box']
x1, y1 = x + width, y + height
y_start, y_end = max(0, y), min(img_copy.shape[0], y1)
x_start, x_end = max(0, x), min(img_copy.shape[1], x1)
if x_start >= x_end or y_start >= y_end:
continue
face_region = img_copy[y_start:y_end, x_start:x_end]
k_size_w = min(width, height) // 4 * 2 + 1
k_size_h = k_size_w
if k_size_w < 3:
k_size_w = k_size_h = 3
if face_region.size > 0:
blurred_face = cv2.GaussianBlur(face_region, (k_size_w, k_size_h), 30)
img_copy[y_start:y_end, x_start:x_end] = blurred_face
return img_copy
st.set_page_config(layout="wide", page_title="Face Blurring App")
st.title("Face Blurring Application")
st.markdown("""
Upload an image or provide an image URL to detect and blur faces.
The "Original Processed Image" is the version (resized and contrast-enhanced) that the face detector sees.
""")
uploaded_file = st.sidebar.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
image_url = st.sidebar.text_input("Or enter image URL", placeholder="e.g., https://example.com/image.jpg")
process_button = st.sidebar.button("Blur Faces", use_container_width=True, type="primary")
if 'original_image_to_display' not in st.session_state:
st.session_state.original_image_to_display = None
if 'blurred_image_to_display' not in st.session_state:
st.session_state.blurred_image_to_display = None
col1, col2 = st.columns(2)
if process_button:
pil_image = None
error_message = ""
if uploaded_file is not None:
try:
pil_image = Image.open(uploaded_file).convert("RGB")
st.sidebar.success("Image uploaded successfully!")
except Exception as e:
error_message = f"Error opening uploaded file: {e}"
st.sidebar.error(error_message)
elif image_url:
try:
response = requests.get(image_url, timeout=10)
response.raise_for_status()
pil_image = Image.open(BytesIO(response.content)).convert("RGB")
st.sidebar.success("Image downloaded successfully!")
except requests.exceptions.RequestException as e:
error_message = f"Error fetching image from URL: {e}"
st.sidebar.error(error_message)
except Exception as e:
error_message = f"Error opening image from URL: {e}"
st.sidebar.error(error_message)
else:
error_message = "Please upload an image or provide an image URL."
st.sidebar.warning(error_message)
if pil_image is not None:
img_np_raw = np.array(pil_image)
img_resized_uint8 = cv2.resize(img_np_raw, (320, 320), interpolation=cv2.INTER_LINEAR)
img_processed_for_detection_uint8 = enhance_contrast(img_resized_uint8)
st.session_state.original_image_to_display = img_processed_for_detection_uint8.copy()
with st.spinner('Detecting faces...'):
faces = detect_faces(img_processed_for_detection_uint8)
if not faces:
st.info("No faces detected in the image.")
st.session_state.blurred_image_to_display = st.session_state.original_image_to_display.copy()
else:
st.success(f"Detected {len(faces)} face(s). Blurring them now...")
img_blurred_np_uint8 = blur_faces_on_image(img_processed_for_detection_uint8.copy(), faces)
st.session_state.blurred_image_to_display = img_blurred_np_uint8
else:
st.session_state.original_image_to_display = None
st.session_state.blurred_image_to_display = None
with col1:
st.subheader("Original Processed Image")
if st.session_state.original_image_to_display is not None:
st.image(st.session_state.original_image_to_display, use_column_width=True,
caption="Image after resizing and contrast enhancement (input to detector)")
else:
st.info("Upload an image or provide a URL and click 'Blur Faces'.")
with col2:
st.subheader("Blurred Image")
if st.session_state.blurred_image_to_display is not None:
st.image(st.session_state.blurred_image_to_display, use_column_width=True,
caption="Image with detected faces blurred")
else:
st.info("Blurred image will appear here after processing.")
st.sidebar.markdown("---")
st.sidebar.markdown("Built with [Streamlit](https://streamlit.io) and MTCNN.")