基於opencv和qt的人臉檢測小系統


摘要:利用opencv讀取視頻、圖片並檢測人臉,利用QT顯示窗口,功能選擇等

環境:Ubuntu18.04、OpenCV3.4.0、QT5.10.1

效果圖:

代碼如下(比較簡單沒什么注釋):

main.cpp

#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.setWindowTitle("FaceDetect By lyj");
    w.show();
    return a.exec();
}

widget.cpp(xml文件路徑要根據個人情況修改)

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QPaintEvent>
#include <QTimer>
#include <QPainter>
#include <QPixmap>
#include <QLabel>
#include <QImage>
#include <QFileDialog>
#include <QString>
using namespace std;

QString mydialog(QString title)
{
    QString path;
    QFileDialog *fileDialog = new QFileDialog();//創建一個QFileDialog對象,構造函數中的參數可以有所添加。
    fileDialog->setWindowTitle(title);//設置文件保存對話框的標題
    fileDialog->setFileMode(QFileDialog::AnyFile);//設置文件對話框彈出的時候顯示任何文件,不論是文件夾還是文件
    fileDialog->setViewMode(QFileDialog::Detail);//文件以詳細的形式顯示,顯示文件名,大小,創建日期等信息;
    fileDialog->setGeometry(0,0,200,150);//設置文件對話框的顯示位置
    fileDialog->setDirectory(".");//設置文件對話框打開時初始打開的位置
    if(fileDialog->exec() == QDialog::Accepted)
    {
        //注意使用的是QFileDialog::Accepted或者QDialog::Accepted,不是QFileDialog::Accept
        path = fileDialog->selectedFiles()[0];//得到用戶選擇的文件名
    }
    delete fileDialog;
    return path;
}

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    state = 0;
    connect(&theTimer, &QTimer::timeout, this, &Widget::updateImage);//連接信號與槽,圖像刷新
    if(!face_cascade.load("/home/luoyijie/myprogram/qt_project/face_detection/haarcascade_frontalface_alt.xml"))
    {
        qDebug() << "load xml file failed";
    }
    num = 0;
    ui->label->setText("FaceNum: " + QString::number(num));
    srcImage = Mat::zeros(480, 640, CV_8UC3);//圖像顯示部分初始設置黑色
    this->update();
}

Widget::~Widget()
{
    delete ui;
}
void Widget::on_button1_clicked()
{
    if(state == 0)
    {
        state = 1;
        if(videoCap.open(0))//攝像頭讀取視頻流
        {
            srcImage = Mat::zeros(videoCap.get(CV_CAP_PROP_FRAME_HEIGHT), videoCap.get(CV_CAP_PROP_FRAME_WIDTH), CV_8UC3);
            theTimer.start(33);//time信號
        }
    }
}

void Widget::on_button2_clicked()
{
    if(state == 0)
    {
        state = 2;
        string path_ = mydialog("Open Video").toStdString();
        if(videoCap.open(path_))
        {
            srcImage = Mat::zeros(videoCap.get(CV_CAP_PROP_FRAME_HEIGHT), videoCap.get(CV_CAP_PROP_FRAME_WIDTH), CV_8UC3);
            theTimer.start(33);
        }
    }
}
void Widget::on_button3_clicked()
{
    if(state == 0)
    {
        state = 3;
        string path_ = mydialog("Open Picture").toStdString();
        srcImage = imread(path_);
        updateImage();
    }
}
void Widget::on_button4_clicked()
{
    num = 0;
    switch(state)
    {
        case 0: break;
        case 1:
                srcImage = Mat::zeros(480, 640, CV_8UC3);
                theTimer.stop();
                this->update();
                videoCap.release();
                break;
        case 2:
                srcImage = Mat::zeros(480, 640, CV_8UC3);
                theTimer.stop();
                this->update();
                videoCap.release();
                break;
        case 3:
                srcImage = Mat::zeros(480, 640, CV_8UC3);
                this->update();
                break;
    }
    state = 0;
}
void Widget::updateImage()
{
    if(state == 1 || state == 2)
    {
        videoCap >> srcImage;
    }
    if(srcImage.data)
    {
        vector<Rect> faces;
        face_cascade.detectMultiScale(srcImage, faces, 1.1, 3, 0, Size(50,50), Size(500,500));
        num = faces.size();
        if(faces.size() >= 1)
        {
            for(size_t i=0;i<faces.size();i++)
            {
                Point p1(faces[i].x, faces[i].y);
                Point p2(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
                rectangle(srcImage, p2, p1, cvScalar(0, 0, 255), 1, 4, 0);
            }
        }
        cvtColor(srcImage, srcImage, CV_BGR2RGB);//Qt中支持的是RGB圖像, OpenCV中支持的是BGR
        cv::resize(srcImage, srcImage, Size(640,480));
        this->update();  //發送刷新消息
     }
}
void Widget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
    ui->label->setText("FaceNum: " + QString::number(num));
    QImage image1 = QImage((uchar*)(srcImage.data), srcImage.cols, srcImage.rows, QImage::Format_RGB888);
    painter.drawImage(QPoint(0,0), image1);
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTimer>
#include <QLabel>
#include <QPaintEvent>
#include <QPainter>
#include <QPixmap>
#include <QImage>
#include "cv.h"
#include "highgui.h"
#include "opencv.hpp"
using namespace cv;
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private slots:       //聲明槽
    void on_button1_clicked();
    void on_button2_clicked();
    void updateImage();
    void on_button4_clicked();
    void on_button3_clicked();
private:
    Ui::Widget *ui;          //ui界面對象指針
    QTimer theTimer;
    //QTimer 計時用;
    QLabel *imageLabel;
    Mat srcImage;
    VideoCapture videoCap;
    CascadeClassifier face_cascade;
    int state;//狀態 camera是1,video是2,picture是3,back返回0
    int num;//檢測到的人臉數量
protected:
    void paintEvent(QPaintEvent *e);
};
#endif // WIDGET_H

.pro工程配置文件和.ui文件在整個工程的鏈接里面

https://files.cnblogs.com/files/luoyijie/face_detection.tar.gz

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM