Qt OpenCV 学习(四):车道线检测

1. mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <opencv2/opencv.hpp>
#include <QString>
#include <QFileDialog>
#include <QTimer>
#include <QDebug>
#include <QLabel>

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();

    void showFrame();

private slots:
    void on_btnOpen_clicked();

    void on_btnPlay_clicked();

private:
    Ui::MainWindow *ui;
    QLabel *infoLabel;
    VideoCapture videoCap;
    QTimer *videoTimer;
};
#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);

    infoLabel = new QLabel();
    infoLabel->setMinimumWidth(200);
    this->statusBar()->addWidget(infoLabel);

    videoTimer = new QTimer();

    connect(videoTimer, &QTimer::timeout, this, &MainWindow::showFrame);
}

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

void MainWindow::showFrame() {
    Mat currentFrame;

    videoCap >> currentFrame;
    if (!currentFrame.empty()) {
        infoLabel->setText("video is playing");
        Mat gaussionFrame, grayFrame, cannyFrame;
        // 高斯变换
        GaussianBlur(currentFrame, gaussionFrame, Size(5, 5), 1, 0);
        // 灰度
        cvtColor(gaussionFrame, grayFrame, COLOR_BGR2GRAY);
        // canny 边缘检测
        Canny(grayFrame, cannyFrame, 50, 100);

        Mat resultFrame;
        Mat maskFrame = Mat::zeros(cannyFrame.size(), cannyFrame.type());

        vector<Point>polyPoints;
        polyPoints.push_back(Point(0, 368));
        polyPoints.push_back(Point(300, 210));
        polyPoints.push_back(Point(340, 210));
        polyPoints.push_back(Point(640, 368));

        fillPoly(maskFrame, vector<vector<Point>>{polyPoints}, Scalar(255, 255, 255));
        bitwise_and(cannyFrame, maskFrame, resultFrame);

        vector<Vec4i>lines;
        HoughLinesP(resultFrame, lines, 1, CV_PI / 180, 5, 40, 20);

        for (size_t i = 0; i < lines.size(); i++) {
            Vec4i carLine = lines[i];
            double lineSlope = (double(carLine[3]) - double(carLine[1])) / (double(carLine[2]) - double(carLine[0]));
            if (lineSlope > 0) {
                // 左车道线
                line(currentFrame, Point(carLine[0], carLine[1]), Point(carLine[2], carLine[3]), Scalar(0, 255, 255), 5, LINE_AA);
            } else if (lineSlope < 0) {
                // 右车道线
                line(currentFrame, Point(carLine[0], carLine[1]), Point(carLine[2], carLine[3]), Scalar(0, 255, 255), 5, LINE_AA);
            }
        }

        QImage showImg = QImage((const unsigned char*)(currentFrame.data), currentFrame.cols, currentFrame.rows, currentFrame.step, QImage::Format_RGB888);
        ui->labelPlay->setPixmap(QPixmap::fromImage(showImg.scaled(ui->labelPlay->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)));
    } else {
        infoLabel->setText("video is over");
        qDebug() << "video is over!";
        videoTimer->stop();
        videoCap.release();
    }
}

void MainWindow::on_btnOpen_clicked() {
    QString videoPath = QFileDialog::getOpenFileName(this, "open video", ".", "video(*.mp4 *.avi, *.flv); All files(*.*)");
    ui->lineEdit->setText(videoPath);
    infoLabel->setText("video is loaded");
}

void MainWindow::on_btnPlay_clicked() {
    ui->labelPlay->clear();
    QString videoPath = ui->lineEdit->text();
    videoCap.open(videoPath.toStdString());

    double rate = videoCap.get(CAP_PROP_FPS);
    double videoDelay = 1000 / rate;
    videoTimer->start(videoDelay);
}
相关推荐
传奇开心果编程3 小时前
【Rust入门知识点学与练】第24课:Trait 基础
开发语言·学习·rust
lqj_本人6 小时前
WinPcap 鸿蒙 PC 适配全记录:从 NPF 原始抓包到 VPN_TUN 与 libpcap 双通路
qt·华为·harmonyos
潜心一志7 小时前
HALCON软件——基本架构,算子参数
学习·计算机视觉
爱吃苹果的日记本9 小时前
数据结构第三课(时间复杂度)
数据结构·学习
Quz10 小时前
QML StackView:三种入栈方式(Item、Component 与 URL)
qt
Quz10 小时前
QML StackView:入栈、出栈、替换与批量操作
qt
泡泡鱼(敲代码中)12 小时前
MySQL基础学习笔记:从数据模型到DDL全掌握
开发语言·数据库·笔记·学习·mysql
老赵的博客12 小时前
c++面试之从虚函数表到Rtti一次性讲清楚
c++·qt
fanged13 小时前
Agent的Skills(TODO)
学习
是隼人13 小时前
buuctf-pwn picoctf_2018_shellcode(ret2shellcode)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门