1. 开发环境
Ubuntu18 + OpenCV3 + qt5
2.环境配置
1. 虚拟机安装Ubuntu
2. 安装qt5
下载完成后在下载目录打开终端,赋予可执行权限,再执行即可安装qt sudo chmod +x qt-opensource-linux-x64-5.12.8.run
3. 安装OpenCV库
可参考文章
4. 在QT中引用OpenCV库
若按照上述方法安装好opencv,创建测试项目,在pro文件中加入:
INCLUDEPATH += /usr/local/include //opencv头文件安装路径
LIBS += /usr/local/lib/libopencv_* //opencv库文件路径
测试:
#include <QWidget>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <QMessageBox>
#include <QDebug>
using namespace std;
using namespace cv;
//widget.cpp的析构函数
{
VideoCapture cap(0);
if(!cap.isOpened())
QMessageBox::warning(this,"error","open camera faild!");
cout << "open camera success" << endl;
Mat frame;
cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
cap.set(cv::CAP_PROP_FPS, 30);
for(;;){
cap >> frame;
if (frame.empty()) {
qDebug() << "错误:无法捕获帧";
break; // 退出循环或根据需要处理错误
}
imshow("video", frame);
waitKey(27);
}
}
(若出现警告 “VIDEOIO(V4L2:/dev/video0): select() timeout”,在虚拟机->设置->USB控制器,更改一下兼容性,更改为3.1即可解决问题)
启动程序若正常出现摄像头画面则表明安装配置成功。
ps:一般配置完成后你会发现摄像头是反镜像的(实际使用一般是镜像-前置摄像头)这是可以用flip函数来调整画面流frame:
flip(image, flippedImage, 1): 水平翻转
flip(image, flippedImage, 0): 垂直翻转
flip(image, flippedImage, -1): 水平和垂直同时翻转
flip 函数有三个参数,分别是:
**image:**输入图像,即需要进行翻转的原始图像。
**flippedImage:**输出图像,即翻转后的图像将存储在这里。
这里使用 flip(frame, frame, 1);即可改变原图形
3. 人脸检测
1.图像处理
- 将摄像头画面由rgb(彩色)转换为gray(灰度图)
#include <opencv2/imgproc.hpp> //所需头文件
#include <opencv2/objdetect.hpp>
cvtColor(frame,Grayimage,CV_BGR2GRAY);//将彩色图转换从灰度图 其中frame是初始Mat容器所存放的画面流,
//Grayimage是转换后的图像 CV_BGR2GRAY是参数
- 图形均衡化(调整亮度,对比度)
equalizeHist(InputArray src,OutputArray dst); //函数参数说明
equalizeHist(Grayimage,Grayimage); //进行均衡化处理,将处理后的图形进行覆盖(节约内存)
2.人脸轮廓检测
- 加载级联分类器(CascadeClassifier)(关于级联分类器相关可参考)
Ubuntu:/usr/share/opencv/haarcascades$ ls
haarcascade_eye_tree_eyeglasses.xml
haarcascade_eye.xml
haarcascade_frontalcatface_extended.xml
haarcascade_frontalcatface.xml
haarcascade_frontalface_alt2.xml
haarcascade_frontalface_alt_tree.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_default.xml
haarcascade_fullbody.xml
haarcascade_lefteye_2splits.xml
haarcascade_licence_plate_rus_16stages.xml
haarcascade_lowerbody.xml
haarcascade_profileface.xml
haarcascade_righteye_2splits.xml
haarcascade_russian_plate_number.xml
haarcascade_smile.xml
haarcascade_upperbody.xml
//这里我们使用OpenCV训练好的级联分类器进行人脸轮廓检测,可在构造函数中声明即可
classifier.load("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml");
if (classifier.empty()) {
qDebug() << "错误:无法加载级联分类器文件";
}
/*
detectMultiScale(InputArray image,vector<Rect>& objects) 检测函数说明
rectangle (InputOutputArray img,Point pt1,Point pt2,constScalar& color) 将检测到的人脸矩形框绘制在图形上的函数说明
*/
//具体使用:
vector<Rect> Allface; //矩形存放容器
//这里我们使用OpenCV库中已经训练好的级联分类器进行人脸轮廓的识别
classifier.detectMultiScale(Grayimage,Allface); //检测人脸矩形存放到vector容器中
if(Allface.size()){ //是否存在人脸
rectangle(Grayimage,Allface[0],Scalar(255,0,0)); //Allce中存放多个矩形(多张人脸,按照数组形式排列 Scalar改变颜色(rgb)
}
上述仅为关键代码
- 将检测的人脸矩形框保存
//先创建一个Mat容器用于存放截取到的矩形人脸框
Mat Matface; //存放检测的人脸矩形框
vector<uchar> JpgFace; //存放jpg格式的图形
if(Allface.size()){ //是否存在人脸
rectangle(Grayimage,Allface[0],Scalar(255,0,0)); //Allce中存放多个矩形(多张人脸,按照数组形式排列 Scalar改变颜色(rgb)
Matface = Grayimage(Allface[0]); //将截取的人脸存放到Matface中
imencode(".jpg",Matface,JpgFace); //将Matface中的图片转化成jpg格式
}
//imencode函数说明:
imencode(const String &ext,InputArray img,vector<uchar> &buf)
3.百度智能云平台注册
- 注册百度智能云平台
进入官网>产品>人脸识别>人脸搜索 官网链接
立即创建即可
即可在应用列表查看到自己的接口信息
- 创建人脸库
选择查看人脸库即可自定义添加组和人员,上传清晰人脸照即可
4.SDK环境搭建
- 技术文档 > SDK文档 > C++文档 > 按照流程下载人脸识别SDK到Ubuntu中(具体流程可参考文档)
- 安装依赖库libcurl(需要支持https)openssl(加密) jsoncpp
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install openssl
sudo apt-get install libjsoncpp-dev
- 将下载好的SDK解压,并将其base文件夹以及face.h(人脸检测只需这两个文件)文件复制到你的项目中参考文档
这里编译可能会出现报错找不到json和openssl路径,点击错误代码行,将其改为
#include <jsoncpp/json/json.h>
,#include "jsoncpp/json/json.h"
(即改变路径,在前面加上jsoncpp)
并安装libssl库
sudo apt-get install libssl-dev
LIBS += -lcurl -lcrypto -ljsoncpp //在pro文件中加入
并在程序中引入头文件和命名空间
#include <face.h>
using namespace aip;
5.平台接入
- 建立交互客户端client
//头文件中先声明client指针类型对象,再在构造函数中实例化赋值(使用完后需要用delete client进行销毁)
//widget.h
Face *client; //创建客户端对象
//widget.cpp
//建立百度交互客户端client
// 设置APPID/AK/SK
string app_id = "你自己的";
string api_key = "你自己的";
string secret_key = "你自己的";
client = new Face(app_id,api_key,secret_key);
- 格式转换
梳理一下我们的摄像头捕捉流程
frame(初始的彩色视频帧流) > Grayimage(灰度化)> Matface(存放截取的人脸矩形)> JpgFace(人脸矩形图片转化为JPG格式)> Base64Fce(转化为base64格式-百度人脸识别要求的格式)>>>>
//widget.h
//先在头文件的private中声明一个容器存放base64格式的图片
string Base64Face; //用于存放转换成base64格式的照片
//widget.cpp
Base64Face = base64_encode((char *)JpgFace.data(),JpgFace.size()); //将jpg格式的图片转化为base64格式的
- 接收检测结果
//widget.h
Json::Value result; //用于接受检测结果的容器
// 带参数调用人脸搜索函数说明
//result = client.face_search_v3(image, image_type, group_id_list, options);
result = client->face_search_v3(Base64Face,"BASE64","student",Json::nullValue);
cout << result <<endl; //打印测试结果
这里如果报错multiple definition (多重定义):可以将出现多重定义的函数定义为static(静态函数)
6.验证检测结果
可以看到控制台已经输出JSON格式的数据,并且检测成功文章来源:https://www.toymoban.com/news/detail-813312.html
7.解析数据
- json解析
//result返回json数据格式
{
"cached" : 0,
"error_code" : 0,
"error_msg" : "SUCCESS",
"log_id" : 2660475389,
"result" :
{
"face_token" : "952d7830427201926483ab1f02f015b8",
"user_list" :
[
{
"group_id" : "student",
"score" : 80.822387695312003,
"user_id" : "yyqx",
"user_info" : ""
}
]
},
"timestamp" : 1705394660
}
if(!result["result"].isNull()) //发送来的数据中result不为空(检测到人脸)
{
if(result["result"]["user_list"][0]["score"].asInt() >= 88) //提取数据中的score信息(匹配度高才算成功)
{
QString name = QString::fromStdString(result["result"]["user_list"][0]["user_id"].asString()); //将姓名转化成Qstring类型以便提示
QMessageBox::information(this,"欢迎!",name+"打卡成功!");
}
else if(result["result"]["user_list"][0]["score"].asInt() < 88) { //未在人脸库中
QMessageBox::information(this,"欢迎!","人员未注册,请联系管理员!");
}
}
jsoncpp的解析可参考
这里已经实现了人脸检测+识别+数据解析文章来源地址https://www.toymoban.com/news/detail-813312.html
- 获取系统时间
//widget.h
#include <QDateTime>
QDateTime currenttime; //获取时间
//更新后
if(!result["result"].isNull()) //发送来的数据中result不为空(检测到人脸)
{
if(result["result"]["user_list"][0]["score"].asInt() >= 88) //提取数据中的score信息(匹配度高才算成功)
{
currenttime = QDateTime::currentDateTime(); // 获取当前时间
QString checktime = currenttime.toString("yyyy-MM-dd hh:mm:ss"); // 将时间转换为字符串
QString name = QString::fromStdString(result["result"]["user_list"][0]["user_id"].asString()); // 将姓名转化成QString类型以便提示
QMessageBox::information(this, "欢迎!", name + "打卡成功!" + checktime);
}
else if(result["result"]["user_list"][0]["score"].asInt() < 88) { //未在人脸库中
QMessageBox::information(this,"欢迎!","人员未注册,请联系管理员!");
}
}
- 效果
到了这里,关于OpenCV+Ubuntu+QT实现人脸检测/识别(考勤管理)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!