opencv,图片视频相互转换

本文介绍了一个实用工具,能够实现视频与图片序列之间的相互转换,并提供了详细的代码实现。支持自定义输出目录,灵活调整参数。

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

引言

我们在计算机视觉相关的实验中都需要视频与图片序列之间相互转换,上次简单了写了这两种操作是如何实现的(http://blog.sina.com.cn/s/blog_4b0020f301010qcz.html),现在将其功能完善:一方面将其封装为函数,方便调用;另一方面,视频转图片可以任意设定图片输出目录,函数会自动创建相关目录;图片序列转视频可以设定更多的参数,也就可以更好的控制,而且可以自行设定视频输出的目录,函数自动检测并创建相关目录

适合windows平台+OpenCV;

需要引入包含文件:

#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <direct.h>//for mk_dir
#include <io.h>//for _acess()
#include <string>

三个主要的功能函数

int recursive_mkdir( char *dir );//创建多级目录
int ImageToVideo(char* outDir,char* videoName,char* inputDir,int startFrame,int endFrame, int imgW,int imgH,char* imgExt,double fps,int isColor,int fourcc);//图片序列转化为视频
int  VideoToImage(char* videoName,char* outDir,char* imgExt,int maxFrameCount);//视频转化为图片序列
//将图片序列转换为视频,返回视频帧数
int ImageToVideo(char* outDir,char* videoName,char* inputDir,int startFrame,int endFrame, int imgW,int imgH,char* imgExt,double fps=24,int isColor=1,int fourcc=CV_FOURCC('D','I','V','X'))
{       
        //判断输入文件夹是否存在
         if (_access(inputDir,0)==-1)
         {
    std::cout<<"the input directory does not exist!"<<std::endl;
    return 0;
         }
   //判断输出文件夹是否创建 若没有则创建;若为NULL则默认当前工作目录
   char fullVideoName[255];//输出视频的完整文件名:路径+文件名
         strcpy(fullVideoName,"");
   if (outDir==NULL)
   {
    sprintf(fullVideoName,"%s",videoName);
   }
   else
   {
        if (_access(outDir,0)==-1)
           {
                           recursive_mkdir(outDir);
           }
      sprintf(fullVideoName,"%s%s",outDir,videoName);
   }
          int frameCount=0;
    CvVideoWriter *pWriter=NULL;
    CvSize size=cvSize(imgW,imgH);
    pWriter=cvCreateVideoWriter(videoName,fourcc,fps,size,isColor);//CREATE WRITER
        
    IplImage *pImg=NULL;
    char cur_fn[255];//表示某张图片的路径
    while(startFrame<=endFrame)
    {
     strcpy(cur_fn,"");
     sprintf(cur_fn,"%s%d%s",inputDir,startFrame,imgExt);//need to change
     pImg=cvLoadImage(cur_fn,isColor);
     if (!pImg)    
     {
      std::cout<<"can't open an image file"<<std::endl;
      return frameCount;
     }
     cvWriteFrame(pWriter,pImg);
     cvWaitKey(1);
     std::cout<<"Write frame "<<startFrame<<std::endl;
     startFrame++;
     cvReleaseImage(&pImg);
     frameCount++;
    }
    cvReleaseVideoWriter(&pWriter);
    rename(videoName,fullVideoName);//移动文件到指定文件夹
    return  frameCount;
}
//将视频转换为图片序列 返回由视频分解得到的图片总帧数 目前OpenCV只支持AVI格式 因此使用之前需要
//将视频转化问AVI格式

int  VideoToImage(char* videoName,char* outDir,char* imgExt,int maxFrameCount)
{
 CvCapture *cap= cvCaptureFromFile(videoName);
 if (cap==NULL)
 {
  return 0;
 }
   //保存图片的文件夹路径一定要有,因为OpenCV不会自动创建文件夹
 if (_access(outDir,0)==-1)
 {
    recursive_mkdir(outDir);
    std::cout<<"the ouput directory does not exist, and the have been created autonomously!"<<std::endl;
 }
 char cur_fn[255];//保存当前帧所得图片的文件名
 IplImage* pImg=NULL;
 int frame=0;
 while((pImg=cvQueryFrame(cap))!=NULL&&(frame<maxFrameCount))
 {               
  frame++;
  strcpy(cur_fn,"");
  sprintf(cur_fn,"%s%d%s",outDir,frame,imgExt);//这里的设置适合形如 123.jpg 124.jpg的图片序列
  cvSaveImage(cur_fn,pImg,NULL);
 }
 cvReleaseImage(&pImg);
 cvReleaseCapture(&cap);
 return frame;
}
 
 
//该函数借鉴了网上资料,自动创建多级目录
int recursive_mkdir( char *dir )
{
 //分解路径名E:\\AA\\BB\\CC\\
 //
 std::string str = dir;
 int index = 0;
 int i = 0;
 while(1)
 {
  std::string::size_type pos = str.find("\\",index);
  std::string str1;
  str1 = str.substr(0,pos);
  if( pos != -1 && i > 0 )
  {
   if (_access(str1.c_str(),0)==-1)
   {
       _mkdir(str1.c_str());
   }
  }
  if( pos==-1 )
  {
   break;
  }
  i ++;
  index = pos+1;
 }
 return 0;
}

调用示例

   //视频转图片
  char* videoName1="E:\\VIDEOS\\TEST\\Videos\\woman.avi";
  char* outDir1="E:\\VIDEOS\\TEST\\Sequences\\WoemenSequence\\";
  int images=VideoToImage(videoName1,outDir1,".jpg",200);
  std::cout<<"total frames have been extracted from video."<<std::endl;
  int p;
  std::cin>>p;
 
//图片转视频
   char* inputDir="E:\\woman_sequence\\Parameters_Good\\part_occ\\";
   char* videoName="woman.avi";
   char* outDir="E:\\VIDEOS\\TEST\\Videos\\";
   int frames=ImageToVideo(outDir,videoName,inputDir,0,128,352,288,".jpg",30,1,CV_FOURCC('P','I','M','1'));
   std::cout<<"total frames "<<frames<<" have been write to video."<<std::endl;
   int p;
   std::cin>>p;


转自: http://blog.sina.com.cn/s/blog_4b0020f301011yqr.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zlingh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值