一、要求

1、使用百度人脸识别库
2、识别对比图片,获取图片相似度
3、显示最相似的明星照片、显示本人照片
4、调用摄像头拍照、比对查找最相似的明星脸
5、录入明星照片、查看照片列表、修改、删除照片

二、实现方式

2.1百度API封装

1、获取Token

鉴权认证参考:http://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu

填写API_Key和Secret_Key,运行程序后会自动读取,并保存在本地

2、配置https访问

需要依赖libcrypto-1_1.dll和libssl-1_1.dll库,可以在qt路径下找到,放在与exe同级目录下

编译器要选择32位的,62位无效

void BaiduFaceOnline::https_ssl_config(QNetworkRequest& NetworkRequest)
{QSslConfiguration config = NetworkRequest.sslConfiguration();config.setPeerVerifyMode(QSslSocket::VerifyNone);config.setProtocol(QSsl::TlsV1SslV3);NetworkRequest.setSslConfiguration(config);
}

3、相似度比对

访问API,https://aip.baidubce.com/rest/2.0/face/v3/match

使用QEventLoop阻塞等待响应结果

QNetworkReply * reply = NetAccManager->post(NetRequest, post_param);
QEventLoop eventLoop;
connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);

4、QImage转base64编码字符

图片的格式统一位为jpg

QString BaiduFaceOnline::image2base64_str(const QImage& img)
{QByteArray data;QBuffer buf(&data);img.save(&buf, "jpg");QString b64str = QString(data.toBase64());buf.close();return b64str;
}

baidufaceonline.h

#ifndef BAIDUFACEONLINE_H
#define BAIDUFACEONLINE_H#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QUrl>
#include <QNetworkReply>
#include <QMessageBox>
#include <QImage>
#include <QFile>
#include <QTextStream>
#include <QBuffer>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>class BaiduFaceOnline : public QObject
{Q_OBJECT
public:explicit BaiduFaceOnline(QObject *parent = nullptr);void https_ssl_config(QNetworkRequest& NetworkRequest);QString image2base64_str(const QImage& img);QImage base64_str2image(const QString & base64_str);void writeAccToken(const QString& token);QString readAccToken();public slots:void getAccToken();double FaceMatch(const QImage& image1, const QImage& image2);private slots:void getAccTokenReply(QNetworkReply* reply);double getFaceMatchReply(QNetworkReply* reply);private:QNetworkAccessManager* NetAccManager;QNetworkRequest NetRequest;/* 应用参数 */const QString API_Key = "填写自己的";const QString Secret_Key = "填写自己的";QString AccToken = "";/* 应用参数end */const QString FaceMatchUrl = "https://aip.baidubce.com/rest/2.0/face/v3/match";
};#endif // BAIDUFACEONLINE_H

