OpenCV 视频与图片序列相互转换

来源:互联网 发布:windows自带软件 编辑:程序博客网 时间:2024/05/16 17:22

Image To Video

// test000.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <opencv2/core/core.hpp>  #include <opencv2/highgui/highgui.hpp>  #include<iostream>  #include <direct.h>//for mk_dir#include <io.h>//for _acess()#include <string>using namespace std;using namespace cv;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 _tmain(int argc, _TCHAR* argv[]){    //图片转视频F:\carrdisp_test\origin    char* inputDir = "E:\\Homework\\ImagesBmp\\";    char* videoName = "carrdisp_clofr.avi";    char* outDir = "F:\\BaiduYunDownload\\video\\";    int frames = ImageToVideo(outDir, videoName, inputDir, 1, 327, 400, 400, ".bmp", 15, 3, CV_FOURCC('X', 'V', 'I', 'D'));    std::cout << "total frames " << frames << " have been write to video." << std::endl;    int p;    std::cin >> p;    return 0;}//将图片序列转换为视频,返回视频帧数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('X', 'V', 'I', 'D')){    //判断输入文件夹是否存在    if (_access(inputDir, 0) == -1){        std::cout << "the input directory does not exist!" << std::endl;        return 0;    }    //判断输出文件夹是否创建 若没有则创建;若为NULL则默认当前工作目录    char fullVideoName[255];//输出视频的完整文件名:路径+文件名    strcpy_s(fullVideoName, "");    if (outDir == NULL)    {        sprintf_s(fullVideoName, "%s", videoName);//把videoName打印成一个字符串保存在fullVideoName中     }    else{        if (_access(outDir, 0) == -1){            recursive_mkdir(outDir);        }        sprintf_s(fullVideoName, "%s%s", outDir, videoName);//将字符串outDir和videoName连接起来,打印,保存在fullVideoName中    }    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_s(cur_fn, "");        sprintf_s(cur_fn, "%s%03d%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_s(cur_fn, "");        sprintf_s(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;

这里写图片描述

Video To Image

// test000.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <opencv2/core/core.hpp>  #include <opencv2/highgui/highgui.hpp>  #include<iostream>  #include <direct.h>//for mk_dir#include <io.h>//for _acess()#include <string>using namespace std;using namespace cv;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 _tmain(int argc, _TCHAR* argv[]){    //视频转图片    char* videoName1 = "E:\\Homework\\Video\\iss06-10-25_0.avi";    char* outDir1 = "F:\\BaiduYunDownload\\ImagesBmp\\";    int images = VideoToImage(videoName1, outDir1, ".jpg", 380);    std::cout << "total frames have been extracted from video." << std::endl;    int p;    std::cin >> p;    return 0;}//将图片序列转换为视频,返回视频帧数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('X', 'V', 'I', 'D')){    //判断输入文件夹是否存在    if (_access(inputDir, 0) == -1){        std::cout << "the input directory does not exist!" << std::endl;        return 0;    }    //判断输出文件夹是否创建 若没有则创建;若为NULL则默认当前工作目录    char fullVideoName[255];//输出视频的完整文件名:路径+文件名    strcpy_s(fullVideoName, "");    if (outDir == NULL)    {        sprintf_s(fullVideoName, "%s", videoName);//把videoName打印成一个字符串保存在fullVideoName中     }    else{        if (_access(outDir, 0) == -1){            recursive_mkdir(outDir);        }        sprintf_s(fullVideoName, "%s%s", outDir, videoName);//将字符串outDir和videoName连接起来,打印,保存在fullVideoName中    }    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_s(cur_fn, "");        sprintf_s(cur_fn, "%s%03d%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_s(cur_fn, "");        sprintf_s(cur_fn, "%s%03d%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;}

这里写图片描述

连续播放文件夹下所有video和image

#include "stdafx.h"#include <opencv2/core/core.hpp>  #include <opencv2/highgui/highgui.hpp>  #include<iostream>  #include <direct.h>//for mk_dir#include <io.h>//for _acess()#include <opencv2\contrib\contrib.hpp>  #include <string>using namespace std;using namespace cv;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 _tmain(int argc, _TCHAR* argv[]){    string dir_path = "E:\\Homework\\Video\\";    Directory dir;    vector<string> fileNames = dir.GetListFiles(dir_path, "*.avi", false);    for (int i = 0; i < fileNames.size(); i++)    {        //get image name          string fileName = fileNames[i];        string fileFullName = dir_path + fileName;        cout << "File name:" << fileName << endl;        cout << "Full path:" << fileFullName << endl;        //load image          /*IplImage* srcImg = cvLoadImage(fileFullName.c_str(), -1);        cvShowImage("src", srcImg);        cvWaitKey(0);*/        //read video        cvNamedWindow(fileName.c_str(), CV_WINDOW_AUTOSIZE);        CvCapture* capture = cvCreateFileCapture(fileFullName.c_str());        IplImage* frame;        while (1)        {            frame = cvQueryFrame(capture);            if (!frame) break;            cvShowImage(fileName.c_str(), frame);            char c = cvWaitKey(30);            if (c == 27) break;        }        cvReleaseCapture(&capture);        cvDestroyWindow(fileName.c_str());    }    return 0;}

