用c++程序裁剪视频区域并提取每帧保存为图片

在学习中遇到一个问题,需要在视频上画个矩形框, 把矩形框的内容每帧都保存成图片。之前的程序是师兄给我的,有些bug,而且是鼠标画框。这就导致了在批量处理视频时无能为力,不好控制每张图片的大小。我改进了程序,更符合我的需求。
环境:WIN10;VS2013;OpenCV库。
去掉了鼠标事件处理程序,去掉了视频显示的窗口。
处理n个视频。box.width ;box.height;box.x;box.y设定矩形框的位置和大小, path设置视频文件夹路径,v设置视频名称,for循环来处理n个视频,stringstream用来将int转为string,g=10间隔十帧,保存在以视频编号来命名的文件夹中。

#include "stdafx.h"
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include "cv.h"
#include <cvaux.h>
#include "cxcore.h"
#include <io.h>
#include<math.h>
#include <vector>
#include<algorithm>
#include <windows.h>
#include<fstream>
#include <direct.h>

using namespace std;
using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
{
	Rect box;           //定义长方形区域
	box.width = 480;
	box.height = 484;
	box.x = 0;
	box.y = 0;
	int g = 10;//间隔帧数
	//我这里批量处理27个视频,所以j=28
	for (int j = 1; j < 28; j++)
	{
         //这里加入视频文件夹路径,注意是"\\"间隔,不是”\“
		string path = "E:\\xx\\xx\\";
		// 获取视频文件
		std::stringstream ss;
		std::string k;
		ss << j;
		ss >> k;
		//视频完整路径,我这里是*.mp4,k表示视频名字,以数字
		string v = path + k + ".MP4";
		cout<<v<<endl;
		
		//输出文件夹
		string out_path;
		out_path=path+k;
		if (0 != access(out_path.c_str(), 0))
			{
				// if this folder not exist, create a new one.
				mkdir(out_path.c_str());   // 返回 0 表示创建成功,-1 表示失败
			}


		VideoCapture cap(v);
		// 获取视频总帧数
		long totalFrameNumber = cap.get(CV_CAP_PROP_FRAME_COUNT);
		cout << "total frames: " << totalFrameNumber << endl;

		Mat frame;
		bool flags = true;
		long currentFrame = 0;
		
		long i = 0;
		//namedWindow("video", 0);
		//cvResizeWindow("video", 1440, 810);
		
		while (flags){
			// 读取视频每一帧
			cap.read(frame);

			rectangle(frame, box, Scalar(255, 255, 0), 2);
			//imshow("video", frame);
			//if (waitKey(33) == 'q')
				//break;

			
			if (frame.empty())//读取失败时
			{
				cout << "Could not open or find the image" << std::endl;
				return -1;
			}
			frame = frame(Rect(box));
			stringstream str;
			//str << "endoscope" << currentFrame << ".jpg";
			cout << "正在处理第" << currentFrame << "帧" << endl;
			printf("\n");

			// 设置每10帧获取一次帧,可以自己修改的
			if (currentFrame % g == 0){
				// 将帧转成图片输出,命名格式00000-99999,存放在每个视频文件夹,视频文件夹以数字命名
				i++;
				str << cv::format("%05d", i) << ".jpg";
				imwrite(out_path +"\\"+ str.str(), frame);
			}
			// 结束条件
			if (currentFrame >= totalFrameNumber || i>=totalFrameNumber / g){
				flags = false;
			}
			currentFrame++;
		}
		cvWaitKey();
		//cvDestroyWindow("video");
		frame.release();
	}
	system("pause");
	
	return 0;
}


  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你写一个基于OpenCVC++程序,用于提取每隔4帧的视频帧。 首先,你需要在Ubuntu系统上安装OpenCV库,可以使用以下命令进行安装: ``` sudo apt-get install libopencv-dev ``` 安装完成后,你可以创建一个新的C++文件,例如"video_capture.cpp",并在其中添加以下代码: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { // 打开视频文件 VideoCapture cap(argv[1]); if (!cap.isOpened()) { cerr << "Error opening video file" << endl; return -1; } int frame_count = 0; Mat frame; // 循环读取视频帧 while (cap.read(frame)) { frame_count++; // 每隔4帧提取一帧 if (frame_count % 4 == 0) { // 显示帧数 cout << "Extracted frame " << frame_count << endl; // 处理视频帧 // ... // 显示视频帧 imshow("Frame", frame); waitKey(0); } } // 释放视频文件 cap.release(); destroyAllWindows(); return 0; } ``` 在上面的代码中,我们首先打开视频文件并检查是否成功打开。然后,我们使用循环读取视频帧,并使用模运算符每隔4帧提取一帧。你可以在其中添加你自己的处理代码。最后,我们释放视频文件并关闭所有窗口。 在编译时,你需要链接OpenCV库,可以使用以下命令进行编译: ``` g++ video_capture.cpp -o video_capture `pkg-config --cflags --libs opencv` ``` 其中,`pkg-config --cflags --libs opencv`命令用于获取OpenCV库的编译选项。 最后,你可以使用以下命令运行程序,并传入视频文件的路径作为参数: ``` ./video_capture video_file.mp4 ``` 程序提取每隔4帧的视频帧,并显示在窗口中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值