Spaces:
Running
Running
File size: 5,265 Bytes
80b326d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
import cv2
import numpy as np
import os
import sys
from contextlib import contextmanager
import warnings
# Suppress warnings
warnings.filterwarnings("ignore")
try:
from insightface.app import FaceAnalysis
INSIGHTFACE_AVAILABLE = True
except ImportError:
INSIGHTFACE_AVAILABLE = False
app = None
@contextmanager
def suppress_stdout_stderr():
"""A context manager that redirects stdout and stderr to devnull"""
with open(os.devnull, "w") as devnull:
old_stdout = sys.stdout
old_stderr = sys.stderr
sys.stdout = devnull
sys.stderr = devnull
try:
yield
finally:
sys.stdout = old_stdout
sys.stderr = old_stderr
def init_insightface():
"""Explicit initialization if needed outside import."""
global app
if not INSIGHTFACE_AVAILABLE:
raise ImportError("InsightFace not installed. Please install it.")
if app is None:
# Provider options to reduce logging if possible (often needs env var)
# But redirection is safer for C++ logs
providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
try:
import onnxruntime as ort
available = ort.get_available_providers()
print(f"InsightFace: Available ONNX Providers: {available}")
if 'CUDAExecutionProvider' not in available:
print("WARNING: CUDAExecutionProvider not found. InsightFace will likely run on CPU.")
print("To fix, install onnxruntime-gpu: pip install onnxruntime-gpu")
except Exception as e:
print(f"InsightFace: Could not check available providers: {e}")
with suppress_stdout_stderr():
app = FaceAnalysis(name='buffalo_l', providers=providers)
app.prepare(ctx_id=0, det_size=(640, 640))
return app
def detect_faces_insightface(frame):
"""
Detect faces using InsightFace.
Returns a list of dicts with 'bbox' and 'kps'.
bbox is [x1, y1, x2, y2], kps is 5 keypoints (eyes, nose, mouth corners).
"""
global app
if app is None:
init_insightface()
faces = app.get(frame)
results = []
for face in faces:
# Convert bbox to int
bbox = face.bbox.astype(int)
res = {
'bbox': bbox, # [x1, y1, x2, y2]
'kps': face.kps,
'det_score': face.det_score
}
if hasattr(face, 'landmark_2d_106') and face.landmark_2d_106 is not None:
res['landmark_2d_106'] = face.landmark_2d_106
if hasattr(face, 'landmark_3d_68') and face.landmark_3d_68 is not None:
res['landmark_3d_68'] = face.landmark_3d_68
results.append(res)
return results
def crop_and_resize_insightface(frame, face_bbox, target_width=1080, target_height=1920):
"""
Crops and resizes the frame to target dimensions centered on the face_bbox.
face_bbox: [x1, y1, x2, y2]
"""
h, w, _ = frame.shape
x1, y1, x2, y2 = face_bbox
face_center_x = (x1 + x2) // 2
face_center_y = (y1 + y2) // 2
# Calculate crop area based on target aspect ratio and face position
# We want to keep the face roughly in the upper-middle or center?
# Usually center for simple implementation, or slightly upper for "talking head".
# Logic similar to one_face.py but adapted
# Determine the scaling factor to ensure the crop covers the target height
# Ideally we want the height of the video to match the target height after resize
# But usually we source from landscape (16:9) to portrait (9:16).
# We need to crop a 9:16 area from the source.
# Calculate source crop height/width maintaining 9:16 ratio
# Trying to maximize height usage of the source frame usually.
# Let's say we want to use the full height of the source if possible
source_h = h
source_w = int(source_h * (target_width / target_height))
if source_w > w:
# If the calculated width is wider than the source image, we are limited by width
source_w = w
source_h = int(source_w * (target_height / target_width))
# Calculate top-left corner of the crop
crop_x1 = face_center_x - (source_w // 2)
crop_y1 = face_center_y - (source_h // 2) # Center vertically on face
# Adjust to stay within bounds
if crop_x1 < 0:
crop_x1 = 0
elif crop_x1 + source_w > w:
crop_x1 = w - source_w
if crop_y1 < 0:
crop_y1 = 0
elif crop_y1 + source_h > h:
crop_y1 = h - source_h
crop_x2 = crop_x1 + source_w
crop_y2 = crop_y1 + source_h
# Crop
cropped = frame[crop_y1:crop_y2, crop_x1:crop_x2]
# Resize to final target
result = cv2.resize(cropped, (target_width, target_height), interpolation=cv2.INTER_LINEAR)
return result
if __name__ == "__main__":
# Test block
print("Testing InsightFace...")
# Create a dummy image or try to load one if available, but for now just print config
print("InsightFace initialized.")
|