OpenCV人脸识别C++代码实现Demo

news2024/11/17 14:53:34

        OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了很多函数,这些函数非常高效地实现了计算机视觉算法。

        官网:https://opencv.org/

        Github:   https://github.com/opencv/opencv

        Gitcode: https://gitcode.net/opencv/opencv

        OpenCV 的应用领域非常广泛,包括图像拼接、图像降噪、产品质检、人机交互、人脸识别、动作识别、动作跟踪、无人驾驶等。

        OpenCV 4.5.4版本开始,DNN模块集成了高性能的人脸检测算法(使用模型YuNet,由OpenCV China团队贡献)和人脸识别算法(使用模型SFace,由北京邮电大学邓伟洪教授课题组贡献)。

1. 人脸检测

1.1 接口定义

        OpenCV基于深度学习的人脸检测FaceDetectorYN类定义如下

/** @brief DNN-based face detector

model download link: https://github.com/opencv/opencv_zoo/tree/master/models/face_detection_yunet
 */
class CV_EXPORTS_W FaceDetectorYN
{
public:
    virtual ~FaceDetectorYN() {}

    /** @brief Set the size for the network input, which overwrites the input size of creating model. Call this method when the size of input image does not match the input size when creating model
     *
     * @param input_size the size of the input image
     */
    CV_WRAP virtual void setInputSize(const Size& input_size) = 0;

    CV_WRAP virtual Size getInputSize() = 0;

    /** @brief Set the score threshold to filter out bounding boxes of score less than the given value
     *
     * @param score_threshold threshold for filtering out bounding boxes
     */
    CV_WRAP virtual void setScoreThreshold(float score_threshold) = 0;

    CV_WRAP virtual float getScoreThreshold() = 0;

    /** @brief Set the Non-maximum-suppression threshold to suppress bounding boxes that have IoU greater than the given value
     *
     * @param nms_threshold threshold for NMS operation
     */
    CV_WRAP virtual void setNMSThreshold(float nms_threshold) = 0;

    CV_WRAP virtual float getNMSThreshold() = 0;

    /** @brief Set the number of bounding boxes preserved before NMS
     *
     * @param top_k the number of bounding boxes to preserve from top rank based on score
     */
    CV_WRAP virtual void setTopK(int top_k) = 0;

    CV_WRAP virtual int getTopK() = 0;

    /** @brief Detects faces in the input image. Following is an example output.

     * ![image](pics/lena-face-detection.jpg)

     *  @param image an image to detect
     *  @param faces detection results stored in a 2D cv::Mat of shape [num_faces, 15]
     *  - 0-1: x, y of bbox top left corner
     *  - 2-3: width, height of bbox
     *  - 4-5: x, y of right eye (blue point in the example image)
     *  - 6-7: x, y of left eye (red point in the example image)
     *  - 8-9: x, y of nose tip (green point in the example image)
     *  - 10-11: x, y of right corner of mouth (pink point in the example image)
     *  - 12-13: x, y of left corner of mouth (yellow point in the example image)
     *  - 14: face score
     */
    CV_WRAP virtual int detect(InputArray image, OutputArray faces) = 0;

    /** @brief Creates an instance of face detector class with given parameters
     *
     *  @param model the path to the requested model
     *  @param config the path to the config file for compability, which is not requested for ONNX models
     *  @param input_size the size of the input image
     *  @param score_threshold the threshold to filter out bounding boxes of score smaller than the given value
     *  @param nms_threshold the threshold to suppress bounding boxes of IoU bigger than the given value
     *  @param top_k keep top K bboxes before NMS
     *  @param backend_id the id of backend
     *  @param target_id the id of target device
     */
    CV_WRAP static Ptr<FaceDetectorYN> create(const String& model,
                                              const String& config,
                                              const Size& input_size,
                                              float score_threshold = 0.9f,
                                              float nms_threshold = 0.3f,
                                              int top_k = 5000,
                                              int backend_id = 0,
                                              int target_id = 0);

    /** @overload
     *
     *  @param framework Name of origin framework
     *  @param bufferModel A buffer with a content of binary file with weights
     *  @param bufferConfig A buffer with a content of text file contains network configuration
     *  @param input_size the size of the input image
     *  @param score_threshold the threshold to filter out bounding boxes of score smaller than the given value
     *  @param nms_threshold the threshold to suppress bounding boxes of IoU bigger than the given value
     *  @param top_k keep top K bboxes before NMS
     *  @param backend_id the id of backend
     *  @param target_id the id of target device
     */
    CV_WRAP static Ptr<FaceDetectorYN> create(const String& framework,
                                              const std::vector<uchar>& bufferModel,
                                              const std::vector<uchar>& bufferConfig,
                                              const Size& input_size,
                                              float score_threshold = 0.9f,
                                              float nms_threshold = 0.3f,
                                              int top_k = 5000,
                                              int backend_id = 0,
                                              int target_id = 0);

};