这里写图片描述

进度条控制

#include "stdafx.h"#include <opencv2/core/core.hpp>  #include <opencv2/highgui/highgui.hpp>  #include<iostream>  #include <direct.h>//for mk_dir#include <io.h>//for _acess()#include <opencv2\contrib\contrib.hpp>  #include <string>using namespace std;using namespace cv;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);//视频转化为图片序列//设置全局变量,一个为滚动条的位置。回调函数需要用到的变量cvCapture也是全局变量,所以前面有g_,代表globalCvCapture *g_capture = NULL;int g_slider_position = 0;int frame_count = 0;//回调函数,滚动条拖动时被调用 参数是滚动条的位置(整数) 此函数可以设置cvCapture对象的属性void onTrackbarSlide(int pos){    cvSetCaptureProperty(        g_capture,        CV_CAP_PROP_POS_FRAMES,        pos        );    frame_count = pos;//拉一下要统一位置}int _tmain(int argc, _TCHAR* argv[]){    string dir_path = "E:\\Homework\\Video\\";    Directory dir;    vector<string> fileNames = dir.GetListFiles(dir_path, "*.avi", false);    for (int i = 0; i < fileNames.size(); i++)    {        //get image name          string fileName = fileNames[i];        string fileFullName = dir_path + fileName;        cout << "File name:" << fileName << endl;        cout << "Full path:" << fileFullName << endl;        //load image          /*IplImage* srcImg = cvLoadImage(fileFullName.c_str(), -1);        cvShowImage("src", srcImg);        cvWaitKey(0);*/        //read video        cvNamedWindow(fileName.c_str(), CV_WINDOW_AUTOSIZE);        g_capture = cvCreateFileCapture(fileFullName.c_str());        IplImage* frame;        int totalNum = (int)cvGetCaptureProperty(g_capture, CV_CAP_PROP_FRAME_COUNT); //计算文件的总帧数          if (totalNum >= 0)        {            cvCreateTrackbar(                "Position",//滚动条名称                fileName.c_str(),//所属窗口名称                &g_slider_position,                totalNum,                onTrackbarSlide//当滚动条拖动时被触发 回调函数                );        }        while (1)        {            frame = cvQueryFrame(g_capture);            if (!frame) break;            cvShowImage(fileName.c_str(), frame);            char c = cvWaitKey(30);            if (c == 27) break;            cvSetTrackbarPos("Position", fileName.c_str(), frame_count);            frame_count++;            //<span style = "white-space:pre">        < /span>//设置进度条的运动位置          }        cvReleaseCapture(&g_capture);        cvDestroyWindow(fileName.c_str());        g_slider_position = 0;        frame_count = 0;    }    return 0;}

这里写图片描述

所有Video To Image

#include "stdafx.h"#include <opencv2/core/core.hpp>  #include <opencv2/highgui/highgui.hpp>  #include<iostream>  #include <direct.h>//for mk_dir#include <io.h>//for _acess()#include <opencv2\contrib\contrib.hpp>  #include <string>using namespace std;using namespace cv;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 g_i;int _tmain(int argc, _TCHAR* argv[]){    string dir_path = "F:\\BaiduYunDownload\\video\\";    Directory dir;    vector<string> fileNames = dir.GetListFiles(dir_path, "*.avi", false);    for (int i = 0; i < fileNames.size(); i++)    {        //get image name          string fileName = fileNames[i];        string fileFullName = dir_path + fileName;        cout << "File name:" << fileName << endl;        cout << "Full path:" << fileFullName << endl;        //read video        cvNamedWindow(fileName.c_str(), CV_WINDOW_AUTOSIZE);        CvCapture* capture = cvCreateFileCapture(fileFullName.c_str());        IplImage* frame;        //视频转图片        char* videoPathName = &fileFullName[0];        char* outDir = "F:\\BaiduYunDownload\\ImagesBmp\\";        int images = VideoToImage(videoPathName, outDir, ".jpg", 380);        std::cout << "total frames have been extracted from video." << std::endl;        cvReleaseCapture(&capture);        cvDestroyWindow(fileName.c_str());        g_i++;    }    return 0;}//将视频转换为图片序列 返回由视频分解得到的图片总帧数 目前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_s(cur_fn, "");        sprintf_s(cur_fn, "%sindex%d_%03d%s", outDir, g_i,frame, imgExt);//这里的设置适合形如 index[i]_123.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;}

这里写图片描述

参考

【1】使用OPENCV播放AVI视频 - 超人不会飞LC - 博客园
http://www.cnblogs.com/MichaelLi1994/p/3521439.html
【2】OpenCV自带方法遍历目录下文件 - holybin的专栏 - CSDN博客
http://blog.csdn.net/holybin/article/details/25786727
【3】OpenCV实现遍历文件夹下所有文件 - 网络资源是无限的 - CSDN博客
http://blog.csdn.net/fengbingchun/article/details/42435901
【4】OpenCV 视频与图片序列相互转换 - 微雪 - 博客园
http://www.cnblogs.com/yingying0907/archive/2012/08/11/2633426.html
【5】OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect - 迭代的是人,递归的是神 - CSDN博客
http://blog.csdn.net/yang_xian521/article/details/6973667