qt进行视频二值化 未成功 待改进

dq0618 / 2023-08-27 / 原文

QT+opencv 使用videocapture采集视频进行二值化输出_哔哩哔哩_bilibili

 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QTimer>
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QTimer *m_timer;
    VideoCapture *m_videoCapture;
private slots:
    void openVideo();
    void setMatLabel(QLabel &_label,Mat &_frame);
    void actionTriggered();
    void handleFrame();
    QImage cvMat2QImage(const Mat& mat);
    QImage QImage2cvMat(QImage image);

};

#endif // MAINWINDOW_H







#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTimer>
#include <QFileDialog>
#include <QStandardPaths>
#include <QString>
#include <QMessageBox>
#include <QDebug>

#pragma execution_character_set("utf-8")

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_timer=new QTimer(this);
    m_timer->setInterval(30);

    connect(m_timer,SIGNAL(timeout()),this,SLOT(handleframe()));


}

MainWindow::~MainWindow()
{
    if(m_videoCapture!=nullptr)
        m_videoCapture->release();
    if(m_timer->isActive())
        m_timer->stop();
    delete ui;
}
void MainWindow::actionTriggered()
{
    QString fileName=QFileDialog::getOpenFileName(this,tr("打开文件"),QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).value(0,QDir::homePath()),tr("*.mp4 *.mkv"));
    if(!fileName.isEmpty())
        openVideo(fileName);
}
void MainWindow::openVideo()
{
    if(m_timer->isActive())
        m_timer->stop();
    if(m_videoCapture!=nullptr)
        m_videoCapture->release();

    m_videoCapture=new VideoCapture;
    m_videoCapture->open(fileName.toStdString());
    if(!m_videoCapture->isOpened())
    {
        QMessageBox::warning(this,"警告","不能打开视频");
        return;
    }

    m_timer->start();

}



void MainWindow::setMatLabel(QLabel &_label,Mat &_frame)
{
    QImage labelImage=cvMat2QImage(_frame);
    QPixmap pixmap=QPixmap::fromImage(labelImage);
    _label.setPixmap(pixmap.scaled(_label.width(),_label.height()));

}



void MainWindow::handleFrame()
{
    if(!m_videoCapture->read(m_frame))
    {
        QMessageBox::warning(this,"警告","视频文件不能读取");
        m_videoCapture->release();
        m_timer->stop();

        return;
    }

    Mat tmp;
    cvtColor(m_frame,tpm,COLOR_BGR2RGB);
    threshold(tmp,tmp,ui->Slider1->value(),ui->Slider2->value(),THRESH_BINARY);


    setMatLabel(*ui->orgLabel,m_frame);
    setMatLabel(*ui->handleLabel,tmp);
}

QImage MainWindow::cvMat2QImage(const Mat& mat)
{
    if(mat.type()==CV_8UC1)
    {
        QImage image(mat.cols, mat.rows, QInage::Format_Indexed8);
        image.setColorCount(256);
        for (int i=0;i<256;i++)
        {
            image.setColor(i,qRgb(i,i,i));
        }

        uchar *pSrc=mat.data;
        for(int row=0; row <mat.rows; row++)
        {
            uchar *pDest = image.scanLine(row);
            memcpy(pDest, pSrc, mat.cols);
            pSrc +=mat.step;
        }

        return image;
    }

        else if(mat.type()==CV_8UC4)
    {
        const uchar *pSrc=(const uchar*)mat.data;
        QImage image(pSrc,mat.cols,mat.rows,mat.step,QImage::Format_ARGB32);
        return image.copy();
    }
    else
    {
        return QImage();
    }

}

QImage MainWindow::QImage2cvMat(QImage image)
{
    Mat mat;
    switch(image.format())
    {
    case QImage::Format_ARGB32:
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32_Premultiplied:
        mat=Mat(image.height(),image.width(),CV_8UC4,(void*)image.constBits(),image.bytesPerLine());
        break;
    case QImage::Format_RGB888:
        mat=Mat(image.height(),image.width(),CV_8UC3,(void*)image.constBits(),image.bytesPerLine());
        cv::cvtColor(mat,mat,CV_BGR2RGB);
        break;
    case QImage::Format_Indexed8:
        mat=Mat(image.height(),image.width(),CV_8UC1,(void*)image.constBits(),image.bytesPerLine());
        break;
    default:
        break;
    }
    return mat;
}