文章目录
前言一、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的人脸识别》对你有帮助,请点赞、收藏,并留下你的观点哦!