【OpenCV】视频的分帧并以任意的fps合帧处理

博客介绍了实现分帧合帧所需的环境,使用OpenCV,版本要求3.0以上,这里具体为OpenCV320。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境:OpenCV320(3.0以上版本都可以)

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>

using namespace std;
using namespace cv;

void Image_to_video()
{
	int i = 0;
	Mat img;
	
	cout << "------------- image to video ... ----------------" <<endl;
	int fps = 8;		// or 25
	int frameW = 500;	//原视频的大小宽高
	int frameH = 500;	 
	
	VideoWriter writer("111.avi", CV_FOURCC('M', 'J', 'P', 'G'), fps, Size(frameW , frameH ), 1);
	
	while (i<150)
	{
		char image_name[256] = {0};
		sprintf(image_name, ".\\frame\\1 (%d).jpg",i);
		img = imread(image_name,IMREAD_ANYCOLOR);
		if (img.empty())
		{
			cout << "Could not load image file" << endl;
			return ;
		}
		

		cout << i << endl;
		i++;

		imshow("mainWin", img);
		waitKey(30);
		writer << img;
	}
}

void video_to_image()
{
	//视频分帧处理
	VideoCapture cap("123.avi");
	if (!cap.isOpened())
	{
		cout << "未能成功读取视频文件error" << endl;
		return ;
	}
	Mat image;
	int i = 0;
	while (1)
	{
		cap >> image;
		//int nRows = image.rows;				//500
		//int nCols = image.cols;				//500
		//cout << nRows << "," << nCols << endl;
		if (image.empty())
		{
			break;
		}
		char ch1[256] = { 0 };
		sprintf(ch1, ".\\frame\\1 (%d).jpg", i);
		i++;//i=150
		imwrite(ch1, image);

	}
}

int main()
{
	video_to_image();//视频转图像并进行保存

	Image_to_video();//通过读取图像按一定的帧率转视频
	
	return 0;
}

 

 

 

一、问题的提出 做运动析检测,需要有一定的素材视频,但是素材视频的编码OpenCV不能识别,无法对指定的视频做实验,怎么素材视频通用化使得OpenCV能正常识别? 二、解决的方法 (1)素材视频总是有配套的播放器来播放,那么使用这个播放器查看总帧数,和总播放时长,计算出率为25,表示一秒钟播放25图像。 (2)用这个配套的播放器对素材视频进行逐步进抓图,这个操作很辛苦,一秒钟25,那么抓25是一秒,素材视频30秒就要抓750,很辛苦。 (3)抓完后,发现一图1.4M,以位图格式保存,那么30秒就要达到1G的存储空间,怎么办?没办法,不知道怎么去获取解码器和安装解码器,就只能这么忍受。察看到逐步进抓图的存储是按序列编排文件名,那么要修改好使得每个文件名都是以规则“文件名”+“序列”的形式存在。 (4)编写根据序列图生成率25的视频的代码 三、问题的解决: (1)解决一个字符串合并的问题: 由于字符串参数有个赋值格式化设置函数叫做Format,要实现多类型参数的字符串化,可以参照如下示例: float f = 0.0; char sz[128]; int n = 1; CString str; str.Format("%f%s%d",f,sz,n); (2)采用MJPG的编码格式依次将这些图像序列写入到视频中保存起来,采用MJPG的编码格式是因为操作系统自带了Media player播放器,这种编码格式属于无压缩的,Media player可以识别播放。 (3)实现方式是使用MFC对话框窗体的按钮事件来进行视频的逐写图,由于帧数多,那么在写入器循环做写这个动作的时候,整个程序是假死在那里直到写入器的写入操作终结。
在C++中,结OpenCV库读取视频并对其进行二值化处理,可以按照以下步骤进行: 首先,确保已经包含了`opencv2/videoio.hpp`和`opencv2/highgui.hpp`头文件,并链接了相应的OpenCV库。 1. 初始化`VideoCapture`和`Mat`对象: ```cpp #include <opencv2/opencv.hpp> cv::VideoCapture cap("video_path.mp4"); // 替换为你需要的视频文件路径 cv::Mat frame; // 存储每一的矩阵 ``` 2. 打开视频并获取视频信息: ```cpp if (!cap.isOpened()) { std::cerr << "Error opening video file" << std::endl; return -1; } int width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH)); int height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT)); int fps = cap.get(cv::CAP_PROP_FPS); // 率 ``` 3. 循环读取并二值化处理: ```cpp while (true) { // 读取 cap >> frame; // 判断是否读取到视频结束 if (frame.empty()) { break; } // 将BGR颜色空间转换为灰度图 cv::Mat grayFrame; cv::cvtColor(frame, grayFrame, cv::COLOR_BGR2GRAY); // 应用二值化操作,这里以Otsu's阈值法为例 cv::threshold(grayFrame, grayFrame, 0, 255, cv::THRESH_BINARY + cv::THRESH_OTSU); // 可能还需要进一步调整二值化的结果,比如膨胀或腐蚀等 // 你可以在这里查看或保存二值化后的 cv::imshow("Binary Video", grayFrame); if (cv::waitKey(1) >= 0) { // 如果用户按下任意键则退出循环 break; } } // 释放资源 cap.release(); cv::destroyAllWindows(); ``` 在上述代码中,`cv::cvtColor`函数将彩色转化为灰度,`cv::threshold`函数应用二值化处理,然后通过`cv::imshow`展示结果。当用户按下键盘上任意键时,程序停止读取和显示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值