【树莓派 5 】人脸识别
本文介绍了树莓派 5 单板计算机结合 OpenCV 内置 YuNet 算法和 SFace 模型实现人脸识别的项目设计,包括环境部署、预训练模型获取、关键代码、板端推理、效果演示等流程。
项目介绍
准备工作:硬件连接、OpenCV 安装、所需软件包和库安装等;
人脸识别:模型获取、训练图片、流程图、代码、人脸识别的板端推理等;
准备工作
包括硬件连接、虚拟环境创建、OpenCV 安装、软件包和库安装等。
硬件连接
将装有 Raspberry Pi OS 系统的 Micro-SD 卡置入目标插槽;
使用 Mini-HDMI 数据线连接显示屏(也可使用 VNC 或 SSH 远程登录);
使用 USB 接口连接鼠标键盘;
使用 LAN 接口连接互联网(或使用 WiFi 连接无线网络);


OpenCV 安装
OpenCV 是一个开源的计算机视觉库,广泛应用于图像处理、视频分析和机器学习等领域。


为了避免影响系统 Python,采用虚拟环境的方案。
创建并激活虚拟环境;
mkdir ~/cv && cd ~/cv # 创建 cv 文件夹,便于管理 python3 -m venv venv # 创建虚拟环境 venv source venv/bin/activate # 激活虚拟环境 venv
安装 numpy 和 opencv ;
pip install -U pip numpy # 安装 numpy pip install opencv-python opencv-contrib-python # opencv 主模块及 contrib
验证安装;
python3 -c "import cv2,sys,numpy;print('OpenCV:',cv2.__version__,'NumPy:',numpy.__version__)"输出版本号;

详见:OpenCV .
人脸识别
OpenCV 作为计算机视觉领域的核心库,其 Python 接口提供了高效的人脸检测与识别能力。


OpenCV 注册并训练目标人脸,使用 YuNet 模型检测人脸,之后结合 sface 模型识别人脸。
详见:opencv_zoo/models/face_recognition_sface · GitHub .
模型
下载所需模型文件;
wget https://github.com/opencv/face_detection_yunet.onnx wget https://github.com/opencv/face_recognition_sface.onnx
将文件存放在 ./model 路径
训练图片
将目标人脸图片裁剪至合适大小;
文件名为对应的姓名;
置于 ./face 文件夹。


文件目录
~/AI_Vision/faceRecognition $ tree . ├── face │ ├── Arnold.jpg │ ├── Edward.jpg │ └── Robert.jpg ├── fr_onnx.py ├── img │ ├── friends.jpg │ └── test1.jpg └── model ├── face_detection.onnx └── face_recognition.onnx
将目标识别图片置于 ./img 文件夹。
流程图


代码
终端执行 touch fr.py 新建程序文件,并添加如下代码
#!/usr/bin/env python3
import cv2, argparse, os
import numpy as np
from pathlib import Path
# -------------------- Face Recognition -------------------
def recognize_faces(img_path: str,
face_dir: str = "./face",
model_path: str = "./model/face_detection_yunet_2023mar.onnx",
rec_model: str = "./model/face_recognition_sface_2021dec.onnx") -> None:
img = cv2.imread(img_path)
if img is None:
raise FileNotFoundError(img_path)
h, w = img.shape[:2]
# 检测器
detector = cv2.FaceDetectorYN_create(
model=model_path, config="", input_size=(w, h),
score_threshold=0.8, nms_threshold=0.4, top_k=5000)
detector.setInputSize((w, h))
faces = detector.detect(img)[1]
if faces is None:
print("未检测到人脸")
return
recognizer = cv2.FaceRecognizerSF_create(rec_model, "")
regist = {} if args.retrain else load_registry() # name -> feature
if args.retrain or not regist:
print(">>> 重新提取注册照特征 <<<")
regist = {}
face_files = list(Path(face_dir).glob("*.*"))
n_total = len(face_files)
for idx, fp in enumerate(face_files, 1):
name = fp.stem
print(f"[Register] {idx:3d}/{n_total} {name}", end="\r")
reg_img = cv2.imread(str(fp))
if reg_img is None:
continue
rh, rw = reg_img.shape[:2]
detector.setInputSize((rw, rh))
else:
print(f">>> 已加载缓存 {len(regist)} 张注册照 <<<")
detector.setInputSize((w, h))
if not regist:
print("注册库为空")
return
# 逐一比对
for face in faces:
aligned = recognizer.alignCrop(img, face)
feat = recognizer.feature(aligned)
best_score, best_name = -1, "Unknown"
for name, reg_feat in regist.items():
score = recognizer.match(feat, reg_feat, cv2.FaceRecognizerSF_FR_COSINE)
if score > best_score:
best_score, best_name = score, name
# 画框
x, y, w_box, h_box = map(int, face[:4])
SIM_TH = 0.3
if best_score < SIM_TH:
best_name = "Unknown"
print(f"[{best_name}] score={best_score:.3f} box=({x},{y},{w_box},{h_box})")
color = (0, 255, 0) if best_name != "Unknown" else (0, 0, 255) # BGR
draw_rect_alpha(img, (x, y), (x + w_box, y + h_box), color, alpha=0.2)
cv2.rectangle(img, (x, y), (x + w_box, y + h_box), color, 2)
label = f"{best_name}:{best_score:.2f}"
font_scale = 0.8
(t_w, t_h), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, font_scale, 1)
draw_rect_alpha(img, (x, y - t_h - 4), (x + t_w, y), color, alpha=0.8)
cv2.namedWindow("Face Recognition", cv2.WINDOW_NORMAL)
cv2.imshow("Face Recognition", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# ---------- 命令行入口 ----------
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--image", default="./img/test.jpg", help="目标图片路径")
args = parser.parse_args()
if args.mode == "detect":
detect_faces_yunet(args.image)
else:
recognize_faces(args.image)保存代码。
效果
终端执行 python fr.py -i ./img/friends.jpg 指令,对目标图片进行人脸识别;
终端打印识别到的人脸名称、置信度、坐标等信息;


弹窗显示识别结果


更多测试效果

对于未注册人脸,则使用红色标注;

对于已注册人脸,则显示绿色姓名标签;


识别准确度和照片清晰度、人脸角度有关;

此外,可根据实际需求调整识别阈值,以获得最佳体验。
总结
本文介绍了树莓派 5 单板计算机结合 OpenCV 内置 YuNet 算法和 SFace 模型实现人脸识别的项目设计,包括环境部署、预训练模型获取、关键代码、板端推理、效果演示等流程,为相关产品在边缘 AI 领域的快速开发和应用设计提供了参考。
我要赚赏金
