本文介绍了一个完整的人脸识别系统实现,包含采集、训练、验证和识别四个模块。系统使用OpenCV进行图像处理,face_recognition库提取人脸特征,SVM分类器进行训练和预测。采集模块通过摄像头获取人脸图像并保存;训练模块对采集的图像提取特征并训练分类模型;验证模块测试单张图片的识别效果;识别模块实时检测视频流中的人脸并进行身份识别。系统支持多人脸检测,并显示识别置信度,具有较高的实用性和准确性。

采集

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# @File     : 采集
# @Time     : 2025/10/22 10:03
# @Author   : CWB
# @Desc     : 
# ----------------------------------------------------------------------------
"""
这里写文件描述...
"""
import cv2, os, pathlib, time

name = input('输入你的名字: ').strip()
save_dir = pathlib.Path('dataset') / name
save_dir.mkdir(parents=True, exist_ok=True)

cap = cv2.VideoCapture(0)
idx = 0
while True:
    ret, frame = cap.read()
    cv2.imshow('collect', frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord('s'):
        # 1. 先生成完整路径(含中文)
        file_path = save_dir / f'{idx}.jpg'
        # 2. 用 cv2.imencode 把帧编码成 jpg 内存流
        ok, buf = cv2.imencode('.jpg', frame)
        if ok:
            # 3. Python 自己写盘,路径再长再中文都没事
            with open(file_path, 'wb') as f:
                f.write(buf)
            print('saved', file_path)
            idx += 1
    if key == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

训练

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# @File     : 训练
# @Time     : 2025/10/22 10:12
# @Author   : CWB
# @Desc     : 
# ----------------------------------------------------------------------------
"""
这里写文件描述...
"""
from pathlib import Path
import face_recognition, pickle, cv2
from sklearn.svm import SVC
import numpy as np

dataset = Path('dataset')
encodings, labels = [], []

for person_dir in dataset.iterdir():
    if not person_dir.is_dir():
        continue
    name = person_dir.name
    print(f"\n📁 处理身份:{name}")
    for img_path in person_dir.glob('*'):
        bgr = cv2.imread(str(img_path))
        if bgr is None:
            print(f" ❌ 读取失败,跳过:{img_path}")
            continue
        rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
        boxes = face_recognition.face_locations(rgb, model='hog')
        if not boxes:
            print(f" ⚠️ 未检测到人脸,跳过:{img_path.name}")
            continue
        if len(boxes) > 1:
            print(f" ⚠️ 检测到多张脸,跳过:{img_path.name}")
            continue
        enc = face_recognition.face_encodings(rgb, boxes)[0]
        encodings.append(enc)
        labels.append(name)
        print(f" ✅ 已编码:{img_path.name}")

print(f"\n共收集 {len(encodings)} 张有效人脸,{len(set(labels))} 个身份")
print("身份列表:", sorted(set(labels)))

clf = SVC(kernel='linear', probability=True)
clf.fit(encodings, labels)

with open('face_model.pkl', 'wb') as f:
    pickle.dump(clf, f)

验证

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# @File     : 验证
# @Time     : 2025/10/23 13:14
# @Author   : CWB
# @Desc     : 
# ----------------------------------------------------------------------------
"""
这里写文件描述...
"""
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cv2, face_recognition, pickle, numpy as np, pathlib

# 加载训练好的模型
clf = pickle.load(open('face_model.pkl', 'rb'))

# 改成你要测试的图片路径
img_path = pathlib.Path('dataset/cwb/0.jpg')  # ← 改成你想测试的图片

# 读取并预处理
bgr = cv2.imread(str(img_path))
rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)

# 检测人脸并编码
boxes = face_recognition.face_locations(rgb, model='hog')
encodings = face_recognition.face_encodings(rgb, boxes)

for enc in encodings:
    name = clf.predict([enc])[0]
    proba = np.max(clf.predict_proba([enc]))
    print(f"识别结果:{name}(置信度:{proba:.2f})")

识别

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# @File     : 识别
# @Time     : 2025/10/22 10:16
# @Author   : CWB
# @Desc     : 
# ----------------------------------------------------------------------------
"""
这里写文件描述...
"""
import cv2, face_recognition, pickle, numpy as np

clf = pickle.load(open('face_model.pkl', 'rb'))
cap = cv2.VideoCapture(0)
process = True  # 隔帧采样提速

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 1. 缩小图提速,但每帧都检测
    small = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5)
    rgb = cv2.cvtColor(small, cv2.COLOR_BGR2RGB)

    boxes = face_recognition.face_locations(rgb, model='hog')
    encs = face_recognition.face_encodings(rgb, boxes)

    colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255)]
    for i, (box, enc) in enumerate(zip(boxes, encs)):
        name = clf.predict([enc])[0]
        proba = np.max(clf.predict_proba([enc]))
        top, right, bottom, left = [x * 2 for x in box]
        color = colors[i % len(colors)]
        cv2.rectangle(frame, (left, top), (right, bottom), color, 2)
        cv2.putText(frame, f'{name} {proba:.2f}', (left, top - 10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
    cv2.imshow('face recognition', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release(); cv2.destroyAllWindows()

因部分库比较特殊,所有代码在python3.11下运行,依赖库请移步下载

更多推荐