这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 开源硬件 » 【树莓派5】人脸识别

共1条 1/1 1 跳转至

【树莓派5】人脸识别

工程师
2026-01-05 11:35:43     打赏

【树莓派 5 】人脸识别

本文介绍了树莓派 5 单板计算机结合 OpenCV 内置 YuNet 算法和 SFace 模型实现人脸识别的项目设计,包括环境部署、预训练模型获取、关键代码、板端推理、效果演示等流程。

项目介绍

  • 准备工作:硬件连接、OpenCV 安装、所需软件包和库安装等;

  • 人脸识别:模型获取、训练图片、流程图、代码、人脸识别的板端推理等;

准备工作

包括硬件连接、虚拟环境创建、OpenCV 安装、软件包和库安装等。

硬件连接

  • 将装有 Raspberry Pi OS 系统的 Micro-SD 卡置入目标插槽;

  • 使用 Mini-HDMI 数据线连接显示屏(也可使用 VNC 或 SSH 远程登录);

  • 使用 USB 接口连接鼠标键盘;

  • 使用 LAN 接口连接互联网(或使用 WiFi 连接无线网络);

hardware_connect.jpg


OpenCV 安装

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

opencv_logo.jpg

为了避免影响系统 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_version.jpg

详见:OpenCV .

人脸识别

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

fr_cover.jpg

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 文件夹。

fr_faces.jpg

文件目录

 ~/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 文件夹。

流程图

flowchart_fr.png


代码

终端执行 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 指令,对目标图片进行人脸识别;

  • 终端打印识别到的人脸名称、置信度、坐标等信息;

fr_print.jpg

  • 弹窗显示识别结果

fr_friends.jpg

  • 更多测试效果


fr_friends3.jpg

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

fr_test3.jpg

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

fr_test7.jpg

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

fr_friends7.jpg

此外,可根据实际需求调整识别阈值,以获得最佳体验。

总结

本文介绍了树莓派 5 单板计算机结合 OpenCV 内置 YuNet 算法和 SFace 模型实现人脸识别的项目设计,包括环境部署、预训练模型获取、关键代码、板端推理、效果演示等流程,为相关产品在边缘 AI 领域的快速开发和应用设计提供了参考。





关键词: 树莓派     OpenCV     YOLO     YuNet     人脸识    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]