从YouTube视频提取唯一人脸时遇moov atom not found错误求助
问题根源与修复方案
1. 核心错误:无效的视频下载
你直接用urllib.request.urlretrieve下载YouTube网页链接,得到的不是视频文件,而是网页HTML代码。OpenCV读取这种假MP4文件时,会触发moov atom not found错误(MP4文件的关键索引头不存在),后续帧提取、人脸检测自然全失效,最终输出空文件夹和Saved 0 unique faces。
YouTube不会直接暴露视频源链接,必须用专门工具获取真实视频流,推荐用pytube库处理。
2. 次要问题:人脸未实现去重
原代码的known_faces仅存储所有检测到的人脸编码,未做相似度比对去重,即使能检测到人脸,也会重复保存同一人脸,打印的数量并非真实唯一人脸数。
完整修复代码
import os import cv2 import face_recognition import numpy as np from pytube import YouTube # Step 1: 用pytube下载合法YouTube视频 video_url = "https://www.youtube.com/watch?v=JriaiYZZhbY&t=4s" yt = YouTube(video_url) # 选择带音频的最高分辨率MP4流 stream = yt.streams.filter(file_extension='mp4', progressive=True).get_highest_resolution() stream.download(filename="video.mp4") # Step 2: 优化提取视频帧(隔帧提取减少计算量) cap = cv2.VideoCapture("video.mp4") frames = [] frame_interval = 5 # 每5帧提取一次,可按需调整 count = 0 while cap.isOpened(): ret, frame = cap.read() if not ret: break if count % frame_interval == 0: # 转换为RGB格式(face_recognition要求输入RGB,OpenCV默认BGR) rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frames.append(rgb_frame) count += 1 cap.release() # Step 3: 检测人脸并实现真正去重 if not os.path.exists("faces"): os.makedirs("faces") known_encodings = [] unique_face_count = 0 for i, frame in enumerate(frames): face_locations = face_recognition.face_locations(frame) face_encodings = face_recognition.face_encodings(frame, face_locations) for idx, face_encoding in enumerate(face_encodings): # 比对当前人脸是否已存在于已知编码库 matches = face_recognition.compare_faces(known_encodings, face_encoding, tolerance=0.6) if not any(matches): known_encodings.append(face_encoding) # 提取人脸区域并转换回BGR格式保存 top, right, bottom, left = face_locations[idx] face_image = cv2.cvtColor(frame[top:bottom, left:right], cv2.COLOR_RGB2BGR) cv2.imwrite(f"faces/unique_face_{unique_face_count}.jpg", face_image) unique_face_count += 1 print(f"Saved {unique_face_count} unique faces")
修复要点说明
- 视频下载修复:替换
urllib为pytube,确保获取真实MP4文件,安装命令:pip install pytube - 帧处理优化:添加帧间隔减少计算量,同时完成BGR→RGB格式转换(适配
face_recognition库要求) - 人脸去重逻辑:用
face_recognition.compare_faces比对人脸编码,仅保存未出现过的人脸,确保计数为真实唯一人脸数 - 鲁棒性提升:用循环读取视频替代原代码的帧计数方式,避免因视频文件损坏导致的帧读取失败
内容的提问来源于stack exchange,提问作者Tochukwu
相关产品推荐
相关产品推荐

