基于qt的人脸识别

文章目录

前言

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

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

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

一、Ubuntu中运行效果

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

; 二、代码部分

1.工程结构

基于qt的人脸识别
上图左边为工程的结构,主要包括一些头文件。右边为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的人脸识别
效果其实是一样的效果,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/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球