OpenCV结合Qt----人脸识别小demo

前不久用OpenCV的Haar级联分类器做了一个人脸识别的小demo,为了更直观方便地演示效果,将核心代码放在Qt里面做成一个完整的窗口项目。也是第一次使用Qt开发,遇到一些坑记录在这里。
首先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 : "<
    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文件中设计,大致效果如下:
OpenCV结合Qt----人脸识别小demo_第1张图片
可以考虑到如果没有打开摄像头就按人脸检测按钮,由于检测的图像数据为空,会出现程序异常,这里加了一个信息提示小窗口,提醒打开摄像头,效果如下:
OpenCV结合Qt----人脸识别小demo_第2张图片
现在打开摄像头试一下识别效果:
OpenCV结合Qt----人脸识别小demo_第3张图片
具体工程代码附录在文章后面。Qt工程代码

你可能感兴趣的:(Qt学习,人脸识别,opencv,qt)