1.2 性能指标

        人脸检测模型YuNet在WIDER Face数据集的验证集中达到了0.8871(Easy AP),0.8710(Medium AP),0.7681(Hard AP);

1.3 C++调用示例代码

// 第一步:导入相关头文件
#include <opencv2/imgproc.hpp> 
#include <opencv2/objdetect.hpp>  
using namespace cv; 
int main() {
        // 模型下载地址:https://github.com/opencv/opencv_zoo/tree/main/models/face_detection_yunet
        String modelPath = "face_detection_yunet_2023mar.onnx";
        // 第二步:读取图像
        Mat img = imread("face.jpg");
        // 第三步:初始化FaceDetectorYN
        Ptr<FaceDetectorYN> faceDetector = FaceDetectorYN::create(modelPath, "", img.size());
        // 第四步:检测人脸并将结果保存到一个Mat中
        Mat faces; 
        faceDetector->detect(img, faces);
        // faces是一个nx15的二维Mat,每一行分别是:
        // [x1, y1, w, h, x_re, y_re, x_le, y_le, x_nt, y_nt, x_rcm, y_rcm, x_lcm, y_lcm, score]
        // 其中,x1, y1是人脸框左上角坐标,w和h分别是人脸框的宽和高;
        //      {x, y}_{re, le, nt, rcm, lcm}分别是人脸右眼瞳孔、左眼瞳孔、鼻尖、右嘴角和左嘴角的坐标;
        //       score是该人脸的得分。
        
        // ...
        
        return 0;
}

2. 人脸识别

2.1 接口定义

        OpenCV基于深度学习的人脸识别FaceRecognizerSF类定义如下

/** @brief DNN-based face recognizer

model download link: https://github.com/opencv/opencv_zoo/tree/master/models/face_recognition_sface
 */
class CV_EXPORTS_W FaceRecognizerSF
{
public:
    virtual ~FaceRecognizerSF() {}

    /** @brief Definition of distance used for calculating the distance between two face features
     */
    enum DisType { FR_COSINE=0, FR_NORM_L2=1 };

    /** @brief Aligning image to put face on the standard position
     *  @param src_img input image
     *  @param face_box the detection result used for indicate face in input image
     *  @param aligned_img output aligned image
     */
    CV_WRAP virtual void alignCrop(InputArray src_img, InputArray face_box, OutputArray aligned_img) const = 0;

    /** @brief Extracting face feature from aligned image
     *  @param aligned_img input aligned image
     *  @param face_feature output face feature
     */
    CV_WRAP virtual void feature(InputArray aligned_img, OutputArray face_feature) = 0;

    /** @brief Calculating the distance between two face features
     *  @param face_feature1 the first input feature
     *  @param face_feature2 the second input feature of the same size and the same type as face_feature1
     *  @param dis_type defining the similarity with optional values "FR_OSINE" or "FR_NORM_L2"
     */
    CV_WRAP virtual double match(InputArray face_feature1, InputArray face_feature2, int dis_type = FaceRecognizerSF::FR_COSINE) const = 0;

    /** @brief Creates an instance of this class with given parameters
     *  @param model the path of the onnx model used for face recognition
     *  @param config the path to the config file for compability, which is not requested for ONNX models
     *  @param backend_id the id of backend
     *  @param target_id the id of target device
     */
    CV_WRAP static Ptr<FaceRecognizerSF> create(const String& model, const String& config, int backend_id = 0, int target_id = 0);
};

2.2 性能指标

        人脸识别模型SFace在LFW数据集上达到了99.40%的准确率。

2.3 C++调用示例代码

2.3.1 人脸对齐

        将检测到的人脸输入人脸识别模型前,通常需要先进行人脸对齐。人脸对齐利用检测部分提取到的关键点,与给定关键点之间计算变换矩阵,使用仿射变换对人脸进行变换,以减轻人脸尺度、姿态等对人脸特征提取的性能的影响。

// 模型下载地址:https://github.com/opencv/opencv_zoo/tree/master/models/face_recognition_sface
String recog_model_path= "face_recognition_sface_2021dec.onnx";
// 初始化FaceRecognizerSF
Ptr<FaceRecognizerSF> faceRecognizer = FaceRecognizerSF::create(recog_model_path, "");

// 在人脸检测部分的基础上, 对齐检测到的首个人脸(faces.row(0)), 保存至aligned_face。
Mat aligned_face;
faceRecognizer->alignCrop(image, faces.row(0), aligned_face);

