import cv2 import numpy as np import os import subprocess import mediapipe as mp def crop_and_resize_single_face(frame, face): frame_height, frame_width = frame.shape[:2] x, y, w, h = face face_center_x = x + w // 2 face_center_y = y + h // 2 # Cálculo da proporção desejada (9:16) target_aspect_ratio = 9 / 16 # Cálculo da área de corte para evitar barras pretas if frame_width / frame_height > target_aspect_ratio: new_width = int(frame_height * target_aspect_ratio) new_height = frame_height else: new_width = frame_width new_height = int(frame_width / target_aspect_ratio) # Garantir que o corte esteja dentro dos limites crop_x = max(0, min(face_center_x - new_width // 2, frame_width - new_width)) crop_y = max(0, min(face_center_y - new_height // 2, frame_height - new_height)) crop_x2 = crop_x + new_width crop_y2 = crop_y + new_height # Recorte e redimensionamento para 1080x1920 (9:16) crop_img = frame[crop_y:crop_y2, crop_x:crop_x2] resized = cv2.resize(crop_img, (1080, 1920), interpolation=cv2.INTER_AREA) return resized def resize_with_padding(frame): frame_height, frame_width = frame.shape[:2] target_aspect_ratio = 9 / 16 if frame_width / frame_height > target_aspect_ratio: new_width = frame_width new_height = int(frame_width / target_aspect_ratio) else: new_height = frame_height new_width = int(frame_height * target_aspect_ratio) # Criação de uma tela preta result = np.zeros((new_height, new_width, 3), dtype=np.uint8) # Cálculo das margens pad_top = (new_height - frame_height) // 2 pad_left = (new_width - frame_width) // 2 # Colocar o frame original na tela result[pad_top:pad_top+frame_height, pad_left:pad_left+frame_width] = frame # Redimensionar para as dimensões finais return cv2.resize(result, (1080, 1920), interpolation=cv2.INTER_AREA) def detect_face_or_body(frame, face_detection, face_mesh, pose): # Converter a imagem para RGB frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Processar a detecção de rosto results_face_detection = face_detection.process(frame_rgb) results_face_mesh = face_mesh.process(frame_rgb) results_pose = pose.process(frame_rgb) detections = [] # Usar a detecção de rosto se disponível if results_face_detection.detections: # Usar o primeiro rosto detectado detection = results_face_detection.detections[0] bbox = detection.location_data.relative_bounding_box x_min = int(bbox.xmin * frame.shape[1]) y_min = int(bbox.ymin * frame.shape[0]) width = int(bbox.width * frame.shape[1]) height = int(bbox.height * frame.shape[0]) detections.append((x_min, y_min, width, height)) # Usar landmarks do face mesh se disponível if results_face_mesh.multi_face_landmarks: landmarks = results_face_mesh.multi_face_landmarks[0].landmark # Coordenadas do rosto baseadas nos pontos-chave (landmarks) x_coords = [int(landmark.x * frame.shape[1]) for landmark in landmarks] y_coords = [int(landmark.y * frame.shape[0]) for landmark in landmarks] x_min, x_max = min(x_coords), max(x_coords) y_min, y_max = min(y_coords), max(y_coords) width = x_max - x_min height = y_max - y_min detections.append((x_min, y_min, width, height)) # Se nenhum rosto for detectado, usar a pose para estimar o corpo if results_pose.pose_landmarks: x_coords = [lmk.x for lmk in results_pose.pose_landmarks.landmark] y_coords = [lmk.y for lmk in results_pose.pose_landmarks.landmark] x_min = int(min(x_coords) * frame.shape[1]) x_max = int(max(x_coords) * frame.shape[1]) y_min = int(min(y_coords) * frame.shape[0]) y_max = int(max(y_coords) * frame.shape[0]) width = x_max - x_min height = y_max - y_min detections.append((x_min, y_min, width, height)) # Se nada for detectado, retornar uma lista vazia return detections if detections else None def crop_center_zoom(frame): """ Crops the center of the frame to fill 9:16 aspect ratio (Zoom effect). """ frame_height, frame_width = frame.shape[:2] target_aspect_ratio = 9 / 16 # Calculate crop dimensions to FILL the target ratio if frame_width / frame_height > target_aspect_ratio: # Source is wider than target (e.g. 16:9 source, 9:16 target) -> Crop Width new_width = int(frame_height * target_aspect_ratio) new_height = frame_height else: # Source is taller than target -> Crop Height new_width = frame_width new_height = int(frame_width / target_aspect_ratio) start_x = (frame_width - new_width) // 2 start_y = (frame_height - new_height) // 2 # Ensure bounds start_x = max(0, start_x) start_y = max(0, start_y) crop_img = frame[start_y:start_y+new_height, start_x:start_x+new_width] # Resize to final 1080x1920 return cv2.resize(crop_img, (1080, 1920), interpolation=cv2.INTER_AREA)