《Python 人脸识别入门实践:从人脸检测到人脸比对完整实现》

Python 人脸识别入门实践:从人脸检测到人脸比对完整实现


一、什么是人脸识别?

人脸识别,简单来说,就是让计算机判断一张图片或视频中的人脸是谁。

它通常包括两个层面的任务:

text 复制代码
人脸检测:判断图像中有没有人脸,并找出人脸位置
人脸识别:判断检测到的人脸属于谁

例如,在一张图片中,程序可以完成以下工作:

text 复制代码
输入图片
↓
检测图片中的人脸位置
↓
提取人脸特征
↓
和已知人脸进行比对
↓
输出识别结果

所以,人脸识别并不是简单地"看见脸",而是要进一步判断"这张脸是谁"。


二、人脸检测和人脸识别的区别

很多小白刚开始学习时,会把"人脸检测"和"人脸识别"混在一起。

其实它们不是一回事。

对比项 人脸检测 人脸识别
目标 找出图像中的人脸位置 判断人脸属于谁
输出结果 人脸框坐标 人名或身份
难度 相对较低 相对较高
示例 图片中有几张脸 这张脸是不是张三

举个例子:

text 复制代码
人脸检测:这张图片里有一张人脸,位置在左上角。
人脸识别:这张人脸是张三。

完整的人脸识别系统通常要先做人脸检测,再做人脸识别。


三、人脸识别的基本流程

一个基础的人脸识别系统一般包括以下步骤:

text 复制代码
准备已知人脸图片
↓
提取已知人脸特征
↓
读取待识别图片
↓
检测待识别图片中的人脸
↓
提取待识别人脸特征
↓
计算两张人脸特征的相似度
↓
输出识别结果

可以理解为:

text 复制代码
先把"标准答案"存起来
再拿新图片和标准答案进行比较
最后判断是不是同一个人

四、环境准备

本文使用 Python 实现基础人脸识别功能,需要安装以下库:

bash 复制代码
pip install opencv-python
pip install face_recognition

如果安装 face_recognition 时遇到问题,通常是因为它依赖 dlib,部分电脑需要先安装 CMake:

bash 复制代码
pip install cmake
pip install dlib
pip install face_recognition

如果是在 Windows 环境中,安装 dlib 可能会比较麻烦,可以优先使用 Anaconda 或者搜索对应 Python 版本的 whl 文件安装。


五、使用 OpenCV 实现人脸检测

首先,我们用 OpenCV 完成最基础的人脸检测。

1. 准备图片

假设项目目录中有一张图片:

text 复制代码
test.jpg

2. 编写人脸检测代码

python 复制代码
import cv2

# 读取图片
image = cv2.imread("test.jpg")

if image is None:
    print("图片读取失败,请检查图片路径")
    exit()

# 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 加载 OpenCV 自带的人脸检测模型
face_cascade = cv2.CascadeClassifier(
    cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
)

# 检测人脸
faces = face_cascade.detectMultiScale(
    gray,
    scaleFactor=1.1,
    minNeighbors=5,
    minSize=(30, 30)
)

# 绘制人脸框
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 输出检测到的人脸数量
print("检测到的人脸数量:", len(faces))

