失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 基于qt的人脸识别

基于qt的人脸识别

时间:2020-08-07 08:38:09

相关推荐

基于qt的人脸识别

文章目录

前言一、Ubuntu中运行效果二、代码部分1.工程结构2.camera代码移植到linux板子上面的思路

前言

提示:这里可以添加本文要记录的大概内容:

今天准备用qt做一个人脸识别功能,同时看能不能移植到板子上面

提示:以下是本篇文章正文内容,下面案例可供参考

一、Ubuntu中运行效果

通过摄像头检测到的人脸通过百度API在自己搭建的照片库中识别,然后将信息打印在终端上面,如上图的红色小框所示。后面其实还可以通过将百度api返回的数据通过json解析,然后将人的名字打印人脸旁边

二、代码部分

1.工程结构

上图左边为工程的结构,主要包括一些头文件。右边为pro文件里面的一些东西,人脸识别重要的是依赖各种库,比如curl openssl crypto opencv等等。右边就是让编译的时候链接相应的库文件,否则编译会报错

2.camera代码

代码如下(示例):

/******************************************************************Copyright © Deng Zhimao Co., Ltd. 1990-. All rights reserved.* @projectName 05_opencv_camera* @brief camera.cpp* @author Deng Zhimao* @email 1252699831@* @net * @date-03-17*******************************************************************/#include "camera.h"#include "opencv2/core/core.hpp"#include "opencv2/highgui/highgui.hpp"#include <QImage>#include <QDebug>#include <iostream>#include "opencv2/opencv.hpp"#include "face.h"using namespace std;using namespace cv;using namespace aip;static cv::Mat frame;Mat GrayImage; //保存处理后的图片vector<Rect> AllFace;//检测到的人脸Mat MatFace; //保存被标记出来的人脸图像vector<uchar> JpgFace; //保存被转化为jpg格式的人脸图片string Base64Face;//用于保存转换后的图片Json::Value result;//百度智能云的返回信息time_t sec; //显示时间/* 打开人脸实例文件用来检测人脸 */CascadeClassifier Classifier("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml");/* 新建一个client, 对接百度智能云 */std::string app_id = "xxxxx";//"你的 App ID";std::string api_key = "xxxxxxx"; //"你的 Api key"std::string secret_key = "xxxxxx";//"你的 Secret Key"aip::Face client(app_id, api_key, secret_key);Camera::Camera(QObject *parent) :QObject(parent){/* 实例化 */capture = new cv::VideoCapture();timer = new QTimer(this);/* 信号槽连接 */connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeOut()));}Camera::~Camera(){delete capture;capture = NULL;}void Camera::selectCameraDevice(int index){/* 如果有其他摄像头打开了,先释放 */if (capture->isOpened()) {capture->release();}/* 打开摄像头设备 */capture->open(index);}bool Camera::cameraProcess(bool bl){if (bl) {/* 为什么是33?1000/33约等于30帧,也就是一秒最多显示30帧 */timer->start(33);} else {timer->stop();}/* 返回摄像头的状态 */return capture->isOpened();}void Camera::timerTimeOut(){/* 如果摄像头没有打开,停止定时器,返回 */if (!capture->isOpened()) {timer->stop();return;}/* static cv::Mat frame;Mat GrayImage; //保存处理后的图片vector<Rect> AllFace;//检测到的人脸Mat MatFace; //保存被标记出来的人脸图像*//* 打开人脸实例文件用来检测人脸 *//* CascadeClassifier Classifier("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml");*/*capture >> frame;cvtColor(frame, GrayImage, COLOR_BGR2RGB/*CV_BGR2GRAY*/); //转化为灰度图片//equalizeHist(GrayImage, GrayImage); //调整对比度,强化脸部轮廓Classifier.detectMultiScale(GrayImage, AllFace); //保存检测到的人脸if(AllFace.size()){//在图片上用矩形标记出人脸rectangle(GrayImage, AllFace[0], Scalar(255,255,0));MatFace = GrayImage(AllFace[0]);imencode(".jpg", MatFace, JpgFace);//jpg格式转换成base64,并且上传到百度智能云进行人脸搜索Base64Face = base64_encode((char *)JpgFace.data(), JpgFace.size());result = client.search(Base64Face, "BASE64", "Teaching", aip::null);/*打印百度智能云返回的信息*/cout<<result<<endl;}if (GrayImage.cols)/* 发送图片信号 */emit readyImage(matToQImage(GrayImage));}QImage Camera::matToQImage(const cv::Mat &img){/* USB摄像头和OV5640等都是RGB三通道,不考虑单/四通道摄像头 */if(img.type() == CV_8UC3) {/* 得到图像的的首地址 */const uchar *pimg = (const uchar*)img.data;/* 以img构造图片 */QImage qImage(pimg, img.cols, img.rows, img.step,QImage::Format_RGB888);/* 在不改变实际图像数据的条件下,交换红蓝通道 */return qImage.rgbSwapped();}/* 返回QImage */return QImage();}