baidufaceonline.cpp

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif#include "baidufaceonline.h"#include <QEventLoop>BaiduFaceOnline::BaiduFaceOnline(QObject *parent) : QObject(parent)
{NetAccManager = new QNetworkAccessManager(this);https_ssl_config(NetRequest);AccToken = readAccToken();qDebug() << "AccToken" <<AccToken;getAccToken();
}//配置https访问,win32依赖libcrypto-1_1.dll和libssl-1_1.dll,放在与exe同级目录下
void BaiduFaceOnline::https_ssl_config(QNetworkRequest& NetworkRequest)
{QSslConfiguration config = NetworkRequest.sslConfiguration();config.setPeerVerifyMode(QSslSocket::VerifyNone);config.setProtocol(QSsl::TlsV1SslV3);NetworkRequest.setSslConfiguration(config);
}
//QImage转base64编码字符串
QString BaiduFaceOnline::image2base64_str(const QImage& img)
{QByteArray data;QBuffer buf(&data);img.save(&buf, "jpg");QString b64str = QString(data.toBase64());buf.close();return b64str;
}
//base64编码字符串转QImage
QImage BaiduFaceOnline::base64_str2image(const QString & base64_str)
{QImage image;QByteArray base64_data = base64_str.toLatin1();image.loadFromData(QByteArray::fromBase64(base64_data));return image;
}
void BaiduFaceOnline::writeAccToken(const QString& token)
{QFile f("AccToken.txt");if(!f.open(QIODevice::WriteOnly | QIODevice::Text)){qDebug() << ("打开文件失败");}QTextStream txtOutput(&f);txtOutput << token;f.close();}
QString BaiduFaceOnline::readAccToken()
{QFile f("AccToken.txt");if(!f.open(QIODevice::ReadOnly | QIODevice::Text)){qDebug() << ("打开文件失败");return "";}QTextStream txtInput(&f);QString lineStr;lineStr = txtInput.readLine();f.close();return lineStr;
}//获取token
void BaiduFaceOnline::getAccToken()
{//鉴权认证参考:http://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhuif(AccToken.isEmpty()) {QStringList parlist;parlist.append(QString("grant_type=%1").arg("client_credentials"));parlist.append(QString("client_id=%1").arg(API_Key));parlist.append(QString("client_secret=%1").arg(Secret_Key));QByteArray parameters = parlist.join("&").toUtf8();QUrl url("https://aip.baidubce.com/oauth/2.0/token");NetRequest.setUrl(url);NetRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));connect(NetAccManager,&QNetworkAccessManager::finished,this,&BaiduFaceOnline::getAccTokenReply);NetAccManager->post(NetRequest,parameters);}
}
//获取token槽
void BaiduFaceOnline::getAccTokenReply(QNetworkReply* reply)
{QString error = reply->errorString();if (!error.isEmpty() && error != "Unknown error") {return;}if (reply->error() != QNetworkReply::NoError) {QMessageBox::warning(0,"","请求错误!");return;}else {QByteArray content = reply->readAll();reply->deleteLater();QJsonParseError jsonError;QJsonDocument doucment = QJsonDocument::fromJson(content, &jsonError);  // 转化为 JSON 文档if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)){  // 解析未发生错误if (doucment.isObject()){ // 文档只有一个json对象QJsonObject object = doucment.object();  // 转化为对象if (object.contains("access_token")){  // 包含指定的 keyQJsonValue value = object.value("access_token");  // 获取指定 key 对应的 valueif (value.isString()){  // 判断 value 是否为字符串AccToken =  value.toString();  // 将 value 转化为字符串qDebug()<< "parse AccToken:"<<AccToken;writeAccToken(AccToken);    //写入txt文件}}}}}disconnect(NetAccManager,&QNetworkAccessManager::finished,this,&BaiduFaceOnline::getAccTokenReply);
}//人脸对比
double BaiduFaceOnline::FaceMatch(const QImage& image1, const QImage& image2)
{qDebug() <<image1;qDebug() <<image2;QString img1_base64 = image2base64_str(image1);QString img2_base64 = image2base64_str(image2);QJsonObject post_data1;post_data1.insert("image", img1_base64);post_data1.insert("image_type", "BASE64");QJsonObject post_data2;post_data2.insert("image", img2_base64);post_data2.insert("image_type", "BASE64");QJsonArray img_array;img_array.append(post_data1);img_array.append(post_data2);QJsonDocument document;document.setArray(img_array);QByteArray post_param = document.toJson(QJsonDocument::Indented);qDebug() <<post_param;QUrl url(FaceMatchUrl + "?access_token=" + AccToken);NetRequest.setUrl(url);NetRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));QNetworkReply * reply = NetAccManager->post(NetRequest, post_param);QEventLoop eventLoop;connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);eventLoop.exec(QEventLoop::ExcludeUserInputEvents);double score = getFaceMatchReply(reply);qDebug() <<"score:" << score;return  score;
}double BaiduFaceOnline::getFaceMatchReply(QNetworkReply* reply)
{double  score = 0;qDebug() <<"reply";QString error = reply->errorString();if (!error.isEmpty() && error != "Unknown error"){return score;}if (reply->error() != QNetworkReply::NoError){qDebug() <<"请求错误!";return score;}else{QByteArray content = reply->readAll();QJsonParseError jsonError;QJsonDocument doucment = QJsonDocument::fromJson(content, &jsonError);  // 转化为 JSON 文档if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)){if (doucment.isObject()){QJsonObject root_object = doucment.object();if (root_object.take("error_code").toInt() == 0 && root_object.take("error_msg").toString() == "SUCCESS"){QJsonObject result_object = root_object.take("result").toObject();score = result_object.take("score").toDouble(); /*相似度: */}}}reply->deleteLater();}return score;
}

2.2 人脸搜索并找出最相似的

该任务比较耗时,放入线程中执行,采用moveToThread的方式

    // 调用 moveToThread 将该任务交给 workThreadauto *searchWorker = new SearchWorker ;searchWorker->moveToThread(&workerThread);// operate 信号发射后启动线程工作connect(this, SIGNAL(operate()), searchWorker, SLOT(doWork()));// 该线程结束时销毁connect(&workerThread, &QThread::finished, searchWorker, &QObject::deleteLater);// 线程结束后发送信号,对结果进行处理connect(searchWorker, &SearchWorker::resultReady, this, &CameraWidget::slot_handleResults);// 启动线程workerThread.start();

seachWorker封装

#ifndef SEARCHWORKER_H
#define SEARCHWORKER_H#include <QObject>class BaiduFaceOnline;
class SearchWorker: public QObject
{Q_OBJECT
public:explicit SearchWorker(QObject *parent = nullptr);public slots:void doWork();signals:/*** @brief resultReady 线程完成工作时发送的信号* @param score  相似度* @param name   图片名称*/void resultReady(double score, const QString &name);private:BaiduFaceOnline *m_baiduFace;
};#endif // SEARCHWORKER_H
#include "baidufaceonline.h"
#include "searchworker.h"
#include <QDir>SearchWorker::SearchWorker(QObject *parent):QObject(parent)
{m_baiduFace = new BaiduFaceOnline(this);
}void SearchWorker::doWork()
{/* 读取文件 */QString path = "./faces";QDir dir(path);if (!dir.exists()) {return;}// 设置过滤器dir.setFilter(QDir::Files | QDir::NoSymLinks);QStringList filters;filters << "*.jpg";dir.setNameFilters(filters);QStringList imgList = dir.entryList();if (imgList.count() <= 0) {return;}// 创建单元项double maxScore = 0;   /* 最大分数 */QString maxScoreName;for (int i = 0; i<imgList.count(); ++i) {QImage face1 = QImage("./m.jpg");QImage face2 = QImage(path + "/" + imgList.at(i));qDebug() <<face1.isNull() <<face2.isNull();double score = m_baiduFace->FaceMatch(face1, face2);if(score>=maxScore){maxScore = score;maxScoreName = imgList.at(i);}}qDebug() <<"end";qDebug() <<maxScoreName;emit resultReady(maxScore, maxScoreName);
}

2.3摄像头采集

可以查看我另一篇文章,使用qt自带封装的摄像头类QCamera、QCameraInfo、QCameraViewfinder、QCameraImageCapture

【QT】qt操作摄像头_Jason~shen的博客-CSDN博客_qt调用摄像头先上效果图左上角显示摄像头下拉选项,右上角分别是打开摄像头、关闭摄像头、截图保存的功能,左下显示摄像头内容,右下显示截图图片如何实现?1、在工程文件中添加,QT += multimedia(多媒体),QT += multimediawidgets2、主要用到的部件3、获取摄像头信息 //读取所有摄像头信息 QList<QCameraI...https://blog.csdn.net/qq_40602000/article/details/98875026

三、效果展示

源码下载qt+百度API实现人脸对比寻找明星脸-C++文档类资源-CSDN下载https://download.csdn.net/download/qq_40602000/85287399

Qt+百度API实现人脸对比寻找明星脸相关推荐

  1. Python调用百度API进行人脸对比

    目录 1. 作者介绍 2. 关于Base64知识介绍 2.1 Bsae64是什么 2.1 Bsae64编码原理 3. 实验过程 3.1 实验过程 3.2 实验代码 3.3 运行结果 3.4 问题分析 ...

  2. 调用百度API实现人脸对比

    百度API人脸对比 1.首先注册一个百度账号 2.百度AI平台https://ai.baidu.com/,找到 开放能力>人脸与人体检测>人脸对比>立即使用>创建应用 ,点击 ...

  3. 树莓派+百度api实现人脸识别

    title: 树莓派+百度api实现人脸识别 tags: 树莓派 date: 2018-5-31 20:06:00 --- 树莓派对接百度api 我以前玩安卓的时候一直用的讯飞的平台和api,对于百度 ...

  4. 智能门禁(7)----调用face++api实现人脸对比

    人脸识别(二)调用face++api实现人脸对比 首先来看一看调用的人脸对比的api需要的东西:  face++调用人脸对比api的网址: https://api-cn.faceplusplus.co ...

  5. 基于树莓派百度Api的人脸门禁系统--毕业设计

    基于树莓派百度Api的人脸门禁系统 在学校中因为上课原因,没有拿到关于电气及其自动化本专业的毕业题目,但是门禁系统让我眼前一亮.此题目是我硬着头皮接下的. 为了更好的做完自己的毕业设计,在不断的学习p ...

  6. 通过百度API检测人脸特征,获取颜值、年龄、性别--C语言实现

    文章目录 通过百度API检测人脸特征,获取颜值.年龄.性别--C语言实现 一.创建应用获取AK.SK 1.注册登陆后点击:人脸识别云服务 2.立即使用 3.免费尝鲜领取后.创建应用 4.拿到API K ...

  7. python3调用百度API完成人脸识别,检测人种-年龄-性别-颜值-眼镜

    https://ai.baidu.com/docs#/Face-Detect/top 这个是百度人脸识别api 参考博客:https://blog.csdn.net/qq_38412868/artic ...

  8. 调用百度人脸识别API进行人脸对比 C语言

    百度人脸识别api使用是免费的,有人脸对比.人脸搜索.人脸检测与属性分析三个功能,本文写的是人脸对比.这里给出百度人脸对比api的技术文档,请点击网址https://cloud.baidu.com/d ...

  9. 通过百度人脸对比API进行人脸对比

    百度人脸对比API的使用 今天突然有兴趣想做个人脸识别的小demo,项目代码地址:https://github.com/lxixi01/Face_Recognition 效果如下: 步骤: 第一步,需 ...

最新文章

  1. Kaggle Days首次落地中国,日本团队拿下冠军
  2. OSPF的RID和DR/BDR的选举
  3. 每次hexo d部署后都要在github仓库上重新保存域名
  4. 用命令行操作 VirtualBox 和 SGD
  5. 如何在修改checkbox状态,不触发事件
  6. c# load xml 中文报错
  7. 堆栈verilog设计实现及仿真
  8. vue 打包上线后字体图标不显示
  9. Maven报错找不到jre
  10. 重学TCP协议(9) 半连接队列、全连接队列
  11. uart ttl通讯测试可以短接吗_精讲!UART、RS232、RS422、RS485,绝了
  12. git只提交一张图片_几张图让你彻底弄懂git工作流(三) ——git深入
  13. 数论二(hdoj 卡特兰数)
  14. How to remove ROM in MAME
  15. java中中文显示乱码_java中显示中文乱码解决方法
  16. 感冒为什么会流鼻涕?
  17. (论文笔记)NeRV: Neural Representations for Videos
  18. FlinkX配置文件解析
  19. windows中SyncToy(微软同步工具) v2.1汉化版
  20. 达人评测 骁龙778g和骁龙780g的区别 选哪个好

热门文章

  1. 穹顶灯打不出阴暗面_知更鸟的崛起为愤怒的交易者带来了阴暗面
  2. 博学谷-数据分析matplotlib
  3. Ubuntu14.04 安装 TL-WN823N无线网卡驱动
  4. [Luogu3600] 随机数生成器 [概率期望动态规划 拉格朗日插值离散微积分]
  5. 从官网下载mysql 如何配置_从官网下载最新版Mysql并配置使用
  6. 用“找回你”,查找手机号的前身都被注册过些什么……
  7. Liunx之网络编程
  8. (深搜)蒜厂有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。(深搜)
  9. ppt转换成pdf转换器下载
  10. 房价必然增长的十个原因