OpenCV长视频截短

OpenCV长视频截短

    • 1.opencv读取视频帧并保存
    • 2.opencv大量视频转为帧(c++)
    • 3.opencv多帧合成视频(c++)
    • 4.opencv多帧合成视频(python)
    • 5.opencv多帧合成定长视频(python)

为什么不用pr,剪映,PotPlayer呢?我手残,我不会
还有用这些去搞一条就15帧,1s不到的视频,真是杀鸡用牛刀

1.opencv读取视频帧并保存

将长视频打散成一帧一帧的

#include 
#include

using namespace std;
using namespace cv;

int main()
{
	VideoCapture capture("C:/Users/wwy/Desktop/test.mp4");//视频路径
	int i = 0;
	while (1)
	{
		i++;
		Mat img;
		capture >> img;
		if (img.empty()) {
			printf("播放完成\n");
			break;
		}
		imshow("res", img);//显示图片
		string ii = std::to_string(i);
		string path = "C:/Users/wwy/Desktop/111/" + ii+ ".jpg";//保存路径
		imwrite(path,img);
		waitKey(1);
	}

	waitKey(0);
	system("path");
	getchar();
	return 0;
}


2.opencv大量视频转为帧(c++)

由于才粗学浅,这程序没有很流畅,需要一直摁回车键才能一直运行



#include 
#include
#include 
#include 
#include 
#include 
#include 
#include
using namespace std;
using namespace cv;
void getAllFiles(string path, vector<string>& files);
typedef std::vector<std::string>  StringList;
StringList splitstr(const std::string& str, char tag);

int main()
{
	string DATA_DIR = "C:/Users/大喵喵/Desktop/input";//视频所在文件夹
	vector<string> files;
	//测试
	char * DistAll = (char*)"AllFiles.txt";
	getAllFiles(DATA_DIR, files);//所有文件与文件夹的路径都输出
	int size = files.size();
	int  FaiNum = 0;
	cout << size << endl;
	for (int k = 0; k < size; k++)
	{
		cout << files[k] << endl;
		vector<string> name;
		name = splitstr(files[k], '/');
		cout << name[name.size()-1] << endl;
		string imgsName= name[name.size() - 1].substr(0, name[name.size() - 1].length() - 4);
		cout << imgsName << endl;
		VideoCapture capture(files[k]);//视频路径
		int i = 0;
		while (1)
		{
			i++;
			Mat img;
			capture >> img;
			if (img.empty()) {
				printf("播放完成\n");
				break;
			}
			imshow("res", img);//显示图片
			string ii = std::to_string(i);
			string path = "C:/Users/大喵喵/Desktop/refFrames/"+imgsName + ii + ".jpg";//保存路径
			imwrite(path, img);
			waitKey(1);
		}
		system("path");
		getchar();
	}

	return 0;
}


void getAllFiles(string path, vector<string>& files)
{
	//文件句柄  
	intptr_t hFile = 0;
	//文件信息  
	struct _finddata_t fileinfo;  //很少用的文件信息读取结构
	string p;  //string类很有意思的一个赋值函数:assign(),有很多重载版本
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
		do
		{
			if ((fileinfo.attrib &  _A_SUBDIR))  //判断是否为文件夹
			{
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
				{
					files.push_back(p.assign(path).append("/").append(fileinfo.name));//保存文件夹名字
					getAllFiles(p.assign(path).append("/").append(fileinfo.name), files);//递归当前文件夹
				}
			}
			else    //文件处理
			{
				files.push_back(p.assign(path).append("/").append(fileinfo.name));//文件名
			}
		} while (_findnext(hFile, &fileinfo) == 0);  //寻找下一个,成功返回0,否则-1
		_findclose(hFile);
	}
}



/*
分割字符串
*/
StringList splitstr(const std::string& str, char tag)
{
	StringList  li;
	std::string subStr;

	//遍历字符串,同时将i位置的字符放入到子串中,当遇到tag(需要切割的字符时)完成一次切割
	//遍历结束之后即可得到切割后的字符串数组
	for (size_t i = 0; i < str.length(); i++)
	{
		if (tag == str[i]) //完成一次切割
		{
			if (!subStr.empty())
			{
				li.push_back(subStr);
				subStr.clear();
			}
		}
		else //将i位置的字符放入子串
		{
			subStr.push_back(str[i]);
		}
	}

	if (!subStr.empty()) //剩余的子串作为最后的子字符串
	{
		li.push_back(subStr);
	}

	return li;
}

3.opencv多帧合成视频(c++)

把图片合成视频,图片放在文件夹里面,命名格式应该为:1.jpg,2.jpg,3.jpg…
目前只有MP4格式成功了,其他的没有试

// TestForOnlyC++.cpp : 定义控制台应用程序的入口点。
//

/*
为了保证视频帧顺序,对图片命名要有顺序逻辑,对于本代码,图片命名格式需要为1.jpg、2.jpg...
*/

#include 
#include 
#include 
#include 
#include 
#include
#include 

