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