opencv版本:opencv3.4.1
作用: 捕获视频文件,图像序列或摄像头;
class VideoCapture
{
public:
//构造
VideoCapture();
VideoCapture(const String& filename);
//apiPreference参数取值:cv::CAP_FFMPEG or cv::CAP_IMAGES or cv::CAP_DSHOW等
VideoCapture(const String& filename, int apiPreference);
VideoCapture(int index);
//析构
virtual ~VideoCapture();
//打开视频文件或捕获设备或IP视频流以进行视频捕获
virtual bool open(const String& filename);
//打开摄像机进行视频捕获
virtual bool open(int index);
bool open(int cameraNum, int apiPreference);
virtual bool open(const String& filename, int apiPreference);
//若视频捕获已经被初始化(打开),返回true;
virtual bool isOpened() const;
//关闭视频文件或捕获设备。
virtual void release();
//从视频文件或捕获设备中捕获下一帧。
virtual bool grab();
/*解码并返回抓取的视频帧。
image为捕获返回的视频帧,没有帧被捕获image为空;
成功不会返回true;
*/
virtual bool retrieve(OutputArray image, int flag = 0);
//抓取、解码并返回下一个视频帧。
virtual bool read(OutputArray image);
//设置VideoCapture中的属性。
virtual bool set(int propId, double value);
//返回指定的VideoCapture属性
virtual double get(int propId) const;
...
};
测试代码:
int main()
{
VideoCapture capture;
capture.open("./video/xxx.AVI");
if(!capture.isOpened()){
std::cout << "failed to open video!" << std::endl;
return -1;
}
int totalFrame = capture.get(CV_CAP_PROP_FRAME_COUNT);
int imageW = capture.get(CV_CAP_PROP_FRAME_WIDTH);
int imageH = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
double frameRate = capture.get(CV_CAP_PROP_FPS);
std::cout << "----open ok------" << totalFrame << " w=" << imageW << " h=" << imageH << " frameRate="<< frameRate << std::endl;
//----open ok------1276 w=640 h=480 frameRate=24
cv::Mat frameImg ;
long nCount = 1;
while(true)
{
capture >> frameImg ;
if(!frameImg.empty()){
imwrite("./video/inc835.jpg", frameImg);
break;
}
}
capture.release();
return 0;
}
作用: 写视频文件或图像序列;
class VideoWriter
{
public:
//构造
VideoWriter();
/*filename:输出视频文件的文件名
fourcc:用于压缩帧的编解码器的4个字符代码。
fps:帧率
frameSize:帧宽高大小;
isColor:非0,编码器将期望并编码彩色帧;否则,灰度帧;
*/
VideoWriter(const String& filename, int fourcc, double fps,
Size frameSize, bool isColor = true);
//apiPreference参数: cv::CAP_FFMPEG or cv::CAP_GSTREAMER等
VideoWriter(const String& filename, int apiPreference, int fourcc, double fps,
Size frameSize, bool isColor = true);
//析构
virtual ~VideoWriter();
//打开文件
virtual bool open(const String& filename, int fourcc, double fps,
Size frameSize, bool isColor = true);
bool open(const String& filename, int apiPreference, int fourcc, double fps,
Size frameSize, bool isColor = true);
//若视频输出已经被成功初始化(打开),返回true;
virtual bool isOpened() const;
//关闭视频输出
virtual void release();
//写下一帧
virtual void write(const Mat& image);
virtual bool set(int propId, double value);
virtual double get(int propId) const;
//将4个字符连接到一个fourcc代码
static int fourcc(char c1, char c2, char c3, char c4);
protected:
Ptr<CvVideoWriter> writer;
Ptr<IVideoWriter> iwriter;
static Ptr<IVideoWriter> create(const String& filename, int fourcc, double fps,
Size frameSize, bool isColor = true);
};
测试代码:
int main()
{
VideoCapture inputVideo("./video/INC835.AVI");
if(!inputVideo.isOpened()){
std::cout << "----VideoCapture open failed----" << std::endl;
return -1;
}
int imageW = inputVideo.get(CV_CAP_PROP_FRAME_WIDTH);
int imageH = inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT);
double fps = inputVideo.get(CV_CAP_PROP_FPS);
VideoWriter outputVideo;
string fileName = "./video/INC835_Write.avi";
outputVideo.open(fileName, VideoWriter::fourcc('F','M','P','4'),25.0,Size(imageW,imageH),true);
if(!outputVideo.isOpened()){
std::cout << "----VideoWriter open failed----" << std::endl;
inputVideo.release();
return -1;
}
cv::Mat frameImg;
vector<cv::Mat> rgb;
cv::Mat resultImg;
while(1)
{
inputVideo >> frameImg;
if(!frameImg.empty()){
cv::split(frameImg, rgb); //分离出三通道rgb;
for(int i =0; i < 3; i++){
#if 1
if(i != 0){
//提取B通道分量
rgb[i] = cv::Mat::zeros(Size(imageW,imageH), rgb[0].type());
}
#endif
//通道合并
cv::merge(rgb, resultImg);
}
outputVideo << resultImg;
}else{
break; //读取完
}
}
inputVideo.release();
outputVideo.release();
return 0;
}
outputVideo.open(fileName, -1,25.0,Size(imageW,imageH),false);
错误: 调用outputVideo.open出现OpenCV: FFMPEG: tag 0xffffffff/'����' is not found (format 'avi / AVI (Audio Video Interleaved)')'
处理: 将参数2改为使用fourcc生成;具体字段需要根据编码确定;
如: outputVideo.open(fileName, VideoWriter::fourcc('M','J','P','G'),25.0,Size(imageW,imageH),false);
或fourcc('F','M','P','4');