C++ opencv之视频读写(VideoCapture,VideoWriter)的实现

 更新时间:2026年03月04日 09:48:55   作者:阿超没有蛀牙  
本文主要介绍了OpenCV中的VideoCapture和VideoWriter函数,用于视频的读取和保存,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

这篇博客主要讲解OpenCV中视频读写。
主要涉及到两个API函数:
VideoCapture
VideoWriter

一、函数简介

1.1 VideoCapture

视频文件读取、摄像头读取、视频流读取
VideoCapture既支持从视频文件(.avi , .mpg格式)读取,也支持直接从摄像机(比如电脑自带摄像头)中读取。要想获取视频需要先创建一个VideoCapture对象,VideoCapture对象的

创建方式有以下三种:

【方式一】是从文件(.MPG或.AVI格式)中读取视频,**对象创建以后,OpenCV将会打开文件并做好准备读取它,如果打开成功,我们将可以开始读取视频的帧,并且cv::VideoCapture的成员函数isOpened()将会返回true(建议在打开视频或摄像头时都使用该成员函数判断是否打开成功)。

方法:  cv::VideoCapture capture(const string& filename);  // 从视频文件读取 
例程:  cv::VideoCapture capture("C:/Users/DADA/DATA/gogo.avi");  // 从视频文件读取

【方式二】是从摄像机中读取视频,**这种情况下,我们会给出一个标识符,用于表示我们想要访问的摄像机,及其与操作系统的握手方式。对于摄像机而言,这个标志符就是一个标志数字——**如果只有1个摄像机,那么就是0,如果系统中有多个摄像机,那么只要将其向上增加即可。**标识符另外一部分是摄像机域(camera domain),用于表示摄像机的类型,这个域值可以是下面任一预定义常量。

cv::VideoCapture capture(int device );  //视频捕捉设备 id ---笔记本电脑的用0表示 

【方式三】先创建一个捕获对象,然后通过成员函数open()来设定打开的信息,操作如下。

cv::VideoCapture VideoCapture;  这里的第二个VideoCapture是一个对象名
VideoCapture.open( "C:/Users/DADA/DATA/gogo.avi" );  

将视频帧读取到cv::Mat矩阵中,有两种方式:一种是read()操作;另一种是 “>>”操作。

cv::Mat frame;  
cap.read(frame); //读取方式一  
cap >> frame; //读取方式二  

1.2 VideoWriter

功能:视频写出、文件保存
我们先来看一下opencv3中的这个函数原型:

VideoWriter  video_writer;
video_writer.open(const string& filename, int fourcc, double fps,Size frameSize, bool isColor=true);

参数意义:

  • filename:保存文件名称及路径;
  • fourcc:表示压缩帧的codec,一般用CV_FOURCC(‘M’,‘J’,‘P’,‘G’) = motion-jpeg codec;
  • fps:表示帧率,可用video_writer.get(CV_CAP_PROP_FPS);
  • frameSize:保存的视频大小;

而opencv4中与opencv3还是有一定区别的,这个再一会附代码的时候我会附两个不同版本的。

二、代码示例

附opencv4及以上所用代码:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	// 打开摄像头
	// VideoCapture capture(0); 

	// 打开文件
	VideoCapture capture;
	capture.open("C:/Users/Dell/Desktop/opencv-master/samples/data/vtest.avi");
	if (!capture.isOpened()) {
		printf("could not read this video file...\n");
		return -1;
	}
	Size S = Size((int)capture.get(CAP_PROP_FRAME_WIDTH),
		(int)capture.get(CAP_PROP_FRAME_HEIGHT));
	int fps = capture.get(CAP_PROP_FPS);
	printf("current fps : %d \n", fps);
	VideoWriter writer("C:/Users/Dell/Desktop/picture/test.mp4", CAP_OPENCV_MJPEG, fps, S, true);

	Mat frame;
	namedWindow("camera-demo", WINDOW_AUTOSIZE);
	while (capture.read(frame)) {
		imshow("camera-demo", frame);
		writer.write(frame);
		char c = waitKey(50);
		if (c == 27) {
			break;
		}
	}
	capture.release();
	writer.release();
	waitKey(0);
	return 0;
}