using namespace std;
using namespace cv;
void getAllFiles(string path, vector<string>& files);
//测试
int main()
{
	int frames = 15;//一条视频多少帧
	string DATA_DIR = "C:/Users/wwy/Desktop/111/";//图片所在文件夹

	vector<string> files;
	char * DistAll = (char*)"AllFiles.txt";
	getAllFiles(DATA_DIR, files);//所有文件与文件夹的路径都输出
	int size = files.size();
	cout << "图片一共"<<size <<"张"<< endl;
	int videoNum = size / frames;
	int MaxFrame = videoNum * (frames-1);
	cout << "可以制作" << videoNum << "条视频" << endl;
	
	int video_wight = 480;
	int video_hight = 320;
	


	for (int i = 1; i < videoNum + 1; i++) {
		cv::VideoWriter Writer;
		string i_string= to_string(i);
		string filepath = "C:/Users/wwy/Desktop/111/1/"+i_string+".mp4";
		Writer.open(filepath, VideoWriter::fourcc('M', 'P', '4', '2'), 25, Size(video_wight, video_hight), 1);
		if (!Writer.isOpened())
		{
			cout << "无法保存视频" << endl;
		}
		else {
			for (int cou = frames*i-(frames-1); cou < frames * i+1&& MaxFrame; cou++)
			{
				string ii = to_string(cou);
				string path = DATA_DIR + ii + ".jpg";
				Mat src = imread(path);
				resize(src, src, Size(video_wight, video_hight), 0, 0, INTER_LINEAR);
				//imshow("res", src);//显示图片
				cout << path << endl;
				Writer.write(src);//输出视频
			}
			cout << "保存成功" << endl;
		}
		Writer.release();
	}
	waitKey(0);
	return 0;
}

void getAllFiles(string path, vector<string>& files)
{
	//文件句柄  
	intptr_t hFile = 0;
	//文件信息  
	struct _finddata_t fileinfo;  //很少用的文件信息读取结构
	string p;  //string类很有意思的一个赋值函数:assign(),有很多重载版本
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
		do
		{
			if ((fileinfo.attrib &  _A_SUBDIR))  //判断是否为文件夹
			{
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
				{
					files.push_back(p.assign(path).append("/").append(fileinfo.name));//保存文件夹名字
					getAllFiles(p.assign(path).append("/").append(fileinfo.name), files);//递归当前文件夹
				}
			}
			else    //文件处理
			{
				files.push_back(p.assign(path).append("/").append(fileinfo.name));//文件名
			}
		} while (_findnext(hFile, &fileinfo) == 0);  //寻找下一个,成功返回0,否则-1
		_findclose(hFile);
	}
}

4.opencv多帧合成视频(python)

import cv2
import os


def images_to_video():
    fps = 25  # 帧率
    num_frames = 500
    img_array = []
    img_width = 320 #一定要根据自己图片进行更改
    img_height = 240
    path = "/home/user/WWY/results/test_results0/test/"
    imglist = os.listdir(path)
    print(imglist)
    imglist.sort(key=lambda x: int(x[0:-4]))
    print(imglist)
    #imgt=cv2.imread("/home/user/WWY/results/test_results0/test/8.png")
    #cv2.imshow("1",imgt)
    #cv2.waitKey(0)
    for file_name in os.listdir(path):
        img = cv2.imread(path + file_name)
        dim=(img_width,img_height)
        resized=cv2.resize(img,dim,interpolation=cv2.INTER_AREA)
        print(path + file_name)
        if img is None:
            print(file_name + " is non-existent!")
            continue
        img_array.append(resized)

    out = cv2.VideoWriter('demo_1.avi', cv2.VideoWriter_fourcc(*'XVID'), fps, (img_width, img_height))
    #out = cv2.VideoWriter('demo_people.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (img_width, img_height))

    for i in range(len(img_array)):
        out.write(img_array[i])
    out.release()


def main():
    images_to_video()


if __name__ == "__main__":
    main()


5.opencv多帧合成定长视频(python)

import cv2
import os
import natsort

def images_to_video():
    fps = 25  # 帧率
    num_frames = 15
    img_array = []
    img_width = 960
    img_height = 540
    path = "C:/Users/wwy/Desktop/TSRWGAN/mydata/imgs/"


   
    names = natsort.natsorted(os.listdir(path),alg = natsort.ns.PATH)
    #print(names)
    for file_name in names:
    	#print(name)
    #for file_name in os.listdir(path):
        img = cv2.imread(path + file_name)

        dim=(img_width,img_height)
        resized=cv2.resize(img,dim,interpolation=cv2.INTER_AREA)
        if img is None:
            print(file_name + " is non-existent!")
            continue
        img_array.append(resized)


    #out = cv2.VideoWriter('demo_people.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (img_width, img_height))
    video_num = int(len(names) / num_frames )
    k = 0;
    for w in range(1,video_num):
        out = cv2.VideoWriter("C:/Users/wwy/Desktop/TSRWGAN/mydata/video15fs/"+str(w)+'.avi', cv2.VideoWriter_fourcc(*'XVID'), fps, (img_width, img_height))
        for i in range(k,k+num_frames):
            out.write(img_array[i])
        out.release()
        k = k+num_frames
        print(k)

def main():
    images_to_video()


if __name__ == "__main__":
    main()








你可能感兴趣的:(opencv,学习)