dev / app.py
Dzsysop's picture
webcam - video, not a snapshot
29dbb5b
Raw
History Blame
3.37 kB
import gradio as gr
import cv2
import numpy as np
# Load the face detection model (using OpenCV's built-in classifier)
# This is a fast, reliable model that works well for real-time applications.
face_cascade = cv2.CascadeClassifier(
cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
)
def apply_zorro_mask(frame: np.ndarray) -> np.ndarray:
"""
This function is called for every frame from your webcam.
It detects faces and draws a Zorro mask on them.
"""
if frame is None:
return None
# The frame from Gradio is in RGB, but OpenCV uses BGR.
# Convert to BGR for processing, then back to RGB for display.
frame_bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
# Convert the frame to grayscale, which is required for the face detector
gray = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2GRAY)
# Detect faces in the image
# The parameters (scaleFactor, minNeighbors) can be tuned for better performance
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(60, 60))
# Loop over all detected faces and draw the mask
for (x, y, w, h) in faces:
# --- Draw the black Zorro mask (a rectangle over the eyes) ---
mask_height = int(h * 0.4) # Make the mask cover the upper part of the face
mask_y = y + int(h * 0.2) # Position it a bit below the top of the face
cv2.rectangle(frame_bgr, (x, mask_y), (x + w, mask_y + mask_height), (0, 0, 0), -1) # -1 fills the rectangle
# --- Create eye holes (two white circles) ---
eye_y = mask_y + int(mask_height * 0.5)
eye_radius = int(w * 0.1)
# Left eye hole
cv2.circle(frame_bgr, (x + int(w * 0.35), eye_y), eye_radius, (255, 255, 255), -1)
# Right eye hole
cv2.circle(frame_bgr, (x + int(w * 0.65), eye_y), eye_radius, (255, 255, 255), -1)
# --- Optional: Draw a stylish "Z" mark on the mask ---
cv2.putText(frame_bgr, "Z", (x + w - 30, y + h - 20),
cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 3)
# Convert the frame back to RGB for Gradio to display
frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB)
return frame_rgb
# --- Build the Gradio Interface ---
# The 'Blocks' API gives us more control than the simple 'Interface' API.
with gr.Blocks(title="Real-Time Zorro Mask Sandbox") as demo:
gr.Markdown("# 🎭 Real-Time Zorro Mask Sandbox")
gr.Markdown("Allow webcam access. The mask will be applied to your face in real-time!")
with gr.Row():
# Input: The live webcam stream. 'streaming=True' is crucial.
input_webcam = gr.Image(sources=["webcam"], streaming=True, label="Your Webcam Feed")
# Output: Where the processed video stream will be shown.
output_video = gr.Image(label="Live Zorro Mask Output")
# This is the magic line that creates the real-time loop.
# It calls 'apply_zorro_mask' for every new frame from 'input_webcam'
# and sends the result to 'output_video'.
input_webcam.stream(
fn=apply_zorro_mask,
inputs=input_webcam,
outputs=output_video,
time_limit=10, # Optional: Stops the stream after 10 seconds if no new frames
stream_every=0.05 # Optional: Controls the delay between frames (in seconds). Lower is faster.
)
# Launch the app
demo.launch()