这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取手持数字示波器】+OpenCV结合Qt人脸识别

共3条 1/1 1 跳转至

【换取手持数字示波器】+OpenCV结合Qt人脸识别

菜鸟
2024-04-29 19:36:29   被打赏 45 分(兑奖)     打赏

前不久用OpenCV的Haar级联分类器做了一个人脸识别的小demo,为了更直观方便地演示效果,将核心代码放在Qt里面做成一个完整的窗口项目。也是第一次使用Qt开发,遇到一些坑记录在这里。

先看一下我的一些学习的示例方法:

创建一个使用OpenCV和Qt的人脸识别小demo是一个有趣且实用的项目。以下是一个基本的步骤指南,帮助你开始这个项目:

1. 环境准备

  • 安装Qt:从Qt官网下载并安装Qt Creator,这是一个跨平台的C++ IDE,用于开发Qt应用程序。

  • 安装OpenCV:你需要安装OpenCV库。可以从OpenCV官网下载源代码,并按照官方文档编译和安装。也可以使用包管理器(如apt-get或conda)来安装。

  • 配置Qt项目以使用OpenCV:在Qt项目中,你需要配置.pro文件以包含OpenCV的头文件和库。

2. 创建Qt项目

  • 打开Qt Creator并创建一个新的Qt Widgets应用程序。

  • 设计用户界面,包括一个显示视频的窗口和一些控制按钮。

3. 集成OpenCV

  • 在你的Qt项目中包含OpenCV的头文件。

  • 使用OpenCV的VideoCapture类来捕获视频流。

  • 使用OpenCV的人脸检测器(如Haar级联或DNN模块)来检测视频中的人脸。

4. 显示和处理视频

  • 将捕获的视频帧转换为QImage,以便在Qt窗口中显示。

  • 在检测到人脸时,在视频帧上绘制矩形框。

  • 可以添加其他功能,如人脸跟踪、表情识别等。

5. 编译和运行

  • 配置Qt项目以使用OpenCV库。

  • 编译并运行你的应用程序。

6. 优化和调试

  • 优化性能,确保视频流畅。

  • 调试任何可能出现的问题。

大致流程图:

blob.png


示例代码片段

以下是一个简单的代码片段,展示了如何在Qt中捕获视频并使用OpenCV进行人脸检测:

#include <opencv2/opencv.hpp>  
#include <opencv2/objdetect/objdetect.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/imgproc/imgproc.hpp>  
  
// ... 其他Qt相关的头文件和代码 ...  
  
cv::CascadeClassifier face_cascade;  
cv::VideoCapture cap;  
  
void processFrame(const cv::Mat &frame) {  
    std::vector<cv::Rect> faces;  
    std::matvec faces;  
    cv::Mat frame_gray;  
  
    cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);  
    equalizeHist(frame_gray, frame_gray);  
  
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));  
  
    for (size_t i = 0; i < faces.size(); i++) {  
        cv::rectangle(frame, faces[i], cv::Scalar(0, 255, 0), 2);  
    }  
  
    // 将OpenCV的Mat转换为Qt的QImage以显示  
    QImage img((const unsigned char*)(frame.data), frame.cols, frame.rows, frame.step, QImage::Format_RGB888);  
    // ... 显示img在Qt窗口中 ...  
}  
  
void startVideoCapture() {  
    cap.open(0); // 打开默认摄像头  
    if (!cap.isOpened()) {  
        // 处理错误  
    }  
    face_cascade.load("path_to_haarcascade_frontalface_default.xml"); // 加载人脸检测器  
}  
  
// 在某个定时器槽函数中调用processFrame  
void onTimerTimeout() {  
    cv::Mat frame;  
    cap >> frame;  
    if (!frame.empty()) {  
        processFrame(frame);  
    }  
}

下面我是这样进行的。

首先Qt不用多介绍,一个跨平台的图形用户界面应用程序开发框架,在Qt中调用OpenCV库,首先要将其连接到Qt工程中,在pro文件中加入一些内容。

INCLUDEPATH += /usr/local/include \
                /usr/local/include/opencv4 \
                /usr/local/include/opencv2

LIBS += /usr/local/lib/libopencv_highgui.so \
        /usr/local/lib/libopencv_core.so    \
        /usr/local/lib/libopencv_imgproc.so \
        /usr/local/lib/libopencv_imgcodecs.so \
        /usr/local/lib/libopencv_objdetect.so \
        /usr/local/lib/libopencv_video.so \
        /usr/local/lib/libopencv_videoio.so

主要是将工程中使用到的库文件路径加入其中,这里注意每个人的安装目录不同。
要实现在窗口中显示摄像头采集图像,通过按钮打开摄像头和开启人脸识别功能,退出窗口按钮等。将这些操作定义了几个函数,定义如下:

private:
    Ui::MainWindow *ui;
    QTimer  *timer;
    QImage  *image;
    VideoCapture camera;
    Mat  img_cam;
    Mat img_detect;
    Mat  *frame;
    bool f_close_camera;

private slots:
    void on_closeButton_clicked();
    void openCamera();
    void closeCamera();
    void readFrame();
    QImage MatImageToQt(const Mat &src);
    void faceDetect();
    void openVideoFile();

其中定义了两个Mat矩阵,img_cam用于存放摄像头采集到的图像信息,img_detect用于存放待检测的图像信息。我们先介绍如何在Qt中使用OpenCV进行图像采集并显示在窗口的Label上面。使用OpenCV中用于打开摄像头,视频文件等的类VideoCapture,其使用方法也很简单如下是打开摄像头函数:

void MainWindow::openCamera()
{
    camera.open(0);
    timer->start(33);
    f_close_camera = 0;
}

每33毫秒刷新一次,结合帧显示函数将视频显示在窗口中:

