Qt OpenCV 学习(三):跟踪视频中的运动物体

1. mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <opencv2/opencv.hpp>

#include <QTimer>
#include <QPixmap>
#include <QDebug>
#include <QImage>

using namespace cv;
using namespace std;

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_btnPlay_clicked();

    void on_btnStop_clicked();

    void importFrame();

private:
    Ui::MainWindow *ui;

    VideoCapture capture;
    QTimer *timer;
    Mat frame;
    Ptr<BackgroundSubtractorMOG2>ptrMOG;
};
#endif // MAINWINDOW_H

2. mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);
    this->setWindowTitle("Video Play With Qt");

    // 高斯混合背景处理,创建一个 MOG2 背景提取器并应用
    ptrMOG = createBackgroundSubtractorMOG2(500, 16, false);

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(importFrame()));
}

MainWindow::~MainWindow() {
    delete ui;
}

void MainWindow::on_btnPlay_clicked() {
    capture.open("D:\\BaiduNetdiskDownload\\bike.avi");

    double rate = capture.get(CAP_PROP_FPS);
    double timerDelay = 1000 / rate;

    timer->start(timerDelay);
}

void MainWindow::on_btnStop_clicked() {
    timer->stop();
    capture.release();
}

void MainWindow::importFrame() {
    Mat currentFrame;
    Mat grayFrame, foreGround;

    capture >> currentFrame;
    if (!currentFrame.empty()) {
        qDebug() << "Video is running...";
        Mat result = currentFrame.clone();

        ptrMOG->apply(currentFrame, foreGround, 0.05);
        threshold(foreGround, foreGround, 25, 255, THRESH_BINARY);

        // 腐蚀操作消除噪声
        Mat kernelErode = getStructuringElement(MORPH_RECT, Size(5, 5));
        erode(foreGround, foreGround, kernelErode);

        // 膨胀操作突出目标
        Mat kernelDilate = getStructuringElement(MORPH_RECT, Size(11, 11));
        dilate(foreGround, foreGround, kernelDilate);

        // 框选运动目标
        vector<vector<Point>>contours;
        findContours(foreGround, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
        for (uint64 i = 0; i < contours.size(); i++) {
            rectangle(result, boundingRect(contours[i]), Scalar(0, 255, 255), 1);
        }
        cvtColor(result, result, COLOR_BGR2RGB);

        QImage showVideo = QImage((const unsigned char*)(result.data), result.cols, result.rows, result.step, QImage::Format_RGB888);
        ui->labelVideo->setPixmap(QPixmap::fromImage(showVideo.scaled(ui->labelVideo->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)));
    } else {
        qDebug() << "Play is over.";
        timer->stop();
    }
}
相关推荐
小幽余生不加糖3 分钟前
步进电机、有刷直流电机以及无刷直流电机对比
笔记·单片机·嵌入式硬件·学习·能源
癫狂的兔子20 分钟前
【Python】【NumPy】学习笔记
python·学习·numpy
YJlio23 分钟前
Streams 学习笔记(12.2):看见 NTFS 隐藏的备用数据流(ADS)
服务器·笔记·学习
im_AMBER27 分钟前
Leetcode 81 【滑动窗口(定长)】
数据结构·笔记·学习·算法·leetcode
崇山峻岭之间34 分钟前
Matlab学习笔记03
笔记·学习·matlab
崇山峻岭之间36 分钟前
Matlab学习记录08
开发语言·学习·matlab
山土成旧客1 小时前
【Python学习打卡-Day25】从程序崩溃到优雅处理:掌握Python的异常处理艺术
人工智能·python·学习
程序员笨鸟1 小时前
[特殊字符] React 高频 useEffect 导致页面崩溃的真实案例:从根因排查到彻底优化
前端·javascript·学习·react.js·面试·前端框架
YJlio2 小时前
Strings 学习笔记(12.1):从二进制里“扒”出明文信息的瑞士军刀
服务器·笔记·学习
有为少年2 小时前
带噪学习 | Ambient Diffusion (NeurIPS 2023)下篇
人工智能·深度学习·神经网络·学习·机器学习·计算机视觉