利用opencv2跟c++实现视频与图像的互相转换

利用opencv2和c++实现视频与图像的互相转换

做图像检测时,我们时常需要对视频进行处理,实现图像的实时检测,这时我们就需要把视频转换为图像进行处理,处理完之后,我们又需要把图像重新转换为视频,下面我将简单实现视频和图像的互相转换。

首先,视频转换为图像:

代码:

// videoANDimage.cpp : 定义控制台应用程序的入口点。
//需要修改的地方就是视频的路径需要修改,之后图像输出的位置为视频所在的文件夹

#include "stdafx.h"
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <string>
#include <sstream>
//#include <stringstream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{	
	cout<<"*******************开始视频转换为图像********************"<<endl;
	string path("D:\\jiangshan\\videoANDimage\\video2image\\out.avi");//视频路径
	cv::VideoCapture capture(path);
	//检查视频是否成功打开
	if(!capture.isOpened())
	{
		cout<<"不能打开视频文件,请检查视频文件路径是否输入正确!"<<endl;
		return -1;
	}
		
	//获取帧率、帧数
	double rate=capture.get(CV_CAP_PROP_FPS);
	long totalFramenumber=(long)capture.get(CV_CAP_PROP_FRAME_COUNT);
	cout<<"视频的帧数为:"<<totalFramenumber<<endl;
	cout<<"视频的帧率为:"<<rate<<endl;
	bool stop(false);
	cv::Mat frame;//当前视频帧
	int count=1;
	string imagepath;
	string pathtemp;
	string temp;
	int m=path.find_last_of('\\');
	pathtemp.assign(path,0,(m+1));
	while(true)
	{
		if(!capture.read(frame))
			break;
		stringstream ss;//数字转换为字符串
		ss<<count++;
		ss>>temp;
		if(count<10)
		{
			imagepath=pathtemp+"image0000"+temp+".jpg";
			cv::imwrite(imagepath,frame);
		}
		else if(count<100)
		{
			imagepath=pathtemp+"image000"+temp+".jpg";
			cv::imwrite(imagepath,frame);
		}
		else if(count<1000)
		{
			imagepath=pathtemp+"image00"+temp+".jpg";
			cv::imwrite(imagepath,frame);
		}
		else if(count<10000)
		{
			imagepath=pathtemp+"image0"+temp+".jpg";
			cv::imwrite(imagepath,frame);
		}
		else if(count<100000)
		{
			imagepath=pathtemp+"image"+temp+".jpg";
			cv::imwrite(imagepath,frame);
		}
	}
	capture.release();
	cout<<"*********************生成图像成功!**********************"<<endl;
	system("pause");
	return 0;
}

接着是图像转换为视频:

图像传入方式我选择的是路径写在txt中,通过读入txt不断读入图像。txt的生成方式为:建立一个txt文档,把后缀名改为.bat,输入

dir /b/s/p/w *.jpg>list.txt
@pause

保存之后放入图像所在文件,运行即可名为list的txt文件,路径保存于此。

利用opencv2跟c++实现视频与图像的互相转换

opencv只是一个计算机视觉库而不是一个视频处理编码库。所以开发者们试图将这部分尽可能精简,结果就是opencv能够处理的视频只剩下avi扩展名的了。另外一个限制就是你不能创建超过2GB的单个视频,还有就是每个文件里只能支持一个视频流,不能将音频流和字幕流等其他数据放在里面。另外,任何系统支持的编码器在这里都应该能工作。

要创建视频文件,首先得创建一个VideoWriter类得对象。通过构造函数里的参数和其他合适时机使用open函数打开。需要确定文件的名称,格式,帧率,帧大小,是否彩色。其中格式作为第二个参数,opencv提供的格式是未经过压缩的,目前支持的格式如下:

CV_FOURCC('P', 'I', 'M', '1') = MPEG-1 codec

CV_FOURCC('M', 'J', 'P', 'G') = motion-jpeg codec
CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec 
CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec 
CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec 
CV_FOURCC('U', '2', '6', '3') = H263 codec 
CV_FOURCC('I', '2', '6', '3') = H263I codec 

CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec

代码:

// image2video.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <string>
#include <fstream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	cout<<"*********************开始图像转换为视频*********************"<<endl;
	string imagepath("D:\\jiangshan\\videoANDimage\\video2image\\list.txt");
	int m=imagepath.find_last_of('.');
	string avipath=imagepath.substr(0,m)+".avi";
	ifstream File;
	File.open(imagepath);
	if(!File.is_open())
	{
		cout<<"图像无法读取,请检查图像路径是否有误!"<<endl;
		return -1;
	}
	string imageName;
	int height;
	int width;
	double rate;
	cout<<"请输入帧率:";
	cin>>rate;
	cout<<"请输入图像的宽度:";
	cin>>width;
	cout<<"请输入图像的高度:";
	cin>>height;
	cout<<"请输入图像是否为彩色,是输入1,不是则输入0!  ";
	int e;
	bool color=true;
	cin>>e;
	if(e==0)
	{
		color=false;
	}
	cv::VideoWriter writer;
	writer.open (avipath,CV_FOURCC('M', 'J', 'P', 'G'),rate,cv::Size(width,height),color);
	if(!writer.isOpened())
	{
		cout<<"Could not open the writer for write!"<<endl;
		return -1;
	}
	while(getline(File,imageName))
	{
		cv::Mat image=cv::imread(imageName);
		if(!image.data)
		{
			cout<<"Could not load image file..."<<endl;
			return -1;
		}
		writer<<image;	
	}
	cout<<"*********************生成视频成功!*********************"<<endl;
	system("pause");
	return 0;
}