虹软人脸识别 - 人脸特征数据的存取

文章目录

  • 虹软人脸识别 - 人脸特征数据的存取
    • 一、简介
    • 二、数据库应用
      • 1. 连接数据库
      • 2. 建表
      • 3. 注册人脸并保存其特征值到数据库
      • 4. 获取人脸特征数据库进行人脸识别
    • 三、工程配置
      • 1. 编译前准备
      • 2. 依赖说明
    • 四、功能界面展示
      • 1. 主界面预览
      • 2. 注册人脸
      • 3. 识别人脸

一、简介

人脸识别在社会中应用越来越多,提供人脸识别的 API 的公司也很多,如百度、商汤、Face++、虹软、微软等。在简单了解了这些不同企业提供的产品后,发现只有虹软是提供免费离线 SDK 的。使用在线 API,因为网络延迟实时性跟不上。刚开始用的时候还是 2.0 版本,现在已经 3.0 了,实测效果确实不错。在 3.0 后还可以在视频中追踪人脸,避免后重复识别提高了性能。

在网上关于 ArcSoft 的人脸识别 SDK — ArcFace 的开发教程已经很多了,而且 SDK 自带的官方文档也非常简单易懂,就不再重复介绍了。本文的主要内容是怎么使用
SDK 并结合数据库(可选 SQLite 和 MySQL)来保存人脸特征数据以及怎么使用这些特征,中间还包含了和人脸特征相关的部分 API 的使用。

在本文末提供了使用 ArcFace、Qt 编写的示例代码。

二、数据库应用

将数据库的操作封装为一个类,下面介绍封装类的具体实现。

1. 连接数据库

使用封装好的数据库对象连接数据库,具体的细节如下:

  • 使用 SQLite

连接数据库的接口(构造函数)


DatabaseSQLite(QString const & database_name);

实现


database_ = QSqlDatabase::addDatabase("QSQLITE", database_name);database_.setDatabaseName(database_name);database_.open();
  • 使用 MySQL

连接数据库的接口(构造函数)


DatabaseMySQL::DatabaseMySQL(QString const & host_name,QString const & user_name,QString const & password,QString const & database_name);

实现


database_ = QSqlDatabase::addDatabase("QMYSQL", database_name);database_.setHostName(host_name);database_.setUserName(user_name);database_.setPassword(password);database_.setDatabaseName(database_name);database_.open();

2. 建表

在连接上数据库后,如果数据库中不存在相应的表结构,需要立即创建相应的表来存放数据。

  • 使用 SQLite

建表


