文章目录
前言
提示:这里可以添加本文要记录的大概内容:
今天准备用qt做一个人脸识别功能,同时看能不能移植到板子上面
提示:以下是本篇文章正文内容,下面案例可供参考
一、Ubuntu中运行效果
通过摄像头检测到的人脸通过百度API在自己搭建的照片库中识别,然后将信息打印在终端上面,如上图的红色小框所示。后面其实还可以通过将百度api返回的数据通过json解析,然后将人的名字打印人脸旁边
; 二、代码部分
1.工程结构
上图左边为工程的结构,主要包括一些头文件。右边为pro文件里面的一些东西,人脸识别重要的是依赖各种库,比如curl openssl crypto opencv等等。右边就是让编译的时候链接相应的库文件,否则编译会报错
; 2.camera代码
代码如下(示例):
#include "camera.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include
#include
#include
#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;
string Base64Face;
Json::Value result;
time_t sec;
CascadeClassifier Classifier("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml");
std::string app_id = "xxxxx";
std::string api_key = "xxxxxxx";
std::string secret_key = "xxxxxx";
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) {
timer->start(33);
} else {
timer->stop();
}
return capture->isOpened();
}
void Camera::timerTimeOut()
{
if (!capture->isOpened()) {
timer->stop();
return;
}
*capture >> frame;
cvtColor(frame, GrayImage, COLOR_BGR2RGB);
Classifier.detectMultiScale(GrayImage, AllFace);
if(AllFace.size())
{
rectangle(GrayImage, AllFace[0], Scalar(255,255,0));
MatFace = GrayImage(AllFace[0]);
imencode(".jpg", MatFace, JpgFace);
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)
{
if(img.type() == CV_8UC3) {
const uchar *pimg = (const uchar*)img.data;
QImage qImage(pimg, img.cols, img.rows, img.step,
QImage::Format_RGB888);
return qImage.rgbSwapped();
}
return QImage();
}
代码总体比较简单,主要注意一下那几个api接口的key需要自己申请,相信网上也有很多教程。
上面代码有点杂乱,这下面有一个比较简单的代码,直接在ubuntu运行的,大家可以参照看下
#include
#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;
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;
std::string app_id = "xxxxx";
std::string api_key = "xxxxxxxxxxxxx";
std::string secret_key = "xxxxxxxxxxxx";
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);
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代码比较杂乱,可以参考下在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类是否有人脸存储,没有就不画矩形,这样就不会出现段错误了。
Original: https://blog.csdn.net/m0_57730390/article/details/125900553
Author: Jason~F
Title: 基于qt的人脸识别
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/638043/
转载文章受原作者版权保护。转载请注明原作者出处!