当前位置: 首页 > 工具软件 > VideoCapture > 使用案例 >

opencv之VideoCapture与VideoWriter笔记

壤驷彦
2023-12-01

opencv版本:opencv3.4.1 

1. VideoCapture类 

 作用: 捕获视频文件,图像序列或摄像头;

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;
}

 2. VideoWriter类

 作用: 写视频文件或图像序列;

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');

参考: python错误:OpenCV: FFMPEG: tag 0xffffffff/’����‘’is not found (format ’mp4 / MP4 (MPEG-4 Part 14)’)’-python黑洞网

 类似资料: