(Opencv3.4.2)文件夹下批处理视频与图像的相互转换


目录

 

0.最终环境

1.文件夹下所有视频文件批处理转图像

2.文件夹下所有文件夹中图像批处理转视频

3.工程

4.参考


0.最终环境

win10
vs2015
opencv342

关于vs2015控制台程序工程属性配置,包含目录、库目录、链接器-> 输入:

 

1.文件夹下所有视频文件批处理转图像

文件夹中的所有视频文件遍历保存到该文件夹下,以该视频名称命名的目录下,保存图像:

#include <stdio.h>
#include <io.h>
#include <string>
#include <fstream> 
#include <direct.h>
#include <iostream>
#include "opencv2/opencv.hpp"
#include <io.h>

using namespace std;
using namespace cv;

//给视频文件的根目录,就可以批处理为多个mp4文件生成图像,生成的图像保存到以视频名命名的文件夹中
int VideoWriteImageBatch(string filePath) {
	string inPath = filePath + "*.mp4";//遍历文件夹下的所有文件
									   //用于查找的句柄
	std::string::size_type nPos1 = std::string::npos;
	intptr_t handle = 0;
	struct _finddata_t fileinfo;
	//第一次查找
	handle = _findfirst(inPath.c_str(), &fileinfo);
	if (handle == -1)
		return -1;
	do
	{
		//新建文件夹
		nPos1 = (string(fileinfo.name)).find_last_of(".");
		string folderPath = filePath + (string(fileinfo.name)).substr(0, nPos1) + "/";
		cout << (string(fileinfo.name)).substr(0, nPos1) << endl;
		if (0 != access(folderPath.c_str(), 0))
		{
			// if this folder not exist, create a new one.
			mkdir(folderPath.c_str());   // 返回 0 表示创建成功,-1 表示失败
		}
		else {
			cout << "Directory already exists." << endl;
		}

		string mp4Path = filePath + string(fileinfo.name);
		VideoCapture cap(mp4Path);
		cout << mp4Path << endl;
		//获取视频总帧数
		long totalFrameNumber = cap.get(CV_CAP_PROP_FRAME_COUNT);
		cout << "total frames: " << totalFrameNumber << endl;
		Mat frame;
		bool flags = true;
		long currentFrame = 1;

		while (flags) {
			// 读取视频每一帧
			cap.read(frame);
			stringstream str;
			str << currentFrame << ".png";
			cout << "正在处理第" << currentFrame << "帧" << endl;
			printf("\n");

			// 设置每1帧获取一次帧
			if (currentFrame % 1 == 0) {
				// 将帧转成图片输出
				imwrite(folderPath + str.str(), frame);
			}

			// 结束条件
			if (currentFrame >= totalFrameNumber) {
				flags = false;
			}
			currentFrame++;
		}

	} while (!_findnext(handle, &fileinfo));

	_findclose(handle);

	return 1;
}

// 描述:将视频帧转成图片输出
int main()
{
	//目标文件夹路径
	string filePath = "E:/project/testData/";
	
	VideoWriteImageBatch(filePath);
	
	system("pause");
	return 0;
}

2.文件夹下所有文件夹中图像批处理转视频

文件夹中的所有文件夹中图像(命名例:1.jpg-1000.jpg)生成视频,以该文件夹名称为视频命名,其中ImageWriteVideo中for循环需要给开始写视频的序号,ImageWriteVideoBatch中firstImage也需要自己给:

#include <stdio.h>
#include <io.h>
#include <string>
#include <fstream> 
#include <direct.h>
#include <iostream>
#include "opencv2/opencv.hpp"
#include <io.h>
#include "VideoProcess.h"

using namespace std;
using namespace cv;

//输入图像根目录,第一张图像路径,视频名称,视频帧数量;
//输出视频
int ImageWriteVideo(const char *imagePath, const char *firstImage, string videoName, int videoNum)
{
	char imageName[300];
	Mat src;
	Mat frame;
	Mat src0 = imread(firstImage);
	resize(src0, src0, Size(1280, 720), 0, 0, INTER_LINEAR);
	Size size = src0.size();
	VideoWriter writer(videoName, CV_FOURCC('M', 'J', 'P', 'G'), 25, size, true);

	for (int i = 3; i < videoNum; i++) {
		sprintf_s(imageName, "%s%04d%s", imagePath, i, ".png");
		src = imread(imageName);
		resize(src, src, Size(1280, 720), 0, 0, INTER_LINEAR);

		if (src.empty()) {
			cout << "error in read picture" << endl;
			return -1;
		}
		writer.write(src);
		
	}
	cout << "==================================success to write video=================================\n" << endl;
	return 1;
}


//给视频文件的根目录,就可以批处理为多个目录下的图像生成avi文件
int ImageWriteVideoBatch(string filePath) {

	string inPath = filePath + "*";//遍历文件夹下的所有文件
	intptr_t handle = 0;//用于查找的句柄
	struct _finddata_t fileinfo;
	//第一次查找
	handle = _findfirst(inPath.c_str(), &fileinfo);
	if (handle == -1) {
		return -1;
	}
	do
	{
		string folderPath = filePath + (string(fileinfo.name)) + "/";
		cout <<"=======================================Now Processing====================================\n" <<folderPath << endl;
		string firstImage = folderPath + "2.png";
		string videoName = folderPath + (string(fileinfo.name)) + ".avi";
		string ImagePath = folderPath + "*.png";
		//cout << ImagePath << endl;
		int videoNum = GetDesignateFilesNumber(ImagePath);
		if (videoNum == -1) {
			continue;
		}
		else {
			videoNum = videoNum + 1;
		}
		//cout << videoNum << endl;
		ImageWriteVideo((folderPath.c_str()), (firstImage.c_str()), videoName,  videoNum);

	} while (!_findnext(handle, &fileinfo));

	_findclose(handle);

	return 1;
}
//// 描述:将视频帧转成视频输出
int main()
{
	//目标文件夹路径
	string filePath = "E:\project\test\";

	ImageWriteVideoBatch(filePath);

	system("pause");
	return 0;
}

3.工程

工程全部已经给在github-VideoProcess

4.参考

1.c++ 遍历文件夹中的文件

2.C++ 创建文件夹的四种方式

3.OpenCV|图片与视频的相互转换(C++&Python)

发布了24 篇原创文章 · 获赞 11 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_35975447/article/details/100130196
今日推荐