auto query = QSqlQuery(database_);query.exec("CREATE TABLE IF NOT EXISTS
features("           "\n""
id      INTEGER PRIMARY KEY
AUTOINCREMENT," "\n""    name
VARCHAR(32),"
"\n""    feature BLOB"                               "\n"");");
  • 使用 MySQL

建表


auto query = QSqlQuery(database_);query.exec("CREATE TABLE IF NOT EXISTS
features("            "\n""    id
INTEGER PRIMARY KEY AUTO_INCREMENT," "\n""    name
VARCHAR(32),"
"\n""    feature BLOB"                                "\n"");");

SQLite 和 MySQL 的建表操作区别如下:

SQLite MySQL
AUTOINCREMENT AUTO_INCREMENT

存放特征值的字段 feature 使用 BLOB,因为 ArcFace SDK 提取的特征是一串定长的二进制数据(目前 3.0 为 1032 字节)。
这里的表结构很简单,实际中可以根据业务需要扩展表结构。

3. 注册人脸并保存其特征值到数据库

将人名(文件名)和人脸特征值(通过 ArcFace SDK 获取)绑定加入到数据库和内存缓存。

获取人脸特征值的相关代码


// 读取本地文件并转为 B8G8R8 的格式QImage image = load(filename);// 将图片数据转换为 ArcFace SDK 图像的接口(这里用的使新版的接口)auto asf_image = ASVLOFFSCREEN();asf_image.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;asf_image.i32Width = image.width();asf_image.i32Height = image.height();asf_image.pi32Pitch[0] = 3 * image.width();asf_image.ppu8Plane[0] = const_cast<uint8_t *>(image.bits());auto faces_info = ASF_MultiFaceInfo();// 检测人脸,检测到的人脸位置信息存放在 faces_infoASFDetectFacesEx(handle, &asf_image, &faces_info);if (faces_info.faceNum == 0){ return; }// 仅处理第一个人脸(因为文件名只有一个,无法和多个人脸对应)auto face_info = ASF_SingleFaceInfo();face_info.faceRect = faces_info.faceRect[0];face_info.faceOrient = faces_info.faceOrient[0];auto asf_feature = ASF_FaceFeature();// 提取特征到 asf_featureASFFaceFeatureExtractEx(handle, &asf_image, &face_info,
&asf_feature);// 如果提取处理的特征值数据还在 ArcFace SDK 中,且下次再提取会被覆盖,所以对特征值数据进行复制auto feature =
std::vector<uint8_t>(static_cast<size_t>(asf_feat.featureSize));std::copy_n(asf_feat.feature, asf_feat.featureSize, feature.begin());// 添加到本地数据库和内存缓存,具体细节在下面详细说明database_->add(QFileInfo(filename).baseName(), std::move(feature));

保存单人脸特征到数据库的接口


auto add(QString name,Feature feature) -> bool;

实现

这里 SQLite 和 MySQL 的操作是一样的。

先将数据插入到数据库:


auto query = QSqlQuery(database_);query.prepare("INSERT INTO features(name,
feature)VALUES(:name, :feature);");auto feature_bytes = QByteArray(reinterpret_cast<char
*>(&feature[0]),static_cast<int>(feature.size()));query.bindValue(":name", name);query.bindValue(":feature", feature_bytes);query.exec();

在实际开发过程中,可能会同时插入多条人脸特征,这时使用事务可以提升性能。

在数据库插入成功后再把数据复制到内存中数据库数据的副本中,保证内存中人脸特征数据库和数据库中的一致:


features_.emplace_back(std::move(feature), std::move(name));

4. 获取人脸特征数据库进行人脸识别

该模块 SQLite 和 MySQL 的操作是一样的。

在程序启动时,将数据库中的人脸特征预加载到缓存中。

加载数据到缓存的实现


auto query = QSqlQuery(database_);query.exec("SELECT name, feature FROM
features");while (query.next()){auto name = query.value(QStringLiteral(u"name")).toString();auto feature =
query.value(QStringLiteral(u"feature")).toByteArray();features_.emplace_back(Feature(feature.cbegin(),
feature.cend()),std::move(name));}

上面代码中 features_ 的类型是
std::vector<std::pair<std::vector<uint8_t>, QString>>,可根据具体的需求调整。

人脸比对的实现


// 读取本地文件并转为 B8G8R8 的格式QImage image = load(filename);// 将 QImage 图像数据转换为 ASVLOFFSCREEN(3.0 的新接口)auto asf_image = ASVLOFFSCREEN();asf_image.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;asf_image.i32Width = image.width();asf_image.i32Height = image.height();asf_image.pi32Pitch[0] = 3 * image.width();asf_image.ppu8Plane[0] = const_cast<uint8_t *>(image.bits());auto faces_info = ASF_MultiFaceInfo();// 检测人脸,检测到的人脸信息存放在 faces_infoASFDetectFacesEx(handle, &asf_image, &faces_info);if (faces_info.faceNum == 0){ return; }// 相似度最高且高于阈值就认为是同一个人constexpr auto threshold = 0.8f;for (auto i = 0; i != faces_info.faceNum; ++i){auto face_info = ASF_SingleFaceInfo();face_info.faceRect =
faces_info.faceRect[i];face_info.faceOrient =
faces_info.faceOrient[i];auto asf_feat =
ASF_FaceFeature();ASFFaceFeatureExtractEx(handle,
&asf_image, &face_info, &asf_feat);auto name =
QString("?");auto max_similarity = 0.0f;// database_->features() 得到的是人脸特征数据库在内存中的缓存// 类型是
std::vector<std::pair<std::vector<uint8_t>, QString>>for (auto const & feat_name:
database_->features()){auto asf_feat2 = ASF_FaceFeature();asf_feat2.feature =
feat_name.first.data();asf_feat2.featureSize =
static_cast<int>(feat_name.first.size());auto similarity = 0.0f;ASFFaceFeatureCompare(face_engine_, &asf_feat, &asf_feat2,
&similarity);if (threshold <=
similarity && max_similarity < similarity){name = feat_name.second;max_similarity =
similarity;}}// 这里有个绘制人脸框的操作,因为与识别逻辑无关所以没有给出代码}

