Qt+OpenCV 读取摄像头视频并保存

1、函数:

函数原型:
Qt+OpenCV 读取摄像头视频并保存_第1张图片
参数:

。第一个参数:输出视频文件名,可以指定输出路径
。第二个参数:用于压缩帧的编码器的4个字符的代码,如:
CV_FOURCC(‘P’,‘I’,‘M’,‘1’) = MPEG-1 codec
CV_FOURCC(‘M’,‘J’,‘P’,‘G’) = motion-jpeg codec
CV_FOURCC(‘M’, ‘P’, ‘4’, ‘2’) = MPEG-4.2 codec
CV_FOURCC(‘D’, ‘I’, ‘V’, ‘3’) = MPEG-4.3 codec
CV_FOURCC(‘D’, ‘I’, ‘V’, ‘X’) = MPEG-4 codec
CV_FOURCC(‘U’, ‘2’, ‘6’, ‘3’) = H263 codec
CV_FOURCC(‘I’, ‘2’, ‘6’, ‘3’) = H263I codec
CV_FOURCC(‘F’, ‘L’, ‘V’, ‘1’) = FLV1 codec
。第三个参数:创建的视频流的帧率
。第四个参数:每帧视频的大小
。第五个参数:如果它不为零,则编码器将编码彩色帧,否则为灰度帧(仅Windows当前支持该标志)

Tips:

—》若fourcc=-1,则会从系统中弹出编解码器选择对话框
—》若要保存图像序列,则应使用适当的文件名(例如img_%02d.jpg)和fourcc=0 或 fps=0。若要保存原始帧,应使用未压缩的图像格式(例如img_%02d.BMP)。
—》大多数编解码器是有损的。如果想要无损视频文件,则需要使用无损编解码器(例如FFMPEG FFV1,Huffman HFYU,Lagarith LAGS等)。
—》如果启用了FFMPEG,则可以使用codec=0; fps=0;来创建未压缩(原始)的视频文件。
—》生成文件占用空间最小的编码方式是MPEG-4.2 codec。在VideoWriter类的构造函数参数为CV_FOURCC(‘M’, ‘P’, ‘4’, ‘2’) 。最大的是MPEG-1 codec,对应在VideoWriter类的构造函数参数为CV_FOURCC(‘P’,‘I’,‘M’,‘1’) ,所占磁盘空间是前者的5.7倍。

2、代码:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 

#include "opencv2/opencv.hpp"

using namespace cv;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    QImage mat2QImage(cv::Mat cvImg);

private slots:
    void readFrame();

private:
    Ui::MainWindow *ui;

    QTimer *time;

    Mat frame;

    VideoCapture cap;
    VideoWriter write;

    int counter;  //记录帧数
};

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

    time = new QTimer(this);
    time->start(10);

    connect(time, SIGNAL(timeout()), this, SLOT(readFrame()));

    counter = 0;

    cap.open(0);
    write.open("test.avi", VideoWriter::fourcc('M', 'P', '4', '2'), 30.0, Size(640, 480), true); //保存在当前目录,名为test的AVI视频
}

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

//读取摄像头视频并保存
void MainWindow::readFrame()
{
   cap >> frame;
   counter++;
   if(frame.empty())
   {
        qDebug()<<"frame is empty";
        cap.release();
   }

   if (counter <= 100)  //只保存100帧
   {
       qDebug() << "counter = " << counter;
       write.write(frame);  //保存视频帧
   }
   ui->label->setPixmap(QPixmap::fromImage(mat2QImage(frame)));
}

//Mat to QImage
QImage MainWindow::mat2QImage(cv::Mat cvImg)
{
    QImage qImg;

    if (cvImg.channels() == 3)                             //3 channels color image
    {
        cv::cvtColor(cvImg, cvImg, CV_BGR2RGB);
        qImg = QImage((const unsigned char*)(cvImg.data),
                      cvImg.cols, cvImg.rows,
                      cvImg.cols*cvImg.channels(),
                      QImage::Format_RGB888);
    }

    else if (cvImg.channels() == 1)                    //grayscale image
    {
        qImg = QImage((const unsigned char*)(cvImg.data),
                      cvImg.cols, cvImg.rows,
                      cvImg.cols*cvImg.channels(),
                      QImage::Format_Indexed8);
    }

    else
    {
        qImg = QImage((const unsigned char*)(cvImg.data),
                      cvImg.cols, cvImg.rows,
                      cvImg.cols*cvImg.channels(),
                      QImage::Format_RGB888);
    }
    return qImg;
}

main.c

#include "mainwindow.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

3、参考:

1、https://blog.csdn.net/qq_42189368/article/details/80663174

2、https://docs.opencv.org/3.3.0/dd/d9e/classcv_1_1VideoWriter.html#ad59c61d8881ba2b2da22cff5487465b5

你可能感兴趣的:(Qt,OpenCV)