您的位置:首页 > 运维架构

视频流读取与视频帧处理

2013-12-20 21:00 302 查看

背景引言

视频信号是视觉信息的一个主要源头,它由按序列排放的图像组成,即帧(Frame)。本节主要介绍视频读取和对视频帧处理知识。

读取视频序列

为了处理视频序列,需要读取每一Frame.用c++类封装VideoProcessor类视频读取处理的代码:
class VideoProcessor{
private:
VideoCapture caputure; //The OpenCV Video capture object

void (*process)(Mat &,Mat &); // the callback function to be called for the
// processing of each frame
bool callIt;

string WindowNameInput; //Input display windnow name
string WindowNameOutput; //Output display window name

int delay;
long fnumber; // number of processed frames

long frameToStop; // stop at this frame number
bool stop;
public:
VideoProcessor() : callIt(true),delay(0),fnumber(0),stop(false),frameToStop(-1){}
void setFrameProcess(void (*process)(Mat &,Mat &)){
this->process = process;
}

bool setInput(string filename){
fnumber = 0;

caputure.release ();
return caputure.open (filename);
}

void displayInput(string wn){
WindowNameInput = wn;
namedWindow (WindowNameInput);
}

void displayOutput(string wn){
WindowNameOutput = wn;
namedWindow (WindowNameOutput);
}

void dontDisplay(){
destroyWindow (WindowNameInput);
destroyWindow (WindowNameOutput);
WindowNameInput.clear ();
WindowNameOutput.clear ();
}

void run(){
Mat frame;
Mat output;
if(!isOpened()) return;
stop = false;
while(!isStopped()){
if(!readNextFrame(frame)) break;
if(WindowNameInput.length ()!=0) imshow (WindowNameInput,frame);

if(callIt) process(frame,output);
else output = frame;
if(WindowNameOutput.length ()!=0) imshow (WindowNameOutput,output);

if(delay>=0&&waitKey (delay)>=0) waitKey(0);

if(frameToStop>=0&&getFrameNumber()==frameToStop) stopIt();
}
}

void stopIt(){
stop = true;
}

bool isStopped(){
return stop;
}

bool isOpened(){
return caputure.isOpened ();
}

void setDelay(int d){
delay = d;
}

bool readNextFrame(Mat &frame){
return caputure.read (frame);
}

void CallProcess(){
callIt = true;
}
void dontCallProcess(){
callIt = false;
}

void stopAtFrameNo(long frame){
frameToStop = frame;
}

long getFrameNumber(){
long fnumber = static_cast<long>(caputure.get ((CV_CAP_PROP_POS_FRAMES)));
return fnumber;
}

double getFrameRate(){
return caputure.get(CV_CAP_PROP_FPS);
}
};
目前,OpenCV2.x中用于操作video文件的类基于ffmpeg.所以,无需像OpenCV1.x那样安装第三方解码软件转换器,才能读取视频信息。

处理视频帧

处理视频帧主要是对于每个视频帧都应用一些处理函数。将自己的类中封装OpenCV的视频获取框架,同时可以指定每帧调用函数。作为一个视频帧处理函数,如:canny函数计算输入图像的Canny边缘。代码如下所示:
void canny(cv::Mat& img, cv::Mat& out) {
if (img.channels()==3)
cvtColor(img,out,CV_BGR2GRAY);
Canny(out,out,100,200);
threshold(out,out,128,255,cv::THRESH_BINARY_INV);
}接着,定义一个video处理类,将与一个回调函数相关联。使用此类,将创建一个实例并指定输入的video文件,绑定回调函数,然后开始处理过程。代码如下所示:

VideoProcessor processor;
processor.setInput ("test.avi");
processor.displayInput ("Input Video");
processor.displayOutput ("Output Video");
processor.setDelay (2000./processor.getFrameRate ());

processor.setFrameProcess (canny );
processor.run ();实验结果,当输入视频的一帧,对应的输出帧如图所示:



参考资料

[1] Robert Laganière, " OpenCV 2 Computer Vision Application Programming Cookbook" ,Packt Publishing 2011.

关于Image Engineering & Computer Vision的更多讨论与交流,敬请关注本博和新浪微博songzi_tea.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息