/************************ @HJ 2017/3/30 参考http://blog.sina.com.cn/s/blog_4b0020f301010qcz.html修改的代码 @主要调用opencv相关函数,从视频流中提取出图片序列 @需要注意的问题: cvReleaseImage(&pImg)释放内存出错的两种情况:具体可以参考http://www.cnblogs.com/grandyang/p/4615036.html 1)从摄像头获取的图片不能被修改和释放,所以如果我们对捕获的图像调用cvReleaseImage就会出错 2)使用完了CvCapture,需要用cvReleaseCapture来释放内存,那么我们就不需要再用cvReleaseImage来释放每一张图像的内存了 ******************************/ #include <opencv2opencv.hpp> #include <highgui.h> #include <iostream> #include <io.h>//for _acess() #include <string> const int picNum = 25;//设置所想要的图片序列数量 char* videoName1 = "C:\TEST\opencv\V2P2V\V2P2V\V2P2V\1.wmv";//输入的视频绝对路径 char* outDir1 = "C:\TEST\opencv\V2P2V\V2P2V\V2P2V\img\";//输出图像的绝对路径 int VideoToImage(char* videoName, char* outDir, char* imgExt, int picNum);//视频转化为图片序列MaxFrameCount可以填写你想需要的图片序列格式 //将视频转换为图片序列 返回由视频分解得到的图片总帧数 int VideoToImage(char* videoName, char* outDir, char* imgExt, int picNum) { CvCapture *cap = cvCaptureFromFile(videoName); if (cap == NULL) { return 0; } if (_access(outDir, 0) == -1) { std::cout << "the ouput directory does not exist!" << std::endl; cvWaitKey(); } char cur_fn[255];//保存当前帧所得图片的文件名 IplImage* pImg = NULL; int frame = 0; while ((pImg = cvQueryFrame(cap)) != NULL && (frame<picNum)) { frame++; strcpy(cur_fn, ""); sprintf(cur_fn, "%s%d%s", outDir, frame, imgExt);//将outDir, frame, imgExt三个数据拼接然后放在cur_fn中 cvSaveImage(cur_fn, pImg, NULL); } //cvReleaseImage(&pImg);//从摄像头获取的图片不能被修改和释放,所以如果我们对捕获的图像调用cvReleaseImage就会出错 cvReleaseCapture(&cap); return 1; } int main(){ //视频转图片 if (int images = VideoToImage(videoName1, outDir1, ".jpg", picNum)){//输入的视频绝对路径、输出图像的绝对路径、存储图像的格式.jpg,图像序列数据 std::cout << "ALL pictures have been extracted from the video." << std::endl; } else std::cout << "the work is failed." << std::endl; cvWaitKey(); }
---------------------------------------------------------------------------------------------------------------------------------------------------------------
jpg图片序列,转化成avi格式视频:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <io.h> using namespace cv; using namespace std; //将图片序列转换为视频,返回视频帧数 目前OpenCV只支持输出AVI格式的视频 int ImageToVideo(char* outDir, char* videoName, char* inputDir, int startFrame, int endFrame, int imgW, int imgH, char* imgExt, double fps, int isColor, int fourcc) { //判断输入文件夹是否存在 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); } 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; } int main() { //将从摄像头中读到的图像序列转换为.avi视频 //VideoCapture capture(0); //VideoWriter writer("VideoTest.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25.0, Size(640, 480)); //Mat frame; //while (capture.isOpened()) //{ // capture >> frame; // writer << frame; // imshow("video", frame); // if (cvWaitKey(20) == 27) // { // break; // } //} char* outDir = "C:\TEST\opencv\video2pic\viedo2pic\viedo2pic\img\"; char* videoName = "110.avi"; char* inputDir = "C:\TEST\opencv\video2pic\viedo2pic\viedo2pic\img\"; int startFrame =1; int endFrame = 100; int imgW = 320; int imgH = 240; char* imgExt=".jpg"; double fps = 15; ImageToVideo( outDir, videoName, inputDir, startFrame, endFrame, imgW, imgH, imgExt, fps, 1, CV_FOURCC('D', 'I', 'V', 'X')); return 0; }