• opencv视频文件的读取,处理与保存


    文章目录

    opencv视频文件的读取,处理与保存

    一、视频文件的读取:
    1、cv::VideoCapture是OpenCV库中用于处理视频输入的类,它提供了一种简单的方法来从摄像头,视频文件、或图像序列中读取帧;
    (1)打开摄像头:
    cv::VideoCapture capture(int index)
    
    参数解释:
    index:打开指定编号的摄像头,编号0表示默认摄像头,如果你的计算机连接了多个摄像头,你可以使用不同的编号来选择不同的摄像头;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    (2)打开视频文件:
    cv::VideoCapture capture(const std::string& filename)
    
    参数解释:
    filename:打开指定的视频文件,你需要提供视频文件的路径和名称作为参数;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    (3)打开网络摄像头:
    cv::VideoCapture capture(const std::string& apiKey, const std::string& deviceId)
    
    参数解释:
    用于打开网络摄像头,需要提供相应的API密钥和设备ID;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    (4)打开图像序列:
    cv::VideoCapture capture(const std::string& pattern, int api)
    
    参数解释:
    用于打开图像序列,需要提供文件名模式(通配符)和相应的API;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2、cv::VideoCapture类的常用方法:
    (1)capture.get():用于获取视频的属性,比如帧数、帧率等:
    capture.get(int propId)
    
    参数解释:
    propId:是一个整数参数,用于指定你想获取的属性类型(
        	cv::CAP_PROP_FRAME_COUNT:获取视频的帧数;
        	cv::CAP_PROP_FPS:获取视频的帧率(每秒帧数);
    	cv::CAP_PROP_FRAME_WIDTH:视频帧的宽度;
    	cv::CAP_PROP_FRAME_HEIGHT:视频帧的高度;
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例:

    #include 
    #include 
    #include 
    
    using namespace cv;
    using namespace std;
    
    int main() {
    
    	// 初始化一个cv::VideoCapture对象,打开视频文件
    	VideoCapture capture("C:\\cpp\\image\\cayenne.mp4");
    	if (!capture.isOpened()) {
    		std::cerr << "Error: 无法打开视频文件." << std::endl;
    		return -1;
    	}
    	// 调用cv::VideoCapture类的get()方法,获取视频宽度,高度,帧数,帧率
    	int frameWidth = capture.get(cv::CAP_PROP_FRAME_WIDTH);
    	int frameHeight = capture.get(cv::CAP_PROP_FRAME_HEIGHT);
    	int frameCount = capture.get(cv::CAP_PROP_FRAME_COUNT);
    	double fps = capture.get(cv::CAP_PROP_FPS);
    
    	std::cout << "frame width:" << frameWidth << std::endl;
    	std::cout << "frame height:" << frameHeight << std::endl;
    	std::cout << "Number of Frames:" << frameCount << std::endl;
    	std::cout << "FPS:" << fps << std::endl;
    
    	capture.release(); // 释放VideoCapture对象
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    (2)capture.set(int propId, double value):用于设置视频的属性,比如设置视频的帧率、帧大小等属性;
    capture.set(int propId, double value)
    
    参数解释:
    propId:指定了你想设置的属性类型;
    value:要设置的值;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    示例:

    cv::VideoCapture capture(0); // 打开默认摄像头
    
    if (!capture.isOpened()) {
        std::cerr << "Error: 无法打开摄像头." << std::endl;
        return -1;
    }
    
    capture.set(cv::CAP_PROP_FRAME_WIDTH, 1280);
    capture.set(cv::CAP_PROP_FRAME_HEIGHT, 720);
    capture.set(cv::CAP_PROP_FPS, 30);
    
    capture.release(); // 释放VideoCapture对象
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    (3)capture.read(cv::Mat& frame):用于读取视频的一帧,将其存储在 cv::Mat 对象中;

    示例:

    cv::VideoCapture capture("video_file.mp4");
    
    if (!capture.isOpened()) {
        std::cerr << "Error: 无法打开视频文件." << std::endl;
        return -1;
    }
    
    cv::Mat frame;
    capture.read(frame);
    
    // 在这里可以对 frame 进行处理
    
    capture.release(); // 释放VideoCapture对象
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    (4)capture.release():用于释放 VideoCapture 对象所占用的资源,一般在你已经完成了对视频流的操作后调用它;
    二、对视频帧进行处理:

    循环遍历视频的每一帧,可以在循环内部对每一帧进行处理在这里,我注释掉了处理部分,你可以根据需要添加各种图像处理操作,比如滤波、边缘检测等;

    代码示例:

    #include 
    #include 
    #include 
    
    using namespace cv;
    using namespace std;
    
    int main() {
    
    	// 打开视频文件
    	VideoCapture capture("C:\\cpp\\image\\cayenne.mp4");
    
    	// 检查视频是否成功打开
    	if (!capture.isOpened()) {
    		std::cerr << "Error: 无法打开视频文件." << std::endl;
    		return -1;
    	}
    
    	// 获取视频的帧数和帧率
    	int frameCount = capture.get(cv::CAP_PROP_FRAME_COUNT);
    	double fps = capture.get(cv::CAP_PROP_FPS);
    
    	// 创建一个VideoWriter对象来保存处理后的视频
    	cv::VideoWriter outVideo("outVideo.mp4", capture.get(CAP_PROP_FOURCC), fps, cv::Size(capture.get(cv::CAP_PROP_FRAME_WIDTH), capture.get(cv::CAP_PROP_FRAME_HEIGHT)));
    
    	// 循环处理视频的每一帧
    	for (int i = 0; i < frameCount; ++i) {
    		cv::Mat frame;
    		capture >> frame; // 读取一帧
    
    		if (frame.empty()) {
    			break;
    		}
    
    		// 在这里可以对frame进行处理,比如进行滤波、边缘检测等
    		// 例如:cv::cvtColor(frame, frame, cv::COLOR_BGR2GRAY);
    
    		// 将处理后的帧写入输出视频文件
    		outVideo << frame;
    	}
    
    	// 释放VideoCapture和VideoWriter对象
    	capture.release();
    	outVideo.release();
    
    	std::cout << "视频处理完成." << std::endl;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    三、保存处理后的视频:
    1、cv::VideoWriter 是opencv中用于将图像帧序列保存为视频文件的类,它可以将处理过的帧写入一个视频文件,也可以将视频流输出到摄像头或网络;
    (1)创建一个 cv::VideoWriter 对象:

    函数原型:

    cv::VideoWriter writer(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true)
    
    参数解释:
    filename:要保存的视频文件名或者设备地址;
    fourcc:FourCC编码,指定视频编解码器的类型(
    	cv::VideoWriter::fourcc('X','V','I','D'):Xvid编解码器;
    	cv::VideoWriter::fourcc('M','J','P','G'):MJPEG编解码器;
    	cv::VideoWriter::fourcc('M','P','4','V'):MPEG-4编解码器;
    	cv::VideoWriter::fourcc('H','2','6','4'):H.264编解码器;
    );
    fps:帧率,即每秒显示的帧数;
    frameSize:帧的大小,可以通过cv::Size类指定;
    isColor:指定保存的视频是否为彩色,默认为true
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2、cv::VideoWriter类的常用方法:
    (1)cv::VideoWriter::open():用于打开一个视频文件或设备以便写入视频帧;
    cv::VideoWriter::open(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true)
    
    参数解释:参数和构造函数类似;
    filename:要保存的视频文件名或者设备地址;
    fourcc:FourCC编码,指定视频编解码器的类型(
    	cv::VideoWriter::fourcc('X','V','I','D'):Xvid编解码器;
    	cv::VideoWriter::fourcc('M','J','P','G'):MJPEG编解码器;
    	cv::VideoWriter::fourcc('M','P','4','V'):MPEG-4编解码器;
    	cv::VideoWriter::fourcc('H','2','6','4'):H.264编解码器;
    );
    fps:帧率,即每秒显示的帧数;
    frameSize:帧的大小,可以通过cv::Size类指定;
    isColor:指定保存的视频是否为彩色,默认为true
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    (2)cv::VideoWriter::write():用于将一帧图像写入视频文件;
    cv::VideoWriter::write(const Mat& image)
    
    参数解释:
    image:要写入视频的帧,通常是一个cv::Mat对象;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    (3)cv::VideoWriter::isOpened():用于检查VideoWriter对象是否成功打开,如果成功打开了视频文件或者设备,该方法将返回true,否则返回false;
    (4)cv::VideoWriter::release():用于释放VideoWriter对象所占用的资源,一般在你已经完成了对视频的写入操作后调用它;

    示例:

    我们首先创建了一个 VideoWriter 对象,指定了视频文件的名称、FourCC编码、帧率和帧大小。接着,我们检查是否成功打开了文件。然后,我们创建了一个红色的帧(640x480 大小的纯红色图像)并将其写入视频文件10次。最后,我们释放了 VideoWriter 对象。

    #include 
    #include 
    #include 
    
    using namespace cv;
    using namespace std;
    
    int main() {
    
    	Demo demo;
    	// 初始化一个cv::VideoCapture对象,打开视频文件
    	VideoCapture capture("C:\\cpp\\image\\cayenne.mp4");
    	// 调用cv::VideoCapture类的get()方法,获取视频宽度,高度,帧数,帧率
    	int frame_width = capture.get(CAP_PROP_FRAME_WIDTH);
    	int frame_height = capture.get(CAP_PROP_FRAME_HEIGHT);
    	int count = capture.get(CAP_PROP_FRAME_COUNT);
    	double fps = capture.get(CAP_PROP_FPS);
    	std::cout << "frame width:" << frame_width << std::endl;
    	std::cout << "frame height:" << frame_height << std::endl;
    	std::cout << "FPS:" << fps << std::endl;
    	std::cout << "Number of Frames:" << count << std::endl;
    	// 初始化一个cv::VideoWriter 对象,保存处理后的视频文件
    	// capture.get(CAP_PROP_FOURCC):获取原视频的编解码器
    	// Size(frame_width, frame_height):原视频的宽高
    	VideoWriter writer("C:\\cpp\\image\\test.mp4", capture.get(CAP_PROP_FOURCC), fps, Size(frame_width, frame_height), true);
    	Mat frame;
    	while (true) {
    		// 读取视频的一帧,将其存储在frame对象中
    		capture.read(frame);
    		// TODO: do something...
    		// 对读取到的这帧图像,做flip()翻转处理
    		flip(frame, frame, 1);
    		if (frame.empty()) {
    			break;
    		}
    		// 显示这帧图像
    		imshow("frame", frame);
    		// 对这帧图像,做色彩空间转换
    		demo.colorSpace(frame);
    		// 将这帧图像写入视频文件
    		writer.write(frame);
    
    		int c = waitKey(1);
    		if (c == 27) { // 退出
    			break;
    		}
    	}
    
    	// release
    	capture.release();
    	writer.release();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    做色彩空间转换 demo.colorSpace()函数如下:

    void Demo::colorSpace(Mat &image) {
    
    	Mat gray, hsv;
    	// 转hsv
    	cvtColor(image, hsv, COLOR_BGR2HSV);
    	// 转灰度
    	cvtColor(image, gray, COLOR_BGR2GRAY);
    
    	// 显示这两张图
    	imshow("HSV",hsv);
    	imshow("GARY", gray);
    
    	// 保存这两张图
    	imwrite("C:\\cpp\\vs\\opencv\\hsv.png", hsv);
    	imwrite("C:\\cpp\\vs\\opencv\\gray.png", gray);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    RHEL8.4 安装docker&docker-compose
    问卷设计中的常见问题
    基于JavaEE电子商务交易系统
    mybatis-plus 分页插件配置
    uniapp图片base64保存本地
    uni-app:单页面的页面切换
    MindSponge分子动力学模拟——使用MDAnalysis工具进行后分析(2024.02)
    C3P0反序列化链分析
    老绅士才懂的Wallpaper免费使用方法3.0
    2741. 特别的排列 Medium
  • 原文地址:https://blog.csdn.net/qq_33867131/article/details/133344471