partyaap / app.py
RICHERGIRL's picture
Update app.py
c5d7c78 verified
import cv2
import numpy as np
import mediapipe as mp
import gradio as gr
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(
static_image_mode=False,
max_num_faces=1,
refine_landmarks=True,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
def overlay_mask(image, mask_img, landmarks):
h, w, _ = image.shape
if not landmarks:
return image
# Define landmark indices for key points
left_cheek_idx = 234 # left cheek
right_cheek_idx = 454 # right cheek
top_idx = 10 # nose bridge or forehead, for top alignment
# Get coordinates of key points
left = landmarks[left_cheek_idx]
right = landmarks[right_cheek_idx]
top = landmarks[top_idx]
# Normalize the coordinates to pixel positions
left = (int(left.x * w), int(left.y * h))
right = (int(right.x * w), int(right.y * h))
top = (int(top.x * w), int(top.y * h))
# Calculate the width and height of the mask dynamically
mask_width = int(np.linalg.norm(np.array(right) - np.array(left))) # Distance between cheeks
mask_height = int(1.5 * np.linalg.norm(np.array(top) - np.array(((left[0] + right[0]) // 2, (left[1] + right[1]) // 2)))) # Height based on forehead
# Resize the mask to the calculated width and height
resized_mask = cv2.resize(mask_img, (mask_width, mask_height))
# Calculate the center of the mask on the face
center_x = (left[0] + right[0]) // 2
center_y = (left[1] + right[1]) // 2
top_left_x = center_x - mask_width // 2
top_left_y = center_y - mask_height // 2
# Overlay mask with alpha blending (assumes the mask has an alpha channel)
for i in range(mask_height):
for j in range(mask_width):
if 0 <= top_left_y + i < h and 0 <= top_left_x + j < w:
alpha = resized_mask[i, j, 3] / 255.0 # assuming mask has alpha channel
image[top_left_y + i, top_left_x + j] = (
alpha * resized_mask[i, j, :3] + (1 - alpha) * image[top_left_y + i, top_left_x + j]
)
return image
# Process function
def process(image):
if image is None:
return None
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = face_mesh.process(image_rgb)
if results.multi_face_landmarks:
landmarks = results.multi_face_landmarks[0].landmark
# Load and process your mask PNG with alpha channel
mask_img = cv2.imread("mask.png", cv2.IMREAD_UNCHANGED)
image = overlay_mask(image, mask_img, landmarks)
return image
# Gradio UI
iface = gr.Interface(
fn=process,
inputs=gr.Image(type="numpy"), # Updated line for camera input
outputs="image",
live=True
)
iface.launch()