三、工程配置

1. 编译前准备

  • profile.ini 文件中填好在官网下载的 ArcFace SDK 的 APP_IDSDK_KEY

注意,因为使用的是相对路径,使用不同的启动方式文件放置的路径不同:
如果使用 Visual Studio,那么这个文件应该放到项目根目录下;
如果使用 Qt Creator,那个这个文件应该放到构建的二进制目录的父目录下(即 build-
开头的目录下);
如果是直接双击运行,那么这个文件应该放到程序所在目录的同级目录下。

2. 依赖说明

  • ArcFace SDK: 3.0。

  • Qt: 5.12.0。

    • 不同的版本 Qt 可能没有内置 MySQL 的动态库。

如果需要查看数据表,可以使用 Sqlite Expert。

示例代码下载路径(https://github.com/tz-byte/arcface-with-database)

四、功能界面展示

1. 主界面预览

2. 注册人脸

点击注册按钮,选取一张人脸图片,仅取第一张人脸进行特征提取,将文件名和人脸特征绑定存入数据库。

具体使用的是 SQLite 还是 MySQL 数据库,请在 widget.cpp 文件中搜索 database_.reset(new,默认是 SQLite。

3. 识别人脸

点击识别按钮,选取一张人脸的图片。

效果图:

绿色框表示识别成功,识别出来的结果在框内左下角。
红色框表示识别失败,可能是没有注册,或人脸相似度低于阈值。

虹软人脸识别 - 人脸特征数据的存取相关推荐

  1. Python机器学习:PCA与梯度上升:009人脸识别与特征脸(lfw_people数据集)

    将w的每一行想成一个样本,则第一行是最重要的样本..第二行次重要..(Wk特征engen face) CODE 我们使用lfw_people数据集 #人脸识别与特征脸 import numpy as ...

  2. 人脸识别之特征脸方法(Eigenface)

    人脸识别之特征脸方法(Eigenface) zouxy09@qq.com http://blog.csdn.net/zouxy09 因为需要,花了一点时间写了下经典的基于特征脸(EigenFace)的 ...

  3. 基于PCA 人脸识别/人脸识别算法/人脸检测程序源码MATLAB ELM+PCA人脸识别 PCA人脸识别matlab代码 基于PCA算法的人脸识别

    1.基于PCA的人脸识别代码 2.MATLAB ELM+PCA人脸识别 2.基于PCA的人脸识别(matlab)(采用PCA算法进行人脸识别,通过抽取人脸的主要成 分,构成特征脸空间,识别时将测试图像 ...

  4. K210人脸识别+人脸信息存储

    K210系列教程 使用MaixPy IDE开发K210 K210实现人脸识别(附代码解读) K210人脸识别+人脸信息存储 K210人脸识别+RFID录入信息 在我的上一篇博客中已经介绍了如何使用K2 ...

  5. 微信小程序公众号支付宝小程序的登录授权、支付、分享、人脸识别人脸核身

    文章目录 一.微信小程序 1. 获取信息用户信息 2.支付 3.分享 4. 腾讯云小程序人脸核身 二.微信公众号 1.获取信息用户信息 2.支付 3. 分享(普通分享) 4.分享(vue单页面 配置分 ...

  6. 人脸识别_云端人脸识别-人脸识别SDK+API-人脸识别闸机解决方案

    云端人脸识别-人脸识别SDK+API-人脸识别闸机解决方案 人脸识别闸机-人脸识别闸机解决方案 软硬一体的人脸识别闸机解决方案,提升人员系统化管理的安全性与便捷性 方案构成 针对人员出入的闸机及门禁场 ...

  7. 人脸反光识别和读数识别_云端人脸识别-人脸识别SDK+API-人脸识别闸机解决方案...

    云端人脸识别-人脸识别SDK+API-人脸识别闸机解决方案 人脸识别闸机-人脸识别闸机解决方案 软硬一体的人脸识别闸机解决方案,提升人员系统化管理的安全性与便捷性 方案构成 针对人员出入的闸机及门禁场 ...

  8. CV之FR之MTCNN:基于TF框架利用MTCNN算法检测并对齐人脸图像进(人脸识别/人脸相似度)而得出人脸特征向量从而计算两张人脸图片距离案例应用之详细攻略

    CV之FR之MTCNN:基于TF框架利用MTCNN算法检测并对齐人脸图像进(人脸识别/人脸相似度)而得出人脸特征向量从而计算两张人脸图片距离案例应用之详细攻略 目录 基于TF框架利用MTCNN算法检测 ...

  9. 人脸识别摄像头采集数据训练

    /* 交互式对话框:请选择要执行的动作1.人脸采集:打开摄像头,采集照片,保存训练模型2.人脸识别:<1>打开摄像头,采集照片,预识别:<2>输入图像的路径,图像识别输出结果: ...

最新文章

  1. HDU2642(二维的树状数组)
  2. JavaScript值得注意的小知识点
  3. Sysinternals Suite 2012.06.28软件简介
  4. vscode浏览器打开html
  5. win7系统 软件服务器地址,老司机传授win7系统设置DNS服务器地址的设置方案.
  6. php mirror怎么安装,如何安装Composer配置国内Packagist镜像
  7. LeetCode_database刷题记录(627. 交换工资)
  8. 国内外优秀音视频博客索引(持续更新)
  9. 全新卡盟系统PHP版 集成易支付_2020易支付系统/聚合支付系统源码/免签约聚合支付系统/集成易支付相互对接...
  10. 计算机windows7桌面管理,win7自带桌面整理,win7系统怎么改回自带桌面
  11. 数字时代:DevOps工程师的必备技能清单
  12. 用jq做一个点击图片放大消失
  13. Windows Touchpad 报告描述符实例
  14. UIPATH 发送SMTP电子邮件
  15. 悼念512汶川大地震遇难同胞——选拔志愿者(巴什博弈)
  16. 算法和数据结构开篇:开发面试前,不得不掌握的8种数据结构
  17. 为什么程序员和产品经理水火不容? | 每日趣闻
  18. 电子邮件中的to、cc、bcc
  19. 国家级荣誉!烽火参建的这个项目获“鲁班奖”
  20. 中国麒麟菜养殖产业发展现状分析,产量下降进口量上升「图」

热门文章

  1. tomcat启动一闪而逝
  2. 多个excel文件不在一个视图里分开独立显示
  3. POJO、DO、DTO、AO、BO、VO、JB、DAO、EJB
  4. Boundary Loss 原理与代码解析
  5. 2020巅峰极客wp
  6. 李晓洋出任百度资本CEO 负责投融资及全面管理工作
  7. java弱签名视为未签名,[java 被视为未签名]QQ幸福签名:你所愿,我终于将你视为平常,连看你一眼都觉得多余。...
  8. iphone7运行linux,我在iPhone7装入了Linux系统!
  9. Run Android apps in Windows, OS X, Linux with Chrome (and a modified runtime)
  10. Bootstrap下拉菜单