摘要:利用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(,,,);//设置文件对话框的显示位置
fileDialog->setDirectory(".");//设置文件对话框打开时初始打开的位置
if(fileDialog->exec() == QDialog::Accepted)
{
//注意使用的是QFileDialog::Accepted或者QDialog::Accepted,不是QFileDialog::Accept
path = fileDialog->selectedFiles()[];//得到用户选择的文件名
}
delete fileDialog;
return path;
} Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
state = ;
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 = ;
ui->label->setText("FaceNum: " + QString::number(num));
srcImage = Mat::zeros(, , CV_8UC3);//图像显示部分初始设置黑色
this->update();
} Widget::~Widget()
{
delete ui;
}
void Widget::on_button1_clicked()
{
if(state == )
{
state = ;
if(videoCap.open())//摄像头读取视频流
{
srcImage = Mat::zeros(videoCap.get(CV_CAP_PROP_FRAME_HEIGHT), videoCap.get(CV_CAP_PROP_FRAME_WIDTH), CV_8UC3);
theTimer.start();//time信号
}
}
} void Widget::on_button2_clicked()
{
if(state == )
{
state = ;
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();
}
}
}
void Widget::on_button3_clicked()
{
if(state == )
{
state = ;
string path_ = mydialog("Open Picture").toStdString();
srcImage = imread(path_);
updateImage();
}
}
void Widget::on_button4_clicked()
{
num = ;
switch(state)
{
case : break;
case :
srcImage = Mat::zeros(, , CV_8UC3);
theTimer.stop();
this->update();
videoCap.release();
break;
case :
srcImage = Mat::zeros(, , CV_8UC3);
theTimer.stop();
this->update();
videoCap.release();
break;
case :
srcImage = Mat::zeros(, , CV_8UC3);
this->update();
break;
}
state = ;
}
void Widget::updateImage()
{
if(state == || state == )
{
videoCap >> srcImage;
}
if(srcImage.data)
{
vector<Rect> faces;
face_cascade.detectMultiScale(srcImage, faces, 1.1, , , Size(,), Size(,));
num = faces.size();
if(faces.size() >= )
{
for(size_t i=;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(, , ), , , );
}
}
cvtColor(srcImage, srcImage, CV_BGR2RGB);//Qt中支持的是RGB图像, OpenCV中支持的是BGR
cv::resize(srcImage, srcImage, Size(,));
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(,), 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 = );
~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