Dzsysop commited on
Commit
29dbb5b
·
1 Parent(s): 7bee81a

webcam - video, not a snapshot

Browse files
Files changed (1) hide show
  1. app.py +62 -27
app.py CHANGED
@@ -2,41 +2,76 @@ import gradio as gr
2
  import cv2
3
  import numpy as np
4
 
 
 
5
  face_cascade = cv2.CascadeClassifier(
6
  cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
7
  )
8
 
9
- def mask_image(image):
10
- """Apply mask to a single image (not streaming)"""
11
- if image is None:
 
 
 
12
  return None
13
 
14
- # Convert to BGR for OpenCV
15
- frame = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
16
- gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
17
 
18
- faces = face_cascade.detectMultiScale(gray, 1.3, 5)
 
19
 
 
 
 
 
 
20
  for (x, y, w, h) in faces:
21
- # Zorro mask
22
- cv2.rectangle(frame, (x, y + int(h*0.35)),
23
- (x + w, y + int(h*0.65)), (0, 0, 0), -1)
24
- # Eye holes
25
- cv2.circle(frame, (x + int(w*0.35), y + int(h*0.5)),
26
- int(w*0.1), (255, 255, 255), -1)
27
- cv2.circle(frame, (x + int(w*0.65), y + int(h*0.5)),
28
- int(w*0.1), (255, 255, 255), -1)
29
-
30
- return cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
31
-
32
- # Simple interface - user clicks "Capture" then "Submit"
33
- demo = gr.Interface(
34
- fn=mask_image,
35
- inputs=gr.Image(sources=["webcam"], type="numpy"),
36
- outputs=gr.Image(),
37
- title="Zorro Mask",
38
- description="1. Allow camera access\n2. Click 'Capture'\n3. Click 'Submit'\n4. See the mask!",
39
- examples=None
40
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
 
42
  demo.launch()
 
2
  import cv2
3
  import numpy as np
4
 
5
+ # Load the face detection model (using OpenCV's built-in classifier)
6
+ # This is a fast, reliable model that works well for real-time applications.
7
  face_cascade = cv2.CascadeClassifier(
8
  cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
9
  )
10
 
11
+ def apply_zorro_mask(frame: np.ndarray) -> np.ndarray:
12
+ """
13
+ This function is called for every frame from your webcam.
14
+ It detects faces and draws a Zorro mask on them.
15
+ """
16
+ if frame is None:
17
  return None
18
 
19
+ # The frame from Gradio is in RGB, but OpenCV uses BGR.
20
+ # Convert to BGR for processing, then back to RGB for display.
21
+ frame_bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
22
 
23
+ # Convert the frame to grayscale, which is required for the face detector
24
+ gray = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2GRAY)
25
 
26
+ # Detect faces in the image
27
+ # The parameters (scaleFactor, minNeighbors) can be tuned for better performance
28
+ faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(60, 60))
29
+
30
+ # Loop over all detected faces and draw the mask
31
  for (x, y, w, h) in faces:
32
+ # --- Draw the black Zorro mask (a rectangle over the eyes) ---
33
+ mask_height = int(h * 0.4) # Make the mask cover the upper part of the face
34
+ mask_y = y + int(h * 0.2) # Position it a bit below the top of the face
35
+ cv2.rectangle(frame_bgr, (x, mask_y), (x + w, mask_y + mask_height), (0, 0, 0), -1) # -1 fills the rectangle
36
+
37
+ # --- Create eye holes (two white circles) ---
38
+ eye_y = mask_y + int(mask_height * 0.5)
39
+ eye_radius = int(w * 0.1)
40
+ # Left eye hole
41
+ cv2.circle(frame_bgr, (x + int(w * 0.35), eye_y), eye_radius, (255, 255, 255), -1)
42
+ # Right eye hole
43
+ cv2.circle(frame_bgr, (x + int(w * 0.65), eye_y), eye_radius, (255, 255, 255), -1)
44
+
45
+ # --- Optional: Draw a stylish "Z" mark on the mask ---
46
+ cv2.putText(frame_bgr, "Z", (x + w - 30, y + h - 20),
47
+ cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 3)
48
+
49
+ # Convert the frame back to RGB for Gradio to display
50
+ frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB)
51
+ return frame_rgb
52
+
53
+ # --- Build the Gradio Interface ---
54
+ # The 'Blocks' API gives us more control than the simple 'Interface' API.
55
+ with gr.Blocks(title="Real-Time Zorro Mask Sandbox") as demo:
56
+ gr.Markdown("# 🎭 Real-Time Zorro Mask Sandbox")
57
+ gr.Markdown("Allow webcam access. The mask will be applied to your face in real-time!")
58
+
59
+ with gr.Row():
60
+ # Input: The live webcam stream. 'streaming=True' is crucial.
61
+ input_webcam = gr.Image(sources=["webcam"], streaming=True, label="Your Webcam Feed")
62
+ # Output: Where the processed video stream will be shown.
63
+ output_video = gr.Image(label="Live Zorro Mask Output")
64
+
65
+ # This is the magic line that creates the real-time loop.
66
+ # It calls 'apply_zorro_mask' for every new frame from 'input_webcam'
67
+ # and sends the result to 'output_video'.
68
+ input_webcam.stream(
69
+ fn=apply_zorro_mask,
70
+ inputs=input_webcam,
71
+ outputs=output_video,
72
+ time_limit=10, # Optional: Stops the stream after 10 seconds if no new frames
73
+ stream_every=0.05 # Optional: Controls the delay between frames (in seconds). Lower is faster.
74
+ )
75
 
76
+ # Launch the app
77
  demo.launch()