# 显示结果
cv2.imshow("Face Detection", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行后,程序会在图片中的人脸区域画出绿色矩形框。


六、OpenCV 人脸检测代码解析

1. 读取图片

python 复制代码
image = cv2.imread("test.jpg")

用于读取本地图片。

2. 转换灰度图

python 复制代码
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

很多传统图像检测算法会先把彩色图片转换为灰度图,这样可以减少计算量。

3. 加载人脸检测器

python 复制代码
face_cascade = cv2.CascadeClassifier(
    cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
)

这里使用的是 OpenCV 自带的 Haar 人脸检测模型,适合小白入门。

4. 检测人脸

python 复制代码
faces = face_cascade.detectMultiScale(gray)

检测结果中包含每张人脸的位置。

每个人脸框包括:

text 复制代码
x, y, w, h

含义分别是:

参数 含义
x 人脸框左上角 x 坐标
y 人脸框左上角 y 坐标
w 人脸框宽度
h 人脸框高度

七、使用摄像头进行实时人脸检测

除了检测图片,也可以调用摄像头进行实时检测。

python 复制代码
import cv2

# 打开摄像头
cap = cv2.VideoCapture(0)

# 加载人脸检测模型
face_cascade = cv2.CascadeClassifier(
    cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
)

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

    if not ret:
        print("摄像头读取失败")
        break

    # 转换为灰度图
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 检测人脸
    faces = face_cascade.detectMultiScale(
        gray,
        scaleFactor=1.1,
        minNeighbors=5,
        minSize=(30, 30)
    )

    # 绘制人脸框
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

    # 显示画面
    cv2.imshow("Real-time Face Detection", frame)

    # 按 q 退出
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

# 释放资源
cap.release()
cv2.destroyAllWindows()

其中:

python 复制代码
cv2.VideoCapture(0)

表示调用电脑默认摄像头。

如果有多个摄像头,可以尝试:

python 复制代码
cv2.VideoCapture(1)
cv2.VideoCapture(2)

八、使用 face_recognition 实现人脸识别

OpenCV 上面的代码主要完成的是"人脸检测",也就是找到人脸在哪里。

如果想判断"这个人是谁",可以使用 face_recognition 库。

假设我们有两张图片:

text 复制代码
known.jpg      # 已知人物照片
unknown.jpg    # 待识别人物照片

代码如下:

python 复制代码
import face_recognition

# 加载已知人脸图片
known_image = face_recognition.load_image_file("known.jpg")

# 加载待识别人脸图片
unknown_image = face_recognition.load_image_file("unknown.jpg")

# 提取已知人脸特征
known_encodings = face_recognition.face_encodings(known_image)

# 提取待识别人脸特征
unknown_encodings = face_recognition.face_encodings(unknown_image)

# 判断是否检测到人脸
if len(known_encodings) == 0:
    print("已知图片中没有检测到人脸")
    exit()

if len(unknown_encodings) == 0:
    print("待识别图片中没有检测到人脸")
    exit()

# 获取第一张人脸的特征
known_encoding = known_encodings[0]
unknown_encoding = unknown_encodings[0]

# 人脸比对
results = face_recognition.compare_faces(
    [known_encoding],
    unknown_encoding,
    tolerance=0.6
)

# 输出结果
if results[0]:
    print("识别结果:是同一个人")
else:
    print("识别结果:不是同一个人")

九、人脸识别代码解析

1. 加载图片

python 复制代码
known_image = face_recognition.load_image_file("known.jpg")
unknown_image = face_recognition.load_image_file("unknown.jpg")

分别加载已知图片和待识别图片。

2. 提取人脸特征

python 复制代码
known_encodings = face_recognition.face_encodings(known_image)
unknown_encodings = face_recognition.face_encodings(unknown_image)

face_encodings 会把人脸转换成一组特征向量。

可以简单理解为:

text 复制代码
把一张人脸转换成一串数字

后续程序就是通过比较这串数字来判断两张脸是否相似。

3. 人脸比对

python 复制代码
results = face_recognition.compare_faces(
    [known_encoding],
    unknown_encoding,
    tolerance=0.6
)

tolerance 表示容忍度。

一般来说:

tolerance 说明
0.4 更严格,误识别更少,但可能漏识别
0.6 默认值,比较常用
0.8 更宽松,容易识别成功,但误识别风险更高

小白入门阶段可以先使用:

python 复制代码
tolerance=0.6

十、识别多个人脸

如果一张图片中有多个人脸,可以循环处理。

python 复制代码
import face_recognition

# 加载已知人脸
known_image = face_recognition.load_image_file("known.jpg")
known_encodings = face_recognition.face_encodings(known_image)

if len(known_encodings) == 0:
    print("已知图片中没有检测到人脸")
    exit()

known_encoding = known_encodings[0]

# 加载待识别图片
unknown_image = face_recognition.load_image_file("unknown.jpg")

# 获取待识别图片中所有人脸位置
face_locations = face_recognition.face_locations(unknown_image)

# 获取所有人脸特征
face_encodings = face_recognition.face_encodings(unknown_image, face_locations)

print("检测到人脸数量:", len(face_encodings))

for index, face_encoding in enumerate(face_encodings):
    result = face_recognition.compare_faces(
        [known_encoding],
        face_encoding,
        tolerance=0.6
    )

    if result[0]:
        print(f"第 {index + 1} 张人脸:匹配成功")
    else:
        print(f"第 {index + 1} 张人脸:不是目标人物")

十一、给识别结果画框并显示姓名

下面这个例子会在图片中画出人脸框,并标注识别结果。

python 复制代码
import cv2
import face_recognition

# 加载已知人脸
known_image = face_recognition.load_image_file("known.jpg")
known_encodings = face_recognition.face_encodings(known_image)

if len(known_encodings) == 0:
    print("已知图片中没有检测到人脸")
    exit()

known_encoding = known_encodings[0]
known_name = "Zhang San"

# 加载待识别图片
image = face_recognition.load_image_file("unknown.jpg")

# 检测人脸位置和特征
face_locations = face_recognition.face_locations(image)
face_encodings = face_recognition.face_encodings(image, face_locations)

# 转换颜色格式,便于 OpenCV 显示
image_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

for face_location, face_encoding in zip(face_locations, face_encodings):
    top, right, bottom, left = face_location

    matches = face_recognition.compare_faces(
        [known_encoding],
        face_encoding,
        tolerance=0.6
    )

    if matches[0]:
        name = known_name
    else:
        name = "Unknown"

    # 绘制人脸框
    cv2.rectangle(image_bgr, (left, top), (right, bottom), (0, 255, 0), 2)

    # 绘制姓名背景
    cv2.rectangle(image_bgr, (left, bottom - 30), (right, bottom), (0, 255, 0), -1)

    # 写入姓名
    cv2.putText(
        image_bgr,
        name,
        (left + 6, bottom - 8),
        cv2.FONT_HERSHEY_SIMPLEX,
        0.8,
        (255, 255, 255),
        2
    )

# 显示结果
cv2.imshow("Face Recognition", image_bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

十二、识别多个人物

如果要识别多个人物,可以准备多张已知人脸图片。

假设有:

text 复制代码
known_faces/
├── zhangsan.jpg
├── lisi.jpg
└── wangwu.jpg

可以这样写:

python 复制代码
import face_recognition
import os

known_face_encodings = []
known_face_names = []

known_faces_dir = "known_faces"

for filename in os.listdir(known_faces_dir):
    if filename.endswith(".jpg") or filename.endswith(".png"):
        image_path = os.path.join(known_faces_dir, filename)

        image = face_recognition.load_image_file(image_path)
        encodings = face_recognition.face_encodings(image)

        if len(encodings) > 0:
            known_face_encodings.append(encodings[0])

            # 使用文件名作为姓名
            name = os.path.splitext(filename)[0]
            known_face_names.append(name)

print("已加载人脸数量:", len(known_face_encodings))
print("已加载人物姓名:", known_face_names)

这样就可以把文件夹中的人脸批量加载进来。


十三、完整人脸识别项目代码

下面是一份相对完整的人脸识别代码,可以识别多个人物,并在图片上标注姓名。

项目目录结构:

text 复制代码
face_project/
├── known_faces/
│   ├── zhangsan.jpg
│   ├── lisi.jpg
│   └── wangwu.jpg
├── test.jpg
└── main.py

完整代码如下:

python 复制代码
import cv2
import face_recognition
import os

# 存储已知人脸特征和姓名
known_face_encodings = []
known_face_names = []

# 已知人脸文件夹
known_faces_dir = "known_faces"

# 加载已知人脸
for filename in os.listdir(known_faces_dir):
    if filename.lower().endswith((".jpg", ".jpeg", ".png")):
        image_path = os.path.join(known_faces_dir, filename)

        image = face_recognition.load_image_file(image_path)
        encodings = face_recognition.face_encodings(image)

        if len(encodings) > 0:
            known_face_encodings.append(encodings[0])
            name = os.path.splitext(filename)[0]
            known_face_names.append(name)
        else:
            print(f"警告:{filename} 中没有检测到人脸")

print("已加载人脸数量:", len(known_face_encodings))

# 读取待识别图片
image = face_recognition.load_image_file("test.jpg")

# 检测人脸位置
face_locations = face_recognition.face_locations(image)

# 提取人脸特征
face_encodings = face_recognition.face_encodings(image, face_locations)

# 转换为 OpenCV 可显示的 BGR 格式
image_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

# 遍历检测到的人脸
for face_location, face_encoding in zip(face_locations, face_encodings):
    top, right, bottom, left = face_location

    # 默认未知
    name = "Unknown"

    # 与已知人脸进行比对
    matches = face_recognition.compare_faces(
        known_face_encodings,
        face_encoding,
        tolerance=0.6
    )

    # 如果有匹配结果
    if True in matches:
        first_match_index = matches.index(True)
        name = known_face_names[first_match_index]

    # 绘制人脸框
    cv2.rectangle(image_bgr, (left, top), (right, bottom), (0, 255, 0), 2)

    # 绘制姓名背景
    cv2.rectangle(image_bgr, (left, bottom - 30), (right, bottom), (0, 255, 0), -1)

    # 显示姓名
    cv2.putText(
        image_bgr,
        name,
        (left + 6, bottom - 8),
        cv2.FONT_HERSHEY_SIMPLEX,
        0.8,
        (255, 255, 255),
        2
    )

# 保存结果
cv2.imwrite("result.jpg", image_bgr)

# 显示结果
cv2.imshow("Face Recognition Result", image_bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

十四、摄像头实时人脸识别

如果要使用摄像头进行实时人脸识别,可以参考下面代码。

python 复制代码
import cv2
import face_recognition
import os

known_face_encodings = []
known_face_names = []

known_faces_dir = "known_faces"

# 加载已知人脸
for filename in os.listdir(known_faces_dir):
    if filename.lower().endswith((".jpg", ".jpeg", ".png")):
        image_path = os.path.join(known_faces_dir, filename)
        image = face_recognition.load_image_file(image_path)
        encodings = face_recognition.face_encodings(image)

        if len(encodings) > 0:
            known_face_encodings.append(encodings[0])
            known_face_names.append(os.path.splitext(filename)[0])

# 打开摄像头
cap = cv2.VideoCapture(0)

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

    if not ret:
        print("摄像头读取失败")
        break

    # OpenCV 读取的是 BGR,face_recognition 使用 RGB
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # 检测人脸位置
    face_locations = face_recognition.face_locations(rgb_frame)

    # 提取人脸特征
    face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)

    for face_location, face_encoding in zip(face_locations, face_encodings):
        top, right, bottom, left = face_location

        name = "Unknown"

        matches = face_recognition.compare_faces(
            known_face_encodings,
            face_encoding,
            tolerance=0.6
        )

        if True in matches:
            first_match_index = matches.index(True)
            name = known_face_names[first_match_index]

        # 绘制人脸框
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)

        # 绘制姓名背景
        cv2.rectangle(frame, (left, bottom - 30), (right, bottom), (0, 255, 0), -1)

        # 显示姓名
        cv2.putText(
            frame,
            name,
            (left + 6, bottom - 8),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.8,
            (255, 255, 255),
            2
        )

    cv2.imshow("Real-time Face Recognition", frame)

    # 按 q 退出
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

十五、人脸识别常见问题

1. 为什么识别不到人脸?

可能原因有:

  • 图片太模糊;
  • 人脸太小;
  • 光线太暗;
  • 人脸角度太偏;
  • 人脸被遮挡;
  • 图片路径错误;
  • 图片中没有正面人脸。

2. 为什么识别结果不准确?

可能原因有:

  • 已知人脸图片太少;
  • 已知图片和待识别图片差异太大;
  • 人脸表情变化明显;
  • 光照变化太大;
  • 人脸被帽子、口罩、眼镜遮挡;
  • tolerance 参数设置不合理。

3. 如何提高识别准确率?

可以从以下几个方面优化:

text 复制代码
使用更清晰的已知人脸图片
每个人准备多张不同角度的人脸图片
保证光线充足
尽量使用正脸图片
适当调整 tolerance 参数
避免使用严重遮挡的人脸图片

4. 为什么摄像头运行很卡?

可能原因有:

  • 电脑性能不足;
  • 摄像头分辨率太高;
  • 每一帧都做人脸识别计算量较大;
  • 同时识别的人脸数量太多。

可以尝试降低分辨率:

python 复制代码
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

十六、人脸识别的应用场景

人脸识别可以应用在很多实际项目中。

1. 门禁系统

通过摄像头识别人脸,实现刷脸开门。

2. 考勤系统

通过人脸识别判断员工或学生是否到场。

3. 相册分类

根据人脸自动对照片进行分类。

4. 智慧安防

用于人员识别、陌生人检测、重点区域监控等场景。

5. 登录验证

在部分系统中,可以使用人脸作为身份验证方式。


十七、人脸识别项目开发注意事项

人脸识别属于生物特征识别技术,在实际项目中需要特别注意隐私和数据安全。

开发时建议注意以下几点:

  1. 采集人脸数据前应取得用户授权;
  2. 不要随意上传他人人脸照片;
  3. 不要把人脸数据公开到网络;
  4. 人脸数据应加密存储;
  5. 项目中应明确告知用户数据用途;
  6. 不要将人脸识别用于违法、侵犯隐私或未经授权的场景。

技术可以提高效率,但必须在合法、合规、尊重隐私的前提下使用。


十八、本文总结

本文介绍了 Python 人脸识别的基础知识和实现方法,主要包括:

text 复制代码
人脸检测与人脸识别的区别
OpenCV 实现人脸检测
face_recognition 实现人脸比对
多人物人脸识别
摄像头实时人脸识别
常见问题和优化方法

对于初学者来说,建议按照下面的顺序学习:

text 复制代码
先理解人脸检测
再学习人脸特征提取
然后实现两张图片比对
最后实现多人脸识别和摄像头实时识别

人脸识别是计算机视觉中的经典应用,也是很多课程设计、毕业设计和项目实战中常见的方向。掌握本文中的基础代码后,可以进一步扩展为刷脸考勤系统、门禁系统、人脸登录系统以及 Web 可视化识别平台。


相关推荐
ceclar1231 小时前
C# 的任务并行库(TPL)
开发语言·c#·.net
宸丶一1 小时前
Day 10:LangGraph - Agent 的图执行引擎
java·windows·python
快乐的哈士奇2 小时前
【Next.js实战①】Gmail API 按柜号检索邮件:OAuth 双 Cookie 与搜索 Fallback
开发语言·javascript·ecmascript
weixin_307779132 小时前
Python写入Shell文件使用Linux系统的换行符
linux·开发语言·python·自动化
zmzb01032 小时前
Python课后习题训练记录Day130
开发语言·python
阿里嘎多学长2 小时前
2026-06-13 GitHub 热点项目精选
开发语言·程序员·github·代码托管
xiaoshuaishuai82 小时前
C# 委托与事件
开发语言·c#
kmblack12 小时前
javascript计算年龄
开发语言·javascript·ecmascript
高洁013 小时前
医疗行业的数字孪生革命
python·机器学习·数据挖掘·transformer·知识图谱