代码总体比较简单,主要注意一下那几个api接口的key需要自己申请,相信网上也有很多教程。

上面代码有点杂乱,这下面有一个比较简单的代码,直接在ubuntu运行的,大家可以参照看下

#include <iostream>#include "opencv2/opencv.hpp"#include "face.h"using namespace std;using namespace cv;using namespace aip;int main(){Mat ColorImage; //保存图片Mat GrayImage;//保存处理后的图片vector<Rect> AllFace;//检测到的人脸Mat MatFace; //保存被标记出来的人脸图像vector<uchar> JpgFace; //保存被转化为jpg格式的人脸图片string Base64Face;//用于保存转换后的图片Json::Value result;//百度智能云的返回信息time_t sec; //显示时间/* 打开摄像头 */VideoCapture cap(0);if(!cap.isOpened()){cout << "Camera open failed" << endl;return 0;}cout << "Camera open success" << endl;cap >> ColorImage; //拍照/* 新建一个client, 对接百度智能云 */std::string app_id = "xxxxx";//"你的 App ID";std::string api_key = "xxxxxxxxxxxxx"; //"你的 Api key"std::string secret_key = "xxxxxxxxxxxx";//"你的 Secret Key"aip::Face client(app_id, api_key, secret_key);/* 打开人脸实例文件用来检测人脸 */CascadeClassifier Classifier("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml");/* 拍照 */while(1){cap >> ColorImage; //拍照cvtColor(ColorImage, GrayImage, CV_BGR2GRAY); //转化为灰度图片 equalizeHist(GrayImage, GrayImage); //调整对比度,强化脸部轮廓Classifier.detectMultiScale(GrayImage, AllFace); //保存检测到的人脸if(AllFace.size()){//在图片上用矩形标记出人脸rectangle(GrayImage, AllFace[0], Scalar(255,255,0));MatFace = GrayImage(AllFace[0]);imencode(".jpg", MatFace, JpgFace);//jpg格式转换成base64,并且上传到百度智能云进行人脸搜索Base64Face = base64_encode((char *)JpgFace.data(), JpgFace.size());result = client.search(Base64Face, "BASE64", "Teaching", aip::null);/*打印百度智能云返回的信息*/cout<<result<<endl; }imshow("video", GrayImage); //显示照片waitKey(40);}return 0;}

上述代码没有在qt里面,显得逻辑更为清楚—

效果其实是一样的效果,qt代码比较杂乱,可以参考下在ubuntu运行的代码逻辑即可

移植到linux板子上面的思路

首先要切换成正点原子的编译器,然后进行交叉编译的时候发现刚开始是找不到各种库文件,最后发现是因为链接路径里面没有加上如下的链接库,只有加上了才能找到库文件。

LIBS += -L/usr/local/lib

-lopencv_core

-lopencv_highgui

-lopencv_imgproc

-lopencv_videoio

-lopencv_imgcodecs

-lopencv_objdetect

-lcurl

-lcrypto

但是当这一步解决之后发现编译仍然出错,主要原因是下面的.so库格式不对。查了查才发现编译到板子上需要arm架构的动态库文件,而之前编译opencv得到的是x86架构的文件。解决思路是要么把opencv的动态库想办法编译成arm架构的,要么将原子出厂系统中/usr/lib文件下的所有.so拷贝出来替换掉ubuntu里面/usr/local/lib/下面的所有.so文件(后面在做)

/usr/local/lib/libopencv_superres.so👎 error: file not recognized: File format not recognized

代码中遇到的一些问题

刚开始写代码的时候发现,只要头一偏或者蒙住摄像头,程序就会立马段错误,经过检查发现是因为当检测不到人脸的时候,下一步执行画矩形的程序无法执行,从而出现段错误,故先得检测存储人脸的Mat类是否有人脸存储,没有就不画矩形,这样就不会出现段错误了。

如果觉得《基于qt的人脸识别》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。