cv::VideoWriter::VideoWriter(const String& filename,
int fourcc,
double fps,
Size frameSize,
bool isColor=true
)
例:
cap.open("dev/video11", CAP_V4L2);
//write.open("test.mp4", VideoWriter::fourcc('m', 'p', '4', 'v'), 30.0, Size(640, 480), true);
write.open("test.avi", VideoWriter::fourcc('M', 'P', '4', '2'), 30.0, Size(640, 480), true);
//cv.VideoWriter_fourcc('X', '2', '6', '4') # H.264 codec
关闭摄像头:
cap.release();
关闭录制:
write.release();
参数:
第一个参数:输出视频文件名,可以指定输出路径
第二个参数:用于压缩帧的编码器的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
H265编码
fourcc = cv2.VideoWriter_fourcc(‘H’, ‘E’, ‘V’, ‘C’)
cv2.VideoWriter_fourcc(‘I’,‘4’,‘2’,‘0’)
这个选项是一个未压缩的YUV编码,4:2:0色度子采样。这种编码广泛兼容,但会产生大文件。文件扩展名应为.avi。
cv2.VideoWriter_fourcc(‘P’,‘I’,‘M’,‘1’)
此选项为MPEG-1。文件扩展名应为.avi。
cv2.VideoWriter_fourcc(‘X’,‘V’,‘I’,‘D’)
此选项是一个相对较旧的MPEG-4编码。如果要限制结果视频的大小,这是一个很好的选择。文件扩展名应为.avi。
cv2.VideoWriter_fourcc(‘m’, ‘p’, ‘4’, ‘v’)
此选项是另一个相对较旧的MPEG-4编码。如果要限制结果视频的大小,这是一个很好的选择。文件扩展名应为.m4v。
cv2.VideoWriter_fourcc(‘X’,‘2’,‘6’,‘4’):
这个选项是一种比较新的MPEG-4编码方式。如果你想限制结果视频的大小,这可能是最好的选择。文件扩展名应为.mp4。
cv2.VideoWriter_fourcc(‘T’,‘H’,‘E’,‘O’)
这个选项是Ogg Vorbis。文件扩展名应为.ogv。
cv2.VideoWriter_fourcc(‘F’,‘L’,‘V’,‘1’)
此选项为Flash视频。文件扩展名应为.flv。
第三个参数:创建的视频流的帧率
第四个参数:每帧视频的大小
第五个参数:如果它不为零,则编码器将编码彩色帧,否则为灰度帧(仅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倍。
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();
}
示例:
QString qstr;
QString time = QTime::currentTime().toString("hh:mm:ss");
QString date = QDate::currentDate().toString("yyyy/MM/dd");
qstr = date + " " + time;
String str = qstr.toStdString();
cv::putText(frame, str, cv::Point(10, 25), cv::FONT_HERSHEY_SCRIPT_COMPLEX, 1.0, cv::Scalar(0, 255, 255), 2, 8, 0);
或
putText(frame, str, Point(10, 20), FONT_HERSHEY_SCRIPT_COMPLEX, 0.5, (0, 255, 255), 1, LINE_AA);
putText();
第三参数Point(10, 30):位置坐标
第五参数:字体大小
第六参数:字体颜色
第七参数:字体粗细