摘要:利用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