OpenCV 视频保存成图片序列

// avi2images.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"



//产生一个随机数和时间组成的文件名
//rand_file_name:最后产生的随机文件的名字
//extension:文件的扩展名
//num_of_rand_nums:文件名中包含的随机数的个数
int OpencvChinaCom_Get_Rand_Filename(char* rand_file_name , char* extension ,int num_of_rand_nums)
{
	
	
	char* p_end;
	int i = 0 , rand_num;

	if(!rand_file_name || !extension || num_of_rand_nums<0)return -1;
    time_t temptime = time(0);/*得到系统时间*/
    tm *temptm = localtime(&temptime);
	
	unsigned int mon=temptm->tm_mon+1;
    unsigned int day=temptm->tm_mday;
    unsigned int s_hour = temptm->tm_hour;
    unsigned s_minute = temptm->tm_min;
    unsigned s_second = temptm->tm_sec;

	//将时间写入文件名
	sprintf(rand_file_name , "%d_%d_%d_%d_%d_" , mon , day , s_hour , s_minute , s_second);

	//将p_end定位到字符串的最后面
	p_end = rand_file_name;
	
	while(*p_end != '\0')p_end++;

	for(i=0;i<num_of_rand_nums;i++)
	{
		 rand_num=1+(int)(10.0*rand()/(RAND_MAX+1.0)); /*产生一个0到10的随机数*/
		 if(rand_num>=10)rand_num = 9;
		 if(rand_num<0)rand_num = 0;

		 sprintf(p_end++,"%d_" , rand_num);
	
	}

	sprintf(p_end , ".%s",extension);


return 1;
}


int main(int argc, char* argv[])
{//========================================================
    // CvCapture 是一个结构体,用来保存图像捕获所需要的信息。
    // opencv提供两种方式从外部捕获图像,一种是从摄像头中,一种
    // 是通过解码视频得到图像。两种方式都必须从第一帧开始一帧一帧
    // 的按顺序获取,因此每获取一帧后都要保存相应的状态和参数。
    // 比如从视频文件中获取,需要保存视频文件的文件名,相应的解码器
    // 类型,下一次如果要获取将需要解码哪一帧等。 这些信息都保存在
    // CvCapture结构中,每获取一帧后,这些信息都将被更新,获取下一帧
    // 需要将新信息传给获取的api接口
    //=======================================================
    CvCapture* capture = 0;
    //===========================================================
    // IplImage 是结构体类型,用来保存一帧图像的信息,也就是一帧
    // 图像的所有像素值构成的一个矩阵
    //===========================================================
    IplImage *frame;
     
     // 创建一个窗口,用“result”作为窗口的标识符
     cvNamedWindow( "result", 1 );
     
     // ==========================================
     // 初始化一个视频捕获操作。
     // 告诉底层的捕获api我想从 Capture1.avi中捕获图片,
     // 底层api将检测并选择相应的解码器并做好准备工作
     //==============================================
   capture = cvCaptureFromFile("c:\\1.avi");

   char imagename[256];
   char imagefullpath[256];
   IplImage* frameCopy = cvCreateImage(cvSize(cvGetCaptureProperty(capture,3),cvGetCaptureProperty(capture,4)),8,3);

    // 如果 初始化失败,那么capture为空指针,程序停止,
    // 否则进入捕获循环
    if( capture )
    {
        // 捕获循环
        for(;;)
        {
            // 调用cvGrabFrame,让底层api解码一帧图像
            // 如果解码失败,就退出循环
            // 如果成功,解码的图像保存在底层api的缓存中
            if( !cvGrabFrame( capture ))
                break;
            
            // 将解码得到图像信息从缓存中转换成IplImage格式放在frame中
            frame = cvRetrieveFrame( capture );
			
			cvCopy(frame,frameCopy);cvFlip(frameCopy,frameCopy);
			OpencvChinaCom_Get_Rand_Filename(imagename,"jpg",4);
			sprintf(imagefullpath,"%s%s","C:\\images\\",imagename);
			cvSaveImage(imagefullpath,frameCopy);

            // 如果获取缓存或转换失败,则退出循环
            if( !frame )
                break;

            // 将frame中的图像信息在窗口result中显示
			cvShowImage( "result", frame );
			
            
            // 如果你敲了键盘,就退出程序,否则继续捕获下一帧
            if( cvWaitKey( 10 ) >= 0 )
                break;
        }

        // 退出程序之前要清理一下堆栈中的内存,免得内存泄露
       // cvReleaseImage( &frame_copy );
		cvReleaseImage(&frameCopy);
        
        // 退出之前结束底层api的捕获操作,免得它们占着茅坑不拉屎
        // 比如会使得别的程序无法访问已经被它们打开的文件
        cvReleaseCapture( &capture );
    
}
    cvDestroyWindow("result");
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_30460949/article/details/89406639