在学习中遇到一个问题,需要在视频上画个矩形框, 把矩形框的内容每帧都保存成图片。之前的程序是师兄给我的,有些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;
}