OpenCV视频解单帧例子
主要利用VideoCapture类。
/*
* 视频解单帧
*/
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int trackbarPosition;
VideoCapture capture;
bool isFileExist(const char *filePath)
{
if (filePath == NULL)
return false;
else if (access(filePath, F_OK) == 0)
return true;
else
return false;
}
bool isDirExist(const char *dirPath)
{
if (dirPath == NULL || opendir(dirPath) == NULL)
return false;
else
return true;
}
void setFramePosition(int position, void *)
{
capture.set(CV_CAP_PROP_POS_FRAMES, position);
trackbarPosition = position;
}
int main()
{
const string videoName = "/home/corfox/Data/GOPR0451_removefisheye.mp4";
const string outputPath = "/home/corfox/Data/GOPR";
int frameNum = 1;
ostringstream numToStr;
string frameName;
Mat frame;
double frameScale = 0.5; // 视频缩放因子
capture.open(videoName);
if (!capture.isOpened())
return 1;
const string windowName = "uncompress video";
const string trackbarName = "position";
namedWindow(windowName);
int frameNums = capture.get(CV_CAP_PROP_FRAME_COUNT);
if (frameNums >= 0)
createTrackbar(trackbarName, windowName, &trackbarPosition, frameNums, setFramePosition);
bool stop = false;
int selectIndex = -1;
int subDirName = 1; // 创建的子文件夹名
int flag;
int frameWidth = capture.get(CV_CAP_PROP_FRAME_WIDTH) * frameScale;
int frameHight = capture.get(CV_CAP_PROP_FRAME_HEIGHT) * frameScale;
while(!stop)
{
if (!capture.read(frame))
break;
resize(frame, frame, Size(frameWidth, frameHight));
trackbarPosition++;
setTrackbarPos(trackbarName, windowName, trackbarPosition);
imshow(windowName, frame);
flag = waitKey(10);
if (flag == 27) // ESC
stop = true;
else if (flag == 115 || flag == 83) // 's' or 'S'
{
selectIndex = 0;
cout << "You pressed the key of 's' to save frame." << endl;
}
else if (flag == 101 || flag == 69) // 'e' or 'E'
{
selectIndex = 1;
cout << "You pressed the key of 'e' to stop saving frame." << endl;
}
else if (flag == 109 || flag == 77) // 'm' or 'M', to mkdir
{
string dirName;
numToStr << outputPath << "/" << subDirName;
dirName = numToStr.str();
if (!isDirExist(dirName.c_str()))
{
dirName = "mkdir " + dirName;
system(dirName.c_str());
}
frameNum = 1;
subDirName++;
numToStr.str("");
cout << "You pressed the key of 'm' to make a directory named the incremental digit number (1, 2, ...)." << endl;
}
switch (selectIndex) {
case 0:
numToStr << outputPath << "/" << (subDirName - 1) << "/" << frameNum << ".jpg";
frameName = numToStr.str();
frameNum++;
imwrite(frameName, frame);
numToStr.str("");
frameName.clear();
break;
case 1:
selectIndex = -1;
break;
default:
break;
}
frame.release();
}
capture.release();
return 0;
}