可直接使用:
bool CapPic(string fileName, long start, long end)
{
_mkdir("D:\\workspace\\capPic\\20170504_A");//建立文件夹
//打开视频文件:其实就是建立一个VideoCapture结构
VideoCapture capture("fileName");
//检测是否正常打开:成功打开时,isOpened返回ture
if (!capture.isOpened())
{
cout << "fail to open!";
return false;
}
//获取整个帧数
long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
cout << "整个视频共" << totalFrameNumber << "帧" << endl;
//设置开始帧()
long frameToStart = start; //1;
size_t frameToEnd = end; //totalFrameNumber;
//只要奇数帧
if (frameToStart % 2 == 0)
{
frameToStart++;
}
if (frameToEnd % 2 == 0)
{
frameToEnd--;
}
//Sets a property in the VideoCapture:0-based index of the frame to be decoded/captured next.
capture.set(CV_CAP_PROP_POS_FRAMES, frameToStart);
cout << "从第" << frameToStart << "帧开始读" << endl;
cout << "第" << frameToEnd << "帧结束" << endl;
//获取帧率:Returns the specified VideoCapture property.
//帧率:一秒多少帧
double rate = capture.get(CV_CAP_PROP_FPS);
cout << "帧率为:" << rate << endl;
//定义一个用来控制读取视频循环结束的变量
bool stop = false;
//承载每一帧的图像
Mat frame;
//显示每一帧的窗口
//namedWindow("Extractedframe");
//两帧间的间隔时间:ms
//int delay = 1000/rate;
double delay = 1000 / rate;
//利用while循环读取帧
//currentFrame是在循环体中控制读取到指定的帧后循环结束的变量
long currentFrame = frameToStart;
while (currentFrame <= frameToEnd)
{
//读取下一帧
if (!capture.read(frame))
{
cout << "读取视频失败" << endl;
return false;
}
//cout << "正在写第" << currentFrame << "帧" << endl;
stringstream str;
str << "./20170504_A/" << currentFrame << ".jpg";
//cout << str.str() << endl;
Mat roi = frame(Rect(1040, 200, 880, 880)); //get region of interesting
imwrite(str.str(), roi);
currentFrame += 2;
capture.read(frame);//奇数帧呢,空流
}
//关闭视频文件
capture.release();
cout << "Done!" << endl;
}
完整程序:获取某一帧到另外一帧的所有图片,并存在对应的文件夹内,图片以帧,jpg命名,可在vs2015下运行:
涉及文件的读取,stringstream、string、const char*之间的转换、目录的建立等等,值得阅读。
#include <iostream>
#include <cstdlib>
#include <direct.h>
#include "opencv2/opencv.hpp"
#include <Windows.h>
#include <string>
#include <sstream>//stringstream
using namespace std;
using namespace cv;
bool CapPic(string fileName, long start, long end);
vector<vector<int>> ReadFile(string dataFile);
int main(int argc, char * argv[])
{
string fileName = "D:\\workspace\\capPic\\20170504_A.MP4";
string dataFile = "test.txt";
vector<vector<int>> range = ReadFile(dataFile);
int n = range.size();
for (int i = 0; i < n; i++)
{
CapPic(fileName, range[i][0], range[i][1]);
}
return 0;
}
bool CapPic(string fileName, long start, long end)
{
_mkdir("D:\\workspace\\capPic\\20170504_A");//建立文件夹
//打开视频文件:其实就是建立一个VideoCapture结构
VideoCapture capture(fileName);
//检测是否正常打开:成功打开时,isOpened返回ture
if (!capture.isOpened())
{
cout << "fail to open!";
return false;
}
//获取整个帧数
long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
cout << "整个视频共" << totalFrameNumber << "帧" << endl;
//设置开始帧()
long frameToStart = start; //1;
size_t frameToEnd = end; //totalFrameNumber;
//只要奇数帧
if (frameToStart % 2 == 0)
{
frameToStart++;
}
if (frameToEnd % 2 == 0)
{
frameToEnd--;
}
//Sets a property in the VideoCapture:0-based index of the frame to be decoded/captured next.
capture.set(CV_CAP_PROP_POS_FRAMES, frameToStart);
cout << "从第" << frameToStart << "帧开始读" << endl;
cout << "第" << frameToEnd << "帧结束" << endl;
//获取帧率:Returns the specified VideoCapture property.
//帧率:一秒多少帧
double rate = capture.get(CV_CAP_PROP_FPS);
cout << "帧率为:" << rate << endl;
//定义一个用来控制读取视频循环结束的变量
bool stop = false;
//承载每一帧的图像
Mat frame;
//显示每一帧的窗口
//namedWindow("Extractedframe");
//两帧间的间隔时间:ms
//int delay = 1000/rate;
double delay = 1000 / rate;
//利用while循环读取帧
//currentFrame是在循环体中控制读取到指定的帧后循环结束的变量
long currentFrame = frameToStart;
while (currentFrame <= frameToEnd)
{
//读取下一帧
if (!capture.read(frame))
{
cout << "读取视频失败" << endl;
return false;
}
//cout << "正在写第" << currentFrame << "帧" << endl;
stringstream dirStr;
dirStr << "D:\\workspace\\capPic\\20170504_A\\" << frameToStart << "_" << frameToEnd;
string dirStrTmp = dirStr.str();
const char* constDirStr = dirStrTmp.c_str();//string转为const char*
_mkdir(constDirStr);
stringstream str;
str << dirStrTmp << "\\" << currentFrame << ".jpg";
string picName = str.str();
//cout << str.str() << endl;
Mat roi = frame(Rect(1040, 200, 880, 880)); //get region of interesting
imwrite(str.str(), roi);
currentFrame += 2;
capture.read(frame);空流,不存
}
//关闭视频文件
capture.release();
cout << "Done!" << endl;
}
vector<vector<int>> ReadFile(string dataFile)
{
vector<vector<int>> outData;
vector<int> oneRowData;
ifstream inFile;
inFile.open(dataFile, ios::in);
if (!inFile.is_open())
{
cout << "Error open file" << endl;
}
while (!inFile.eof())
{
string buffTmp;
int nTmp = 0;
while (getline(inFile, buffTmp))
{
stringstream stringIn(buffTmp);//使用串流实现对string的输入输出操作
oneRowData.clear();
while (stringIn >> nTmp)
{
oneRowData.push_back(nTmp);
}
outData.push_back(oneRowData);
}
}
return outData;
}