减少不必要的临时文件操作:避免频繁地读写临时文件。
减少重复操作:尽量减少重复读取和处理相同的帧。
简化面部检测过程:直接在内存中处理帧,而不是写入磁盘再读取。
import cv2
import dlib
import numpy as np
import os
from pathlib import Path
# 加载预训练模型
face_recognition_model = "dlib_face_recognition_resnet_model_v1.dat"
face_recognition_net = dlib.face_recognition_model_v1(face_recognition_model)
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
def load_image(file_path):
"""加载图像"""
image = cv2.imread(file_path)
return image
def get_face_encoding(image):
"""获取图像中第一个脸部的编码"""
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
face_rects = detector(gray_image)
if len(face_rects) > 0:
shape = predictor(gray_image, face_rects[0])
return np.array(face_recognition_net.compute_face_descriptor(image, shape, 100))
return None
def compare_faces(known_face_encoding, unknown_image):
"""比较两张图像是否属于同一人"""
unknown_face_encoding = get_face_encoding(unknown_image)
if known_face_encoding is not None and unknown_face_encoding is not None:
distance = np.linalg.norm(known_face_encoding - unknown_face_encoding)
threshold = 0.3 # 根据实际情况调整阈值
return distance <= threshold
return False
def extract_first_frame(video_path):
"""从视频中提取第一帧"""
cap = cv2.VideoCapture(str(video_path))
ret, frame = cap.read()
if not ret:
raise ValueError(f"Failed to read the video {video_path}")
return frame
def main():
# 定义目标目录
TARGET_DIR = "special"
os.makedirs(TARGET_DIR, exist_ok=True)
# 加载参考图像
known_image_path = "fjy.png" # 请替换为你的样例图片路径
known_image = load_image(known_image_path)
known_face_encoding = get_face_encoding(known_image)
# 遍历当前目录下的所有直接子文件中的 MP4 文件
for mp4_file in Path('.').iterdir():
if mp4_file.is_file() and mp4_file.suffix.lower() == '.mp4':
try:
# 从视频中提取第一帧
frame = extract_first_frame(mp4_file)
# 直接比较第一帧中的人脸是否与参考图像中的人脸匹配
if compare_faces(known_face_encoding, frame):
print(f"Face in {mp4_file.name} matches the reference image.")
# 移动匹配的视频到 special 文件夹
mp4_file.rename(Path(TARGET_DIR) / mp4_file.name)
except Exception as e:
print(f"Error processing {mp4_file.name}: {str(e)}")
if __name__ == "__main__":
main()