一、引言:

         从本文开始正式写代码,上文提到过,第一步我们得首先收集图像数据,我们通过python-opencv来获取视频流,并使用自带的人脸识别模型来检测人脸将人脸数据框选并保存下来。

        二、收集代码:

        废话不多说,我们先把整个代码整理给大家

import cv2
import os

def collect_faces():
    # 创建数据集目录
    os.makedirs("dataset", exist_ok=True)
    
    while True:
        # 输入姓名
        name = input("请输入你的名字(英文或拼音,输入exit退出): ").strip()
        
        # 退出条件
        if name.lower() == "exit":
            print("程序结束")
            break
        
        # 创建个人文件夹
        person_dir = f"dataset/{name}"
        os.makedirs(person_dir, exist_ok=True)
        
        # 加载人脸检测器
        face_detector = cv2.CascadeClassifier(
            cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
        )
        
        # 打开摄像头
        camera = cv2.VideoCapture(0)
        photo_count = 0
        
        print(f"\n开始采集 {name} 的人脸数据")
        print("按 C 键拍照,Q 键退出当前采集")
        print("注意:请先点击摄像头窗口再按按键")
        
        while photo_count < 20:
            # 读取摄像头画面
            ret, frame = camera.read()
            if not ret:
                print("无法获取视频帧")
                break
            
            # 检测人脸
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            faces = face_detector.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)
            
            # 显示画面
            cv2.imshow("Face Collection - Press C to Capture", frame)
            
            # 按键检测
            key = cv2.waitKey(1) & 0xFF
            
            if key == ord('c') or key == ord('C'):  # 拍照
                if len(faces) == 1:  # 确保只检测到一张脸
                    # 保存人脸区域
                    face_img = frame[y:y + h, x:x + w]
                    # 统一保存为jpg格式,编号补零
                    cv2.imwrite(f"{person_dir}/{photo_count:02d}.jpg", face_img)
                    print(f"已保存第 {photo_count + 1}/20 张照片")
                    photo_count += 1
                elif len(faces) > 1:
                    print("检测到多张脸!请确保画面中只有一个人")
                else:
                    print("未检测到人脸!请调整位置")
            
            elif key == ord('q') or key == ord('Q'):  # 退出当前采集
                print(f"提前结束 {name} 的数据采集")
                break
        
        # 关闭当前摄像头
        camera.release()
        cv2.destroyAllWindows()
        
        if photo_count >= 20:
            print(f"\n{name} 的20张照片已成功保存到 {person_dir} 文件夹")
        else:
            print(f"\n{name} 的照片采集未完成,已保存 {photo_count} 张照片")

if __name__ == "__main__":
    collect_faces()

        接下来我会介绍每一段代码的作用: 

import cv2
import os

        首先我们导入opencv的库和os库,前者是处理图像,后者用来操作文件,目的是为了将拍好的照片保存在相应的文件夹中。

1. 初始化设置部分

os.makedirs("dataset", exist_ok=True)

        功能:创建数据集根目录

        参数说明exist_ok=True:如果目录已存在不会报错

        设计考虑:确保程序首次运行时自动创建所需目录结构

2. 主循环控制结构

while True:
    name = input("请输入你的名字(英文或拼音,输入exit退出): ").strip()
    if name.lower() == "exit":
        print("程序结束")
        break

        交互设计

        使用input()获取用户输入,.strip()去除首尾空格,.lower()统一转为小写实现大小写不敏感匹配

        退出机制:检测"exit"输入作为程序终止条件

3. 个人数据存储设置

person_dir = f"dataset/{name}"
os.makedirs(person_dir, exist_ok=True)

        路径管理:

        使用f-string动态生成路径

        格式示例:dataset/John_Doe

        容错设计:同名目录已存在时不会报错

4. 人脸检测器初始化

face_detector = cv2.CascadeClassifier(
    cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
)

        模型选择:使用OpenCV预训练的Haar级联分类器

        路径解析:cv2.data.haarcascades指向OpenCV内置模型目录组合成完整模型路径

5. 视频采集初始化