opencv3代码:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	// 打开摄像头
	// VideoCapture capture(0); 

	// 打开文件
	VideoCapture capture;
	capture.open("D:/vcprojects/images/768x576.avi");
	if (!capture.isOpened()) {
		printf("could not read this video file...\n");
		return -1;
	}
	Size S = Size((int)capture.get(CV_CAP_PROP_FRAME_WIDTH),
		(int)capture.get(CV_CAP_PROP_FRAME_HEIGHT));
	int fps = capture.get(CV_CAP_PROP_FPS);
	printf("current fps : %d \n", fps);
	VideoWriter writer("D:/test.mp4", CV_FOURCC('D', 'I', 'V', 'X'), fps, S, true);

	Mat frame;
	namedWindow("camera-demo", CV_WINDOW_AUTOSIZE);
	while (capture.read(frame)) {
		imshow("camera-demo", frame);
		writer.write(frame);
		char c = waitKey(50);
		if (c == 27) {
			break;
		}
	}
	capture.release();
	writer.release();
	waitKey(0);
	return 0;
}

其实不是代码有什么区别 只是一些标识符在不同opencv版本中的写法不一样。

三、结果展示

上边为输出的fps(每秒传输的帧数)
下边为我们读取的视频

以及我们文件夹中保存的视频:

到此这篇关于C++ opencv之视频读写(VideoCapture,VideoWriter)的实现的文章就介绍到这了,更多相关opencv 视频读写内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • C语言实现汉诺塔(图文详解)

    C语言实现汉诺塔(图文详解)

    个人觉得汉诺塔这个递归算法比电子老鼠的难了一些,不过一旦理解了也还是可以的,其实网上也有很多代码,可以直接参考。记得大一开始时就做过汉诺塔的习题,但是那时代码写得很长很长,也是不理解递归的结果。今天重新来实现一下
    2021-08-08
  • C语言格式输出方式

    C语言格式输出方式

    本文介绍了C语言中printf函数的格式输出,包括整数和浮点数的格式化输出方法,以及如何通过指定宽度和小数位数来控制输出格式
    2025-01-01
  • c++中将二维数组元素变换为逆向存放的实现代码

    c++中将二维数组元素变换为逆向存放的实现代码

    编程将一个二维数组元素变换为逆向存放,即按元素在内存中的物理排列位置,第一个元素变成倒数第一个元素,第二个元素变成倒数第二个元素,依此类推
    2020-11-11
  • 解决在Mac下直接解压C++静态库出现的问题

    解决在Mac下直接解压C++静态库出现的问题

    最近在研究C++的各种编译构建过程,学习了一下cmake,gyp/ninja这些自动化构建工具后,想着自己试下用纯命令行跑一遍编译流程。在试图把C++静态库编译为动态库的过程中遇到了棘手的问题,找了好久后发现是跟Mac平台相关的,这里记录一下,望对遇到类似问题的童鞋有帮助。
    2016-12-12
  • C语言strlen和sizeof在数组中的使用详解

    C语言strlen和sizeof在数组中的使用详解

    对于 strlen 和 sizeof,相信不少程序员会混淆其功能。虽然从表面上看它们都可以求字符串的长度,但二者却存在着许多不同之处及本质区别
    2021-10-10
  • C++ 详解数据结构中的搜索二叉树

    C++ 详解数据结构中的搜索二叉树

    搜索二叉树是一种具有良好排序和查找性能的二叉树数据结构,包括多种操作,本篇只介绍插入,排序(遍历),和删除操作,重点是删除操作比较复杂
    2022-04-04
  • MFC自绘Button按钮分析和实现

    MFC自绘Button按钮分析和实现

    这篇文章主要为大家详细介绍了MFC自绘Button按钮分析和实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • C++中inet_pton、inet_ntop函数的用法

    C++中inet_pton、inet_ntop函数的用法

    这篇文章主要介绍了C++中inet_pton、inet_ntop函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • C语言每日练习之二叉堆

    C语言每日练习之二叉堆

    这篇文章主要为大家介绍了C语言二叉堆,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • C++ vector容器实现贪吃蛇小游戏

    C++ vector容器实现贪吃蛇小游戏

    这篇文章主要为大家详细介绍了C++ vector容器实现贪吃蛇小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02

最新评论