在许多应用的需求中,希望将输入,或捕获图像记录到输出视频流中,并保存成一个完整的视频,OpenCV提供了一种简单的方法。正如【opencv四】利用opencv读取显示视频和【opencv七】利用opencv调用电脑摄像头中用到的可以从视频流中捕获到一个一个的帧,并将这些帧逐一显示。我们也可以创建一个写入功能,使得这一个个的帧能够逐一被放入到视频中。在opencv中cv::VideoWriter类就可以实现这个功能。
下面程序段的功能为:调整输入视频的播放速度,并将新速度的视频保存为.avi文件。主要操纵的就是一个参数:帧率(fps)。
#include "opencv2/opencv.hpp"
#include
using namespace cv;
int main()
{
String out_path = "H:\\vs2017\\opencv_learning\\ConsoleApplication1\\out1.avi";
namedWindow("Example6", WINDOW_AUTOSIZE);
namedWindow("Log_Polar", WINDOW_AUTOSIZE);
VideoCapture cap;
cap.open("H:\\vs2017\\opencv_learning\\ConsoleApplication1\\video1.mp4");
double fps = cap.get(CAP_PROP_FPS)*2;
Size size((int)cap.get(CAP_PROP_FRAME_WIDTH), (int)cap.get(CAP_PROP_FRAME_HEIGHT));
VideoWriter writer;
writer.open(out_path, CV_FOURCC('M', 'J', 'P', 'G'), fps, size, isColor=true);
Mat gry_frame, bgr_frame,cny_frame;
while (1)
{
cap >> bgr_frame;
if (bgr_frame.empty()) break;
imshow("Example6",bgr_frame);
imshow("Log_Polar", bgr_frame);
writer << bgr_frame;
//按Esc键退出while
char c = waitKey(10);
if (c == 27) break;
}
cap.release();
//getchar();
return 0;
}
上述代码中主要的操作就是对cv::VideoWriter这个类实例化出来的writer对象的操作。
writer.open(out_path, CV_FOURCC('M', 'J', 'P', 'G'), fps, size);
该函数有以下几个参数:
四个字符用来表示压缩帧的codec 例如:
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
NOTE:生成文件占用空间最小的编码方式是MPEG-4.2 codec。在VideoWriter类的构造函数参数为CV_FOURCC(‘M’, ‘P’, ‘4’, ‘2’) 。
最大的是MPEG-1 codec,对应在VideoWriter类的构造函数参数为CV_FOURCC(‘P’,‘I’,‘M’,‘1’) ,所占磁盘空间是前者的5.7倍。所以如果需要24小时全天候录制监控,可以优先使用MPEG-4.2的编解码方式。
若编码器代号为 -1,则运行时会弹出一个编码器选择框.
如下面两幅图所示,上方的为输入视频,下方为通过处理后的avi视频。可以看到相同的视频,下方只有5s钟的时间,原因是进行了倍速处理。倍速的速度可以自行调节。