基于OpenCV实现IP摄像头移动人物人脸检测并单独保存人脸抓拍
解决方案:修改代码实现人脸区域保存+移动检测
针对你的需求,我们需要对代码做三处核心修改:修复缩进错误、添加移动检测逻辑、修改保存逻辑为单独人脸区域。以下是修改后的完整代码:
import numpy as np import cv2 import time # 加载人脸检测分类器 face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') def TakeSnapshotAndSave(): # 连接IP摄像头流 video = cv2.VideoCapture("rtsp://user:password@0.0.0.0:553/Streaming/Channels/401") # 初始化前一帧用于移动检测 prev_frame = None # 计数器,用于人脸图片命名 face_num = 0 # 移动检测阈值(可根据实际场景调整) motion_threshold = 5000 while True: ret, frame = video.read() if not ret: print("无法读取摄像头帧,退出") break # 调整帧大小 frame = cv2.resize(frame, (1500, 1000)) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (21, 21), 0) # 移动检测逻辑 motion_detected = False if prev_frame is not None: # 计算前后帧差异 frame_delta = cv2.absdiff(prev_frame, gray) thresh = cv2.threshold(frame_delta, 25, 255, cv2.THRESH_BINARY)[1] thresh = cv2.dilate(thresh, None, iterations=2) contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 判断是否有足够大的移动区域 for contour in contours: if cv2.contourArea(contour) > motion_threshold: motion_detected = True break # 更新前一帧 prev_frame = gray.copy() # 仅当检测到移动时,才进行人脸检测和保存 if motion_detected: faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: # 绘制人脸框(可选,用于预览) cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2) # 提取人脸区域 face_roi = frame[y:y + h, x:x + w] # 保存人脸图片 cv2.imwrite(f'face_{face_num}.jpg', face_roi) face_num += 1 # 添加短暂延迟,避免同一帧重复保存 time.sleep(0.1) # 显示预览画面 cv2.imshow("Lodhran Camera", frame) k = cv2.waitKey(1) if k == ord('q'): break video.release() cv2.destroyAllWindows() if __name__ == "__main__": TakeSnapshotAndSave()
关键修改说明:
- 修复缩进问题:将原代码中脱离函数的
while True循环放入TakeSnapshotAndSave函数内部,解决变量作用域错误 - 添加移动检测:使用帧差法对比前后帧灰度差异,通过轮廓面积判断是否有有效移动,避免无意义的持续抓拍
- 保存人脸区域:在人脸检测的循环内,提取
face_roi并单独保存,每检测到一张人脸生成一个独立文件 - 优化稳定性:添加帧读取失败判断,避免程序崩溃;添加短暂延迟防止同一帧内重复保存相同人脸
内容的提问来源于stack exchange,提问作者Muhammad Noman
相关产品推荐
相关产品推荐

