Spaces:
Running on Zero
Running on Zero
| #!/usr/bin/env python3 | |
| """ | |
| 人脸裁剪处理脚本 | |
| 从单张图像中检测人脸,裁剪并调整大小到指定尺寸 | |
| """ | |
| import os | |
| from PIL import Image | |
| import numpy as np | |
| from flash_head.utils.cpu_face_handler import CPUFaceHandler | |
| def get_scaled_bbox( | |
| bbox, img_w, img_h, ratio: float = 1.0, face_image: Image.Image = None | |
| ): | |
| """ | |
| 根据人脸边界框计算缩放后的裁剪区域 | |
| Args: | |
| bbox: 人脸边界框 [x1, y1, x2, y2] | |
| img_w: 图像宽度 | |
| img_h: 图像高度 | |
| ratio: 缩放比例,数值越大,人脸在画面中的比例越小(周围留白越多) | |
| face_image: PIL Image 对象 | |
| Returns: | |
| 裁剪后的人脸图像 | |
| """ | |
| x1, y1, x2, y2 = bbox | |
| # Calculate center point | |
| center_x = (x1 + x2) / 2 | |
| center_y = (y1 + y2) / 2 | |
| # Calculate width and height | |
| width = x2 - x1 | |
| # Scale width and height | |
| new_width = width * ratio | |
| new_height = new_width | |
| # tile pix | |
| dis_x_left = new_width * 0.5 | |
| dis_x_right = new_width - dis_x_left # 0.5new_width | |
| dis_y_up = new_height * 0.55 | |
| dis_y_down = new_height - dis_y_up # 0.45new_height | |
| # Calculate new coordinates | |
| new_x1 = int(max(0, center_x - dis_x_left)) | |
| new_y1 = int(max(0, center_y - dis_y_up)) | |
| new_x2 = int(min(img_w, center_x + dis_x_right)) | |
| new_y2 = int(min(img_h, center_y + dis_y_down)) | |
| scaled_bbox = [new_x1, new_y1, new_x2, new_y2] | |
| crop_face = face_image.crop(scaled_bbox) | |
| return crop_face | |
| def process_image( | |
| input_path, | |
| face_ratio=2.0, | |
| target_size=(512, 512), | |
| ): | |
| """ | |
| 处理单张图像,进行人脸检测和裁剪 | |
| Args: | |
| input_path: 输入图像路径 | |
| face_ratio: 人脸缩放比例,建议范围:1.5-3.0,默认2.0 | |
| target_size: 输出图像尺寸,默认(512, 512) | |
| Returns: | |
| imgae: 处理后的图像 | |
| """ | |
| # 初始化人脸检测器 | |
| face_detector = CPUFaceHandler() | |
| # 验证输入文件 | |
| if not os.path.isfile(input_path): | |
| raise ValueError(f"File not found: {input_path}") | |
| try: | |
| # 读取图像 | |
| image = Image.open(input_path) | |
| image = image.convert("RGB") | |
| image_rgb = np.array(image) | |
| img_h, img_w = image_rgb.shape[:2] | |
| # 检测人脸 | |
| boxes, scores = face_detector(image_rgb) | |
| if len(boxes) == 0: | |
| raise ValueError("No face detected") | |
| # 转换边界框坐标(从相对坐标转为绝对坐标) | |
| boxes_abs = [ | |
| boxes[0][0] * img_w, | |
| boxes[0][1] * img_h, | |
| boxes[0][2] * img_w, | |
| boxes[0][3] * img_h | |
| ] | |
| # 裁剪人脸 | |
| crop_face = get_scaled_bbox(boxes_abs, img_w, img_h, face_ratio, image) | |
| # 调整大小 | |
| crop_face = crop_face.resize(target_size) | |
| return crop_face | |
| except Exception as e: | |
| raise ValueError(f"Error processing {input_path}: {e}") |