0
点赞
收藏
分享

微信扫一扫

Qt + OpenCV 目标检测(opencv自带xml文件)


文章目录

  • ​​一、创建项目&UI设计​​
  • ​​文件类型判断​​
  • ​​二、代码与演示​​
  • ​​演示效果​​

一、创建项目&UI设计

创建项目,UI设计如下

Qt + OpenCV 目标检测(opencv自带xml文件)_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
#define
#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);
}

演示效果

Qt + OpenCV 目标检测(opencv自带xml文件)_qt_02


拓展阅读:

直接在属性栏目搜索中设置(如下图),或者 pushbutton设置icon和文字

Qt + OpenCV 目标检测(opencv自带xml文件)_#include_03


举报

相关推荐

0 条评论