当前位置: 首页 > news >正文

dlib检测视频中的人脸并裁剪为图片保存

环境要求

找个带有基本cv配置的虚拟环境安装上dlib依赖的人脸检测的基础环境即可,主要是:

pip install boost dlib opencv-python

缺的按提示安装。

demo

设置好视频路径和图像保存路径,裁剪尺寸(默认256)以及裁剪帧数(默认64),可以直接运行:

import os
import random
import cv2
import dlib
from imutils.face_utils import FaceAligner, rect_to_bb
from tqdm import tqdm  # 引入tqdm库# 配置路径
dataset_path = r'D:\python_project\face-parsing\dataset'  # 原始数据集路径
output_path = r'D:\python_project\face-parsing\dataset\results'  # 输出路径
crop_size = 256  # 人脸裁剪后的大小# 获取人脸对齐器
def get_face(fa, image):detector = dlib.get_frontal_face_detector()  # 获取人脸检测器gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 将图像转换为灰度图thresh = gray.shape[0] // 4  # 设置阈值rects = detector(gray, 2)  # 检测人脸face_aligned = None  # 初始化返回的人脸图像for rect in rects:(x, y, w, h) = rect_to_bb(rect)  # 获取人脸的坐标if w > thresh:  # 如果人脸宽度大于阈值,则认为是有效人脸face_aligned = fa.align(image, gray, rect)  # 对齐人脸break  # 只处理第一张人脸return face_aligned# 处理视频
def process_video(video_path, save_dir, fa):cap = cv2.VideoCapture(video_path)  # 打开视频文件total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))  # 获取总帧数if total_frames < 64:  # 如果视频帧数少于64,跳过该视频print(f"Warning: Video '{video_path}' has less than 64 frames. Skipping.")cap.release()  # 释放视频文件returnstart_frame = random.randint(0, total_frames - 64)  # 随机选择起始帧frames = []for i in range(start_frame, start_frame + 64):  # 提取连续的64帧cap.set(cv2.CAP_PROP_POS_FRAMES, i)  # 设置当前读取的帧数ret, frame = cap.read()  # 读取该帧if ret:frames.append(frame)  # 保存读取到的帧cap.release()  # 释放视频文件for i, frame in enumerate(tqdm(frames, desc=f"Processing frames from {os.path.basename(video_path)}")):  # 加入进度条face_aligned = get_face(fa, frame)  # 对齐每一帧中的人脸if face_aligned is not None:img_name = f"{i + 1:05d}.jpg"  # 给每一帧命名save_path = os.path.join(save_dir, img_name)  # 保存路径cv2.imwrite(save_path, face_aligned)  # 保存图像else:print(f"Face not found in frame {i + 1}")  # 如果没有检测到人脸# 主函数:处理数据集中的所有视频
def align_dlib():predictor = dlib.shape_predictor(r"../weights/shape_predictor_68_face_landmarks.dat")  # 加载预测器fa = FaceAligner(predictor, desiredFaceWidth=crop_size)  # 初始化人脸对齐器# 遍历主目录(Training、Development、Testing)main_dirs = ['Testing']for main_dir in main_dirs:main_dir_path = os.path.join(dataset_path, main_dir)if not os.path.isdir(main_dir_path):print(f"Skipping non-directory: {main_dir_path}")continue# 遍历每个子目录(Northwind、Freeform 等)sub_dirs = os.listdir(main_dir_path)# for sub_dir in sub_dirs:#     sub_dir_path = os.path.join(main_dir_path, sub_dir)#     if not os.path.isdir(sub_dir_path):#         print(f"Skipping non-directory: {sub_dir_path}")#         continue# 遍历视频文件夹中的每个视频文件video_files = os.listdir(main_dir_path)for video_file in video_files:video_path = os.path.join(main_dir_path, video_file)if not os.path.isfile(video_path):continue# 获取视频名称(去掉文件扩展名)video_name = os.path.splitext(video_file)[0]# 构建保存路径: datasets/avec14/Training/Northwind/236_1_Northwind_videosave_path = os.path.join(output_path, main_dir, video_name)os.makedirs(save_path, exist_ok=True)  # 创建保存文件夹print(f"Processing video: {video_path}")process_video(video_path, save_path, fa)  # 处理该视频if __name__ == "__main__":align_dlib()  # 调用主函数进行处理

debug

eyesCenter在cv2.getRotationMatrix2D中一些版本要求是传入float型,直接传整型可能报错:

Traceback (most recent call last):
File “D:\python_project\face-parsing\utils\face_dect.py”, line 99, in
align_dlib() # 调用主函数进行处理
File “D:\python_project\face-parsing\utils\face_dect.py”, line 95, in align_dlib
process_video(video_path, save_path, fa) # 处理该视频
File “D:\python_project\face-parsing\utils\face_dect.py”, line 49, in process_video
face_aligned = get_face(fa, frame) # 对齐每一帧中的人脸
File “D:\python_project\face-parsing\utils\face_dect.py”, line 24, in get_face
face_aligned = fa.align(image, gray, rect) # 对齐人脸
File “C:\Users\Fine\anaconda3\envs\torch2\lib\site-packages\imutils\face_utils\facealigner.py”, line 68, in align
M = cv2.getRotationMatrix2D(eyesCenter, float(angle), float(scale))
TypeError: Can’t parse ‘center’. Sequence item with index 0 has a wrong type

将人脸对齐脚本中的eyesCenter类型转换为float即可:

		# eyesCenter = ((leftEyeCenter[0] + rightEyeCenter[0]) // 2,# 	(leftEyeCenter[1] + rightEyeCenter[1]) // 2)eyesCenter = ((leftEyeCenter[0] + rightEyeCenter[0]) / 2.0,(leftEyeCenter[1] + rightEyeCenter[1]) / 2.0)# grab the rotation matrix for rotating and scaling the faceM = cv2.getRotationMatrix2D(eyesCenter, float(angle), float(scale))

在这里插入图片描述
参考:
LinlyZhai-对AVEC2014视频进行Dlib或MTCNN人脸裁剪

http://www.lryc.cn/news/575474.html

相关文章:

  • 【C#】 DevExpress.XtraEditors.SidePanel
  • OSEK/VDX OS ISO17356-3,【2】OS架构概述
  • 《大模型 Agent 应用实战指南》第4章:核心 Agent 设计与提示工程
  • 热点代码探测确定何时JIT
  • 【STM32】[特殊字符] WWDG(窗口看门狗)学习笔记
  • ESP32 VSCODE进入menuconfig时ESP-IDF idf.py menuconfig卡进度条,setuptools版本太高解决方法
  • 【Linux】软硬链接,动静态库
  • 第4篇:响应处理——返回数据给客户端(Gin文件下载,JSON,XML等返回)
  • [架构之美]Spring Boot 3.5.3新特性解析及JDK21集成
  • Pydantic 模型
  • python pandas数据清洗
  • 【攻防篇】解决:阿里云docker 容器中自动启动xmrig挖矿
  • 解锁阿里云Datatransport:数据迁移的终极利器
  • 前端项目3-01:登录页面
  • 日语学习-日语知识点小记-进阶-JLPT-真题训练-N2阶段(4):2022年12月2023年12月
  • WPF中Converter基础用法
  • OceanBase SQL 引擎高级技术学习笔记(通俗篇)
  • 智能制造——58页智慧工厂解决方案【附全文阅读】
  • python中学物理实验模拟:斜面受力分析
  • Elasticsearch 中的精确搜索与模糊搜索
  • electron 如何配置 打开控制台
  • Android 开发 获取Debug 跟 Release 包的SHA1值
  • DeepSeek16-open-webui Pipelines开发填坑
  • C语言再出发:2025年AI时代的关键语言
  • 华为云Flexus+DeepSeek征文|基于华为云一键部署 Dify-LLM 平台,结合 MCP 工具与 DeepSeek 模型打造智能学习助手
  • 【stm32】HAL库开发——Cube配置基本定时器
  • 猴子爬山(华为OD)
  • 什么是回归测试?什么时候需要做回归测试?
  • bug复盘:MCP SSE Client 生命周期问题之context.Background() 的使用
  • B站视频下载技术揭秘:从浏览器抓包到FFmpeg音视频合成