一、创建项目&UI设计
创建项目,UI设计如下
文件类型判断
简单的判断文件类型
QString file("sample.jpg");
if (file.contains(".jpg") || file.contains(".bmp") || file.contains(".png"))
qDebug()<<"这是图片。";
推荐使用QMimeDatabase类
QMimeDatabase db;
QMimeType mime = db.mimeTypeForFile("sample.bmp");
if (mime.name().startsWith("image/"))
qDebug()<<"这是图片。";
类型 | 描述 | 示例 |
---|---|---|
text | 普通文本 | text/plain, text/html, text/css, text/javascript |
image | 图像文件(包含动态gif) | image/gif, image/png, image/jpeg, image/bmp, image/webp |
audio | 音频文件 | audio/wav, audio/mpeg, audio/midi, audio/webm, audio/ogg |
video | 视频文件 | video/mp4, video/x-flv, video/webm, video/ogg |
application | 二进制数据 | application/xml, application/pdf |
二、代码与演示
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QFileDialog>
#include <QFile>
#include <opencv2/opencv.hpp>
#include <QMainWindow>
#include <QTimer>
#include <QImage>
#include <QPixmap>
#include <QDateTime>
#include <QMutex>
#include <QMutexLocker>
#include <QMimeDatabase>
#include <iostream>
QPixmap Mat2Image(cv::Mat src);
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
void Init();
~MainWindow();
private slots:
void readFrame(); //自定义信号处理函数
void on_pushButton_OpenFile_clicked();
void on_pushButton_StartDetect_clicked();
void on_pushButton_StopDetect_clicked();
void on_pushButton_FlushDevice_clicked();
private:
Ui::MainWindow *ui;
QTimer *timer;
QImage *img;
QString mp4_path = NULL;
cv::VideoCapture *capture;
cv::CascadeClassifier *classifier;
std::vector<cv::Rect> bodys;
int display_HeightWidth = 500;
int IsDetect_ok = 0; //用于判断是否加载了MP4和xml
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
timer = new QTimer(this);
timer->setInterval(33);
connect(timer,SIGNAL(timeout()),this,SLOT(readFrame()));
ui->pushButton_StartDetect->setEnabled(false);
ui->pushButton_StopDetect->setEnabled(false);
Init();
}
void MainWindow::Init()
{
capture = new cv::VideoCapture();
classifier = new cv::CascadeClassifier;
}
MainWindow::~MainWindow()
{
capture->release();
delete ui;
}
void MainWindow::readFrame()
{
cv::Mat frame, hsv_img, mask_img, gray_src;
capture->read(frame);
if (frame.empty()) return;
// int frame_width = capture->get(cv::CAP_PROP_FRAME_WIDTH);
// int frame_height = capture->get(cv::CAP_PROP_FRAME_HEIGHT);
// if (frame_width / frame_height >= 1){
// cv::resize(frame, frame, cv::Size(display_HeightWidth, (int)(frame_height * display_HeightWidth / frame_width)));
// }else{
// cv::resize(frame, frame, cv::Size((int)(frame_width * display_HeightWidth / frame_height), display_HeightWidth));
// }
//算法一:行人检测
cv::cvtColor(frame, gray_src, cv::COLOR_BGR2GRAY);
cv::equalizeHist(gray_src, gray_src);
classifier->detectMultiScale(gray_src, bodys, 1.1, 3, 0, cv::Size(30, 30));
for (size_t i = 0; i < bodys.size(); i++){
cv::rectangle(frame, bodys[i], cv::Scalar(0, 0, 255), 2, 8, 0);
}
//算法二:颜色跟踪
cv::cvtColor(frame, hsv_img, cv::COLOR_BGR2HSV);
cv::inRange(hsv_img, cv::Scalar(35, 43, 46), cv::Scalar(155, 255, 255), mask_img);
cv::Mat kernel = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
morphologyEx(mask_img, mask_img, cv::MORPH_CLOSE, kernel);
erode(mask_img, mask_img, kernel);
GaussianBlur(mask_img, mask_img, cv::Size(3, 3), 0, 0);
if (cv::waitKey(30) == 27) {
ui->textEdit_log->setText("Exit...");
ui->label_raw->clear();
return;
}
cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);
QImage rawImage = QImage((uchar*)(frame.data),frame.cols,frame.rows,frame.step,QImage::Format_RGB888);
ui->label_raw->setPixmap(QPixmap::fromImage(rawImage)); //显示源图像
QImage dstImage = QImage((uchar*)(mask_img.data),mask_img.cols,mask_img.rows,mask_img.step,QImage::Format_Grayscale8);
ui->label_detect->setPixmap(QPixmap::fromImage(dstImage)); //显示图像
}
void MainWindow::on_pushButton_OpenFile_clicked()
{
QString filename = QFileDialog::getOpenFileName(this,"打开文件",".","*.mp4 *.avi;;*.png *.jpg *.jpeg *.bmp");
if(!QFile::exists(filename)){
return;
}
ui->statusbar->showMessage(filename);
IsDetect_ok +=1;
if (IsDetect_ok ==2)
ui->pushButton_StartDetect->setEnabled(true);
QMimeDatabase db;
QMimeType mime = db.mimeTypeForFile(filename);
if (mime.name().startsWith("image/")) {
cv::Mat src = cv::imread(filename.toLatin1().data());
if(src.empty()){
ui->statusbar->showMessage("图像不存在!");
return;
}
cv::Mat temp;
if(src.channels()==4)
cv::cvtColor(src,temp,cv::COLOR_BGRA2RGB);
else if (src.channels()==3)
cv::cvtColor(src,temp,cv::COLOR_BGR2RGB);
else
cv::cvtColor(src,temp,cv::COLOR_GRAY2RGB);
QImage img = QImage((uchar*)temp.data,temp.cols,temp.rows,temp.step,QImage::Format_RGB888);
ui->label_raw->setPixmap(QPixmap::fromImage(img));
ui->label_raw->resize(ui->label_raw->pixmap()->size());
filename.clear();
}else if (mime.name().startsWith("video/")) {
capture->open(filename.toLatin1().data());
if (!capture->isOpened()){
ui->textEdit_log->append("fail to open MP4!");
return;
}
ui->textEdit_log->append(QString::fromUtf8("Open video: %1 succesfully!").arg(filename));
//获取整个帧数
long totalFrameNumber = capture->get(CV_CAP_PROP_FRAME_COUNT);
ui->textEdit_log->append(QString::fromUtf8("整个视频共 %1 帧").arg(totalFrameNumber));
ui->label_raw->resize(QSize(capture->get(CV_CAP_PROP_FRAME_WIDTH), capture->get(CV_CAP_PROP_FRAME_HEIGHT)));
//设置开始帧()
long frameToStart = 0;
capture->set(CV_CAP_PROP_POS_FRAMES, frameToStart);
ui->textEdit_log->append(QString::fromUtf8("从第 %1 帧开始读").arg(frameToStart));
//获取帧率
double rate = capture->get(CV_CAP_PROP_FPS);
ui->textEdit_log->append(QString::fromUtf8("帧率为: %1 ").arg(rate));
}
}
void MainWindow::on_pushButton_StartDetect_clicked()
{
timer->start();
ui->pushButton_StartDetect->setEnabled(false);
ui->pushButton_StopDetect->setEnabled(true);
}
void MainWindow::on_pushButton_StopDetect_clicked()
{
ui->pushButton_StartDetect->setEnabled(true);
ui->pushButton_StopDetect->setEnabled(false);
timer->stop();
}
void MainWindow::on_pushButton_FlushDevice_clicked()
{
QString xmlfilename = QFileDialog::getOpenFileName(this,"打开文件",".","*.xml");
if(!QFile::exists(xmlfilename)){
return;
}
ui->statusbar->showMessage(xmlfilename);
if (!classifier->load(xmlfilename.toLatin1().data())) {
ui->textEdit_log->append("fail to open classifier_path!");
return;
}
IsDetect_ok +=1;
ui->textEdit_log->append(QString::fromUtf8("Open xmlfile: %1 succesfully!").arg(xmlfilename));
if (IsDetect_ok ==2)
ui->pushButton_StartDetect->setEnabled(true);
}
演示效果
拓展阅读
直接在属性栏目搜索中设置(如下图),或者 pushbutton设置icon和文字
下面是pushbutton设置icon和文字的四种方法详解
1.使用系统自带api
ui->pushButton->setIconSize(QSize(32,32));
ui->pushButton->setIcon(QIcon(":/images/Setting.png"));
ui->pushButton->setText(QString::fromLocal8Bit("系统设置"));
ui->pushButton->setStyleSheet("QPushButton{border:1px solid blue;background:white;}"
"QPushButton:hover{border:0px;background:blue;}"
"QPushButton:pressed{border:0px;background:red;}");
无法设置icon和文字之间的距离。
2.如果想让icon显示在文字上方可使用QToolButton
ui->toolButton->setIconSize(QSize(32,32));
ui->toolButton->setIcon(QIcon(":/images/Setting.png"));
ui->toolButton->setText(QString::fromLocal8Bit("系统设置"));
ui->toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
3.在pushbutton上面使用label进行布局
QLabel *iconLabel = new QLabel;
QLabel *textLabel = new QLabel;
iconLabel->setFixedSize(32,32);
iconLabel->setStyleSheet("border:1px solid red;");
textLabel->setStyleSheet("border:1px solid red;");
iconLabel->setPixmap(QPixmap(":/images/Setting.png"));
textLabel->setText(QString::fromLocal8Bit("系统设置"));
textLabel->setFixedWidth(60);
QHBoxLayout *myLayout = new QHBoxLayout();
myLayout->addSpacing(10);
myLayout->addWidget(iconLabel);
myLayout->addSpacing(30);
myLayout->addWidget(textLabel);
myLayout->addStretch();
ui->pushButton_2->setLayout(myLayout);
ui->pushButton_2->setStyleSheet("QPushButton{border:1px solid blue;background:white;}"
"QPushButton:hover{border:0px;background:blue;}"
"QPushButton:pressed{border:0px;background:red;}");
4.使用图片,设置stylesheet即可
以上三种方法,需要设置,比较麻烦,最好还是找UI设计按钮图片,这样软件的适配性也比较好。
到此这篇关于Qt+OpenCV实现目标检测详解的文章就介绍到这了,更多相关Qt OpenCV目标检测内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!