void MainWindow::readFrame()
{
    camera.read(img_cam);
    QImage img = MatImageToQt(img_cam);
    //QImage img = QImage( (const unsigned char*)(img_cam.data), img_cam.cols, img_cam.rows, QImage::Format_RGB888 );
    ui->showCamera->setPixmap( QPixmap::fromImage(img) );
}

视频采集到之后就可以进行人脸位置的检测了,使用CascadeClassifier加载训练好XML文件,将人脸左边存放在一个Vector中,绘制矩形框在原图像中。

void MainWindow::faceDetect()
{
    std::vector<Rect> face;

    //QString xml_name = QFileDialog::getOpenFileName( this, tr("haarcascade_frontalface_default"), ".",  tr("Image Files(*.xml)") );
    //cout<<"path of xml file is : "<<xml_name.toLatin1().data()<<endl;
    if (img_cam.empty()) {
        QMessageBox::warning(NULL, "提醒", "摄像头还没开", QMessageBox::Yes | QMessageBox::No,
                                                QMessageBox::Yes);
    }

    CascadeClassifier faceCascade;
    faceCascade.load("/home/eden/qt_test/proj_1/build-face_detectot-Desktop_Qt_5_14_1_GCC_64bit-Debug/haarcascade_frontalface_default.xml");
    if(faceCascade.empty())
        cout<<"error 1 : XML file dot load"<<endl;

    while (true) {
            camera.read(img_detect);
            //cv::resize(img_detect, img_detect, Size(450, 450), INTER_LINEAR);
            //img_detect = img_cam;
            if (img_detect.empty()) {
                QMessageBox::warning(NULL, "提醒", "摄像头还没开", QMessageBox::Yes | QMessageBox::No,
                                                        QMessageBox::Yes);
                break;
            }

            faceCascade.detectMultiScale(img_detect, face, 1.1, 10);
            cout<<"br and tl of face is :"<<face.data()->br()<<face.data()->tl()<<face.size()<<endl;
             for (long unsigned int i = 0; i < face.size(); ++i) {
                rectangle(img_detect, face[i].tl(), face[i].br(), Scalar(255, 0, 255), 3);
                string face_num = to_string(i + 1)+" face found";
                putText(img_detect , face_num , {face[i].tl().x , face[i].tl().y} , FONT_HERSHEY_PLAIN , 1.5 ,Scalar(0 , 69 , 255) , 2) ;
            }
            QImage img = MatImageToQt( img_detect );
            ui->showFace->setPixmap( QPixmap::fromImage(img) );
            waitKey(1);

            if(f_close_camera) break;
    }
    ui->showFace->clear();
}

窗口样式在ui文件中设计,大致效果如下:

blob.png

可以考虑到如果没有打开摄像头就按人脸检测按钮,由于检测的图像数据为空,会出现程序异常,这里加了一个信息提示小窗口,提醒打开摄像头,效果如下:

blob.png

现在打开摄像头试一下识别效果:

blob.png

个人的帅照挡一下,

解释一下进行前的参考步骤:

在Qt的UI设计文件(通常是.ui文件,由Qt Designer生成)中设计窗口样式时,你可以使用Qt Designer的图形界面来创建和配置窗口的布局、控件和样式。以下是一个大致的步骤和描述,用于创建一个具有基本样式的人脸识别小demo的窗口:

  1. 启动Qt Designer
    打开Qt Designer,它通常是Qt安装的一部分。

  2. 创建新窗口
    在Qt Designer中,选择“Widgets”作为模板,然后点击“创建”来开始一个新的窗口设计。

  3. 设置窗口属性
    在“对象检查器”(Object Inspector)面板中,你可以设置窗口的标题、大小、图标等属性。

  4. 添加控件
    从左侧的“控件箱”(Widget Box)中,拖动需要的控件到窗口上。对于人脸识别demo,你可能需要:

    • QLabel:用于显示摄像头预览或识别结果。

    • QPushButton:用于开始/停止识别,或者加载/保存图片等。

    • QSlider(可选):用于调整摄像头参数,如亮度、对比度等。

    • QCheckBox(可选):用于启用/禁用某些功能。

  5. 布局管理
    使用布局管理器(如QHBoxLayout、QVBoxLayout、QGridLayout)来组织你的控件,以确保它们在不同屏幕尺寸和分辨率下都能正确显示。

  6. 设置样式

    • 在“属性编辑器”(Property Editor)中,你可以为每个控件设置样式属性,如字体、颜色、边框等。

    • 使用Qt样式表(QSS)来为整个窗口或特定控件设置更复杂的样式。你可以在“样式表”(StyleSheet)编辑框中输入QSS代码。

  7. 信号与槽
    虽然UI设计文件中不直接编写信号与槽的连接代码,但你可以在Qt Designer中设置控件的信号与槽的关联。这样,当你在Qt Creator中打开UI文件并生成相应的C++代码时,这些关联将被自动转换为代码中的信号与槽连接。

  8. 保存和导出
    保存你的UI设计文件(.ui),并在Qt Creator中打开它,或者使用uic工具将其转换为C++头文件(.h),以便在你的应用程序中使用。

  9. 在应用程序中使用
    在你的Qt应用程序中,加载并显示这个UI文件。这通常涉及创建一个继承自QMainWindow或QDialog的类,并在该类中加载UI文件。

  10. 添加人脸识别逻辑
    在应用程序的逻辑代码中,添加人脸识别功能。这通常涉及调用OpenCV库的相关函数来处理摄像头输入、检测人脸、识别身份等。






高工
2024-04-29 20:35:54     打赏
2楼

谢谢分享


高工
2024-04-30 11:44:45     打赏
3楼

谢谢分享


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]