首尾帧人脸差异检测
代码概述
本脚本实现了一个简单的视频筛查系统,主要功能是通过比较视频首帧和尾帧中的人脸差异来判断视频是否合格。如果视频中没有人脸或存在其他异常情况,视频将被移动到错误目录中。具体来说,系统包含以下几个主要步骤:
- 加载视频文件:尝试打开视频文件,并读取首帧和尾帧。
- 人脸检测:使用OpenCV的Haar级联分类器检测视频首帧和尾帧中的人脸。
- 人脸提取与标准化:从检测到的人脸区域中提取并标准化脸部图像。
- 差异计算:计算首帧和尾帧中脸部区域的差异,并与预设的阈值进行比较。
- 视频处理:根据差异判断视频是否合格,并将视频移动到相应的目录。
代码步骤详解
-
导入必要的库
import cv2 import numpy as np import os import shutil
-
加载预训练的人脸检测模型
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
-
定义人脸检测函数
def detect_face(image):gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)return faces
此函数将输入图像转换为灰度图,并使用预训练的Haar级联分类器检测人脸。
-
定义人脸提取与标准化函数
def extract_face(image, face, face_size=(100, 100)):x, y, w, h = faceface_region = image[y:y+h, x:x+w]face_region = cv2.resize(face_region, face_size)return face_region
此函数从检测到的人脸区域中提取脸部图像,并将其标准化为固定尺寸。
-
定义视频分析函数
def analyze_video(video_path, threshold=1000000):cap = cv2.VideoCapture(video_path)if not cap.isOpened():print("Error opening video file:", video_path)return Noneframe_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))ret, first_frame = cap.read()if not ret:print("Failed to grab first frame:", video_path)return Nonecap.set(cv2.CAP_PROP_POS_FRAMES, frame_count - 1)ret, last_frame = cap.read()if not ret:print("Failed to grab last frame:", video_path)return Nonecap.release()first_faces = detect_face(first_frame)last_faces = detect_face(last_frame)if len(first_faces) == 0 or len(last_faces) == 0:print("No face detected in video:", video_path)return Nonefirst_face = extract_face(first_frame, first_faces[0])last_face = extract_face(last_frame, last_faces[0])diff = cv2.absdiff(first_face, last_face)gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)_, thresh = cv2.threshold(gray, 30, 255, cv2.THRESH_BINARY)non_zero_count = cv2.countNonZero(thresh)return non_zero_count >= threshold
此函数执行以下操作:
- 打开视频文件并读取首帧和尾帧;
- 检测首帧和尾帧中的人脸;
- 提取并标准化脸部图像;
- 计算脸部区域的差异,并与阈值进行比较;
- 返回布尔值表示视频是否合格。
-
定义视频处理函数
def process_videos(input_dir, output_dir, error_dir, threshold=1000000):if not os.path.exists(output_dir):os.makedirs(output_dir)if not os.path.exists(error_dir):os.makedirs(error_dir)for root, dirs, files in os.walk(input_dir):for file in files:if file.endswith(('.mp4', '.avi', '.mkv', '.mov', '.wmv')):video_path = os.path.join(root, file)result = analyze_video(video_path, threshold)if result is None:print(f"Moving video {video_path} due to errors.")shutil.move(video_path, os.path.join(error_dir, file))elif result:print(f"Video {video_path} is not up to standard.")shutil.move(video_path, os.path.join(output_dir, file))
此函数遍历输入目录中的所有视频文件,并逐一进行分析:
- 创建输出目录和错误目录;
- 对每个视频文件执行分析;
- 根据分析结果将视频移动到相应目录。
-
主程序入口
if __name__ == '__main__':input_dir = '.' # 输入视频所在的文件夹output_dir = 'not_up_to_standard' # 不达标视频输出的文件夹error_dir = 'errors' # 存放检测错误的视频threshold = 1000000 # 需要根据实际情况调整这个阈值process_videos(input_dir, output_dir, error_dir, threshold)
主程序入口定义了输入目录、输出目录和错误目录,并调用
process_videos
函数处理视频文件。
总结
本脚本提供了一个简单但实用的工具,用于自动筛查视频文件,特别适用于需要检测视频首尾帧中人脸差异的应用场景。通过调整阈值和优化人脸检测参数,可以进一步提高系统的准确性和鲁棒性。