前提:在OPENCV中只支持avi格式的视频流,而且大小不能超过2GB,并且不能添加音频。
Opencv-ref-man-2.x中 videowrite 构造函数:
C++: VideoWriter::VideoWriter(const string& filename, int fourcc, double fps, Size frameSize, boolisColor=true)
filname: 输出视频文件名;
fourcc : 压缩帧格式;
CV_FOURCC('P', 'I', 'M', '1') = MPEG-1 codec
CV_FOURCC('M', 'J', 'P', 'G') = motion-jpeg codecCV_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
fps : 创建视频流的帧频
framesize: Size 格式的帧大小。可以调用如Size(640,480) 方式创建一个Size对象;
isColor:可省略。0:grayFrame no 0: colorFrame
// 7/11 by JASON LI
程序一:
//从camera或者视频文件读取然后保存成指定的视频文件(opencv只支持按avi格式保存)。
#include <cv.h>
#include <iostream>
#include <highgui.h>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
string Videoname = "D:\\Pro\\VS_Pro\\Video2pic\\video_2_frame\\Sample.avi"; //绝对路径写法。
int main(int argc, const char** argv)
{
Mat curFrame;
// VideoCapture vc(Videoname); //读取指定的视频文件
VideoCapture vc;
// VideoWriter writer("E:\\jasonli.avi", CV_FOURCC('P', 'I', 'M', '1'), 50.0, Size(640, 480));
//测试时可能所选格式不一样生成视频不一定成功。原因是?
//打开视频文件或者camera,获取图片基本格式
// if (!vc.isOpened()) // open avi格式文件地址。
if (!vc.open(0))
{
cout << "无法打开视频设备" << endl;
return -1;
}
double dwidth = vc.get(CV_CAP_PROP_FRAME_WIDTH);
double dheight = vc.get(CV_CAP_PROP_FRAME_HEIGHT);
// double dfps = vc.get(CV_CAP_PROP_FPS);
cout << "Chanel is: " <<curFrame.channels() << " . ";
cout << "Video width is: " << dwidth << " . ";
cout << "Video height is: " << dheight << endl;
// cout << "Video fps is: " << dfps << endl;
//准备写入文件 // static_cast<int> 与 (int) 作用一样,前者用于c++,后者c语言,严谨
Size size(static_cast<int>(dwidth),static_cast<int>(dheight)); //根据图片格式,创建相应Size对象
VideoWriter writer("E:\\jasonli.avi", CV_FOURCC('P', 'I', 'M', '1'), 50.0, size);
if (!writer.isOpened()) //判断是否可进行写入
{
cout << "无法写入视频文件" << endl;
return -1;
}
while (true)
{
vc >> curFrame;
if (curFrame.empty())
break;
writer<<curFrame;
imshow("wfds", curFrame);
int c = waitKey(20);
if ((char)c == 'c') { break; }
}
waitKey(0);
return 0;
}
程序二:
// 从视频文件中读出图片。按图片方式保存
#include <cv.h>
#include <iostream>
#include <highgui.h>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
string Videoname = "D:\\Pro\\VS_Pro\\Video2pic\\video_2_frame\\Sample.avi";
int main(int argc, const char** argv)
{
Mat curFrame;
// VideoCapture vc(Videoname);
VideoCapture vc;
// VideoWriter writer("E:\\jasonli.avi", CV_FOURCC('P', 'I', 'M', '1'), 50.0, Size(640, 480));
//打开视频文件或者camera,获取图片基本格式
// if (!vc.isOpened()) // open avi格式文件地址。
if (!vc.open(0))
{
cout << "无法打开视频设备" << endl;
return -1;
}
double dwidth = vc.get(CV_CAP_PROP_FRAME_WIDTH);
double dheight = vc.get(CV_CAP_PROP_FRAME_HEIGHT);
// double dfps = vc.get(CV_CAP_PROP_FPS);
cout << "Video width is: " << dwidth << " . ";
cout << "Video height is: " << dheight << endl;
// cout << "Video fps is: " << dfps << endl;
//定义vector 变量,按照jpeg格式进行写入图片
vector<int> pra;
pra.push_back(CV_IMWRITE_JPEG_QUALITY);
pra.push_back(96); //用pushback方法将参数打入vector变量pra
unsigned int i = 0;
char ptr[30];
while (true)
{
vc >> curFrame;
if (curFrame.empty()) //no more Frame
break;
sprintf(ptr, "E:\\jasonli\\img_%d.jpg", i); // 利用sprintf 将整数保存成字符串,主要是为了生成指定格式的照片文件名
if (!imwrite(ptr, curFrame, pra))
{
cout << "存入失败!" << endl;
}
imshow("图片", curFrame);
int c = waitKey(20);
if ((char)c == 'c') { break; }
++i;
}
waitKey(0);
}
程序三:
// 从指定文件夹中读出图片,按照相应的帧速率显示。
#include <cv.h>
#include <iostream>
#include <highgui.h>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
string Videoname = "D:\\Pro\\VS_Pro\\Video2pic\\video_2_frame\\Sample.avi";
int main(int argc, const char** argv)
{
Mat curFrame;
unsigned int i = 0;
char ptr[30];
while (true)
{
sprintf(ptr, "E:\\jasonli\\img_%d.jpg", i); // 利用sprintf 将整数保存成字符串
curFrame = imread(ptr);
if (curFrame.empty()) //no more Frame
break;
imshow("图片", curFrame);
int c = waitKey(20); // 20 : 20ms --> fps: 50
if ((char)c == 'c') { break; }
++i;
}
// waitKey(0);
}
程序四:
//从指定文件夹中读出图片,按照相应的帧速率显示。并保存成相应的avi格式 文件。。 在这里有一个问题就是读出 一帧的图片信息后变成Mat格式了,如何读出原图 长 宽?? 在手册中 Mat 定义中未找到相应的成员来指定,所以这里直接使用已知数据代入:640*480;
#include <cv.h>
#include <iostream>
#include <highgui.h>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main(int argc, const char** argv)
{
Mat curFrame;
unsigned int i = 0;
char ptr[30];
// curFrame = imread("E:\\jasonli\\img_0.jpg");
// double dwidth = curFrame.col; //这样读Mat的不行。 Mat无此定义的成员
// double dheight = curFrame.row;
// double dfps = vc.get(CV_CAP_PROP_FPS);
// cout << "Video width is: " << dwidth << " . ";
// cout << "Video height is: " << dheight << endl;
// Size size(static_cast<int>(dwidth), static_cast<int>(dheight));
VideoWriter writer("E:\\jasonli.avi", CV_FOURCC('P', 'I', 'M', '1'), 20.0, Size(640,480));
if (!writer.isOpened())
{
cout << "无法写入视频文件" << endl;
return -1;
}
while (true)
{
sprintf(ptr, "E:\\jasonli\\img_%d.jpg", i); // 利用sprintf 将整数保存成字符串
curFrame = imread(ptr);
if (curFrame.empty()) //no more Frame
break;
imshow("图片", curFrame);
writer << curFrame;
int c = waitKey(20); // 20 : 20ms --> fps: 50
if ((char)c == 'c') { break; }
++i;
}
}
对于上面的两个背景标出的问题,希望大家
指点。