camera = cv2.VideoCapture(0)
photo_count = 0

        设备控制:VideoCapture(0)打开默认摄像头

        参数0表示第一个视频捕获设备

        状态跟踪:photo_count记录已采集照片数量

6. 用户引导信息

print(f"\n开始采集 {name} 的人脸数据")
print("按 C 键拍照,Q 键退出当前采集")
print("注意:请先点击摄像头窗口再按按键")

        交互提示:

        ①明确当前采集对象

        ②说明控制按键功能

        ③强调操作注意事项(窗口焦点要求)

7. 实时采集循环

while photo_count < 20:
    ret, frame = camera.read()
    if not ret:
        print("无法获取视频帧")
        break

        帧捕获:

        camera.read()返回两个值:ret:读取是否成功的布尔值,frame:捕获的视频帧

        错误处理:视频流异常时退出当前采集

8. 人脸检测处理

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_detector.detectMultiScale(gray, 1.3, 5)

        图像预处理:转换为灰度图像(提高检测效率)

        检测参数:scaleFactor=1.3:图像缩放比例minNeighbors=5:检测稳定性参数

        输出结果:faces为检测到的人脸矩形坐标列表

9. 可视化反馈

for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.imshow("Face Collection - Press C to Capture", frame)

        标注绘制:蓝色矩形框标记检测到的人脸,线宽为2像素

        窗口显示:标题包含操作提示,实时更新视频帧

10. 按键处理逻辑

key = cv2.waitKey(1) & 0xFF
if key == ord('c') or key == ord('C'):
    if len(faces) == 1:
        face_img = frame[y:y + h, x:x + w]
        cv2.imwrite(f"{person_dir}/{photo_count:02d}.jpg", face_img)
        print(f"已保存第 {photo_count + 1}/20 张照片")
        photo_count += 1

        键检测:waitKey(1):1ms延迟,兼顾响应速度和CPU占用,& 0xFF:确保跨平台兼容性

        拍照条件:只允许检测到单一人脸时保存,保存人脸区域ROI(Region of Interest)

        文件命名::02d格式确保两位数编号(00-19),增量计数

11. 异常情况处理

elif len(faces) > 1:
    print("检测到多张脸!请确保画面中只有一个人")
else:
    print("未检测到人脸!请调整位置")

        质量管控:多人同时出现时拒绝采集,无人脸时给出调整提示

12. 退出处理

elif key == ord('q') or key == ord('Q'):
    print(f"提前结束 {name} 的数据采集")
    break

        退出机制:允许中途终止当前采集,保持程序继续运行

13. 资源清理

camera.release()
cv2.destroyAllWindows()

        资源释放:关闭摄像头设备,销毁所有OpenCV窗口

        设计原则:避免资源泄漏

14. 采集结果反馈

if photo_count >= 20:
    print(f"\n{name} 的20张照片已成功保存到 {person_dir} 文件夹")
else:
    print(f"\n{name} 的照片采集未完成,已保存 {photo_count} 张照片")

        用户反馈:区分完成和未完成状态,明确告知存储位置,显示实际采集数量

三、运行效果:

        运行改代码,输入ldh(刘德华),按下c后获取到了图片,在左下角可以看见实时获取的照片数量。

     拍摄完毕后输入exit退出程序

        我拍摄了三个人的照片,分别为ldh(刘德华)、lyf(刘亦菲)、st(沈腾),可以在dataset文件夹中查看我们获取的人脸照片:

四、结语:

        本文主要的功能为:能够通过摄像头自动拍摄并保存多个人的人脸照片。程序会为每个用户创建独立文件夹,通过简单的键盘操作(按C键拍照、Q键退出)即可完成20张人脸照片的采集,并实时显示检测框和操作提示。当检测到多人或无人脸时会给出相应提示,输入"exit"可退出整个程序,所有照片会自动分类保存到dataset目录下。

        目的是:构建人脸识别系统的训练数据集。

       最后,大家如果觉得对您有帮助的话麻烦点点赞,如果有错误或者纰漏希望您能在评论区指出,帮助大家能更好地理解和掌握相关知识!

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