2.3.2 人脸特征提取

        人脸识别模型以尺寸为3*112*112的人脸图像对齐作为输入,输出维度为128维的人脸特征。

// 在上文的基础上, 获取对齐人脸的特征feature。
Mat feature;
faceRecognizer->feature(aligned_face, feature);

2.3.3 人脸特征比对

        对于不同人脸图像的人脸特征,经过人脸特征比对求出特征之间的距离,以确定不同人脸图像是否属于同一身份。当使用consine距离时,值越大,则人脸越相似身份越接近;当使用normL2距离时,值越小,则人脸越相似身份越接近。

// 在上文的基础上, 比对两张人脸的特征feature1,feature2以确认身份。
// 使用consine距离作为指标
const double cosine_similarity_threshold = 0.363;
double cos_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_COSINE); 
if (cos_score >= cosine_similarity_threshold)
{
        // the same identity 
}
else 
{
        // different identities
}

// 使用normL2距离作为指标
const double l2_similarity_threshold = 1.128;
double L2_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_NORM_L2); 
if (L2_score <= l2_similarity_threshold)
{
        // the same identity 
}
else 
{
        // different identities
}

3. 演示Demo

3.1 开发环境

  • OpenCV 4.9.0
  • Visual Studio 2015
  • Windows 10 Pro x64

3.2 功能介绍

        演示程序主界面如下图所示,具有人脸检测、人脸注册和人脸识别等功能。

        人脸检测:启动摄像头,进行实时人脸检测演示,结果显示在左侧(包括FPS,人脸框、五官坐标、人脸得分)。

        人脸注册:读取一张人脸图片,进行人脸检测、特征提取;左侧显示人脸检测结果,右侧显示对齐后人脸图,并保存人脸特征。

        人脸识别:读取一张人脸图片,进行人脸检测、特征提取,并与已存储的注册人脸特性进行比对;结果显示在左侧(其中:蓝色得分认为是同一人,红色得分认为是不同人)。

3.3 下载地址

        开发环境:

  • Windows 10 pro x64
  • Visual Studio 2015
  • OpenCV4.9.0

        下载地址: OpenCV人脸识别C++代码实现Demo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1642896.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何打包Apk适配32和64位

一个表格了解lib下的文件夹 .so文件描述armeabi-v7a第七代及以上的ARM处理器&#xff0c;2011年以后生产的大部分Android设备都使用。arm64-v8a第8代、64位ARM处理器&#xff0c;很少设备&#xff0c;三星GalaxyS6是其中之一。armeabi第5代、第6代的ARM处理器&#xff0c;早期…

C语言数据结构之队列

目录 1.队列的概念及结构2.队列的实现逻辑3.队列的代码实现4.相关例题选择题 •͈ᴗ•͈ 个人主页&#xff1a;御翮 •͈ᴗ•͈ 个人专栏&#xff1a;C语言数据结构 •͈ᴗ•͈ 欢迎大家关注和订阅!!! 1.队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#x…

Ubuntu系统安装nvfortran详细步骤【笔记】

实践设备&#xff1a;华硕FX-PRO&#xff08;NVIDIA GeForce GTX 960M&#xff09; Ubuntu系统安装NVFORTRAN&#xff08;NVIDIA Fortran Compiler&#xff09;步骤如下&#xff1a; 安装依赖项&#xff1a;在安装NVFORTRAN之前&#xff0c;你需要确保系统已经安装了一些必要…

IoTDB 入门教程 基础篇①——时序数据库为什么选IoTDB ?

文章目录 一、前文二、性能排行第一三、完全开源四、数据文件TsFile五、乱序数据高写入六、其他七、参考 一、前文 IoTDB入门教程——导读 关注博主的同学都知道&#xff0c;博主在物联网领域深耕多年。 时序数据库&#xff0c;博主已经用过很多&#xff0c;从最早的InfluxDB&a…

c语言刷题——输出图案

1.输出用“*”组成的X形图案 题目&#xff1a;请打印用“*”组成的X形图案 描述&#xff1a; 多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜线和正斜线的长度。 输出描述&#xff1a; 针对每行输…

一觉醒来 AI科技圈发生的大小事儿 05月04日

&#x1f4f3;CVPR 2024 Highlight | 基于单曝光压缩成像&#xff0c;不依赖生成模型也能从单张图像中重建三维场景 本文介绍了一种基于单曝光压缩成像&#xff08;SCI&#xff09;系统和神经辐射场&#xff08;NeRF&#xff09;的三维场景拍摄与重建方法&#xff0c;实现了不…

杭电acm2018 母牛的故事 Java解法 经典递归

标准递归题 先模拟 接着找递归出口 再找递归通式 想想看 今天的母牛等于前一天的母牛数加上今天出生的母牛 而三天前的母牛所有母牛都能生一头 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scnew Scanner(System.in);l…

单例、工厂、策略、装饰器设计模式

1. 单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a; 单例模式是一种常用的设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点。这种模式的特点是类自己负责保存其唯一的实例&#xff0c;并控制其实例化过程。单例模式广泛应用…

(六)SQL系列练习题(下)#CDA学习打卡

目录 三. 查询信息 16&#xff09;检索"1"课程分数小于60&#xff0c;按分数降序排列的学生信息​ 17&#xff09;*按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩 18&#xff09;*查询各科成绩最高分、最低分和平均分 19&#xff09;*按各科成绩…

【在线oj系统】02-开发环境版本说明

目录 一、前置环境版本介绍 二、SpringCloud组件停更/替换/更新 服务注册和发现 服务调用和负载均衡 分布式事务 服务熔断和降级 服务链路追踪 服务网关 分布式配置管理 三、客户端版本 一、前置环境版本介绍 使用Cloud的版本决定Boot的版本&#xff0c;SpringCloud的…

【C语言】分支和循环(上)

【C语言】分支和循环&#xff08;上&#xff09; 1、if语句1.2 else1.3分支中包含多条语句1.4嵌套if1.5悬空else问题 2、关系操作符3、条件操作符4、逻辑操作符&#xff1a;与、或、非&#xff08;取反&#xff09;&#xff08;&&&#xff0c;||&#xff0c;&#xff0…

从零开始学AI绘画,万字Stable Diffusion终极教程(五)

【第5期】ControlNet 欢迎来到SD的终极教程&#xff0c;这是我们的第五节课 这套课程分为六节课&#xff0c;会系统性的介绍sd的全部功能&#xff0c;让你打下坚实牢靠的基础 1.SD入门 2.关键词 3.Lora模型 4.图生图 5.controlnet 6.知识补充 在SD里面&#xff0c;想要…

Mysql复习笔记: 基础概念(待补充)

一. 基础概念 通用概念: 网络连接必须得分配给一个线程去进行处理&#xff0c;由一个线程来监听请求以及读取请求数据&#xff0c;比如从网络连接中读取和解析出来一条我们的系统发送过去的SQL语句 在数据库中&#xff0c;哪怕执行一条SQL语句&#xff0c;其实也可以是一个独立…

FLIR LEPTON3.5 热像仪wifi 科研实验测温采集仪

点击查看详情!点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情 1、描述 这是一款桌面科研实验测温热成像多功能热像记录仪&#xff0c;小巧轻便…

【C/C++】

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

## 01深度学习介绍与安装PyTorch

文章目录 深度学习的发展历史和基本概念早期历史兴起与发展基本概念 如何安装和设置PyTorch环境系统要求安装步骤验证安装 结语 深度学习的发展历史和基本概念 深度学习&#xff0c;一种通过使用具有多层结构的神经网络来学习数据的复杂模型的机器学习技术&#xff0c;近年来已…

Scikit是什么?

目录 一、Scikit是什么&#xff1f; 二、用Scikit做一个简单房价预测例子 三、sklearn知识点 一、Scikit是什么&#xff1f; Scikit就是scikit-learn&#xff0c;是一个免费软件机器学习库。 https://scikit-learn.org/stable/https://scikit-learn.org/stable/ 用于预测数…

ubuntu20配置深度学习环境

目录 系统环境安装anaconda文件的安装anaconda环境配置anaconda换中科大源常用的anaconda命令 安装显卡驱动安装CUDA下载cudnn安装pytorch更换conda源选择对应的pytorch版本进行安装 系统环境 ubuntu20&#xff0c;安装了ros noetic。 参考博客主要有&#xff1a; https://g…

【Spring】JdbcTemplate

JdbcTemplate 是 Spring 提供的一个 JDBC 模板类&#xff0c;是对 JDBC 的封装&#xff0c;简化 JDBC 代码 也可以让 Spring 集成其它的 ORM 框架&#xff0c;例如&#xff1a;MyBatis、Hibernate 等 使用 JdbcTemplate 完成增删改查 一、环境准备 数据库&#xff1a; 准备…

C++相关概念和易错语法(11)(npos、string的基本使用)

本文主要是分享一些基础的用法和接口&#xff0c;不会涉及迭代器版本&#xff0c;也没有底层概念&#xff0c;主要是保证简单入门和使用。 1.npos string本质上是一个类&#xff0c;里面包含了上百个成员函数&#xff0c;在调用这个头文件后&#xff0c;我们要知道整个类都被…