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

OpenCV重复播放摄像头视频,循环播放摄像头(视频)文件,循环播放视频中某一段视频

2014-12-02 14:44 501 查看
OpenCV中使用摄像头录像并保存并不难实现,本文针对摄像头实时帧画面进行记录,并重复播放

视频文件的读取和处理方法类似,首先,本文对摄像头进行采集和实时帧画面显示。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(){
VideoCapture vcap(0);
if(!vcap.isOpened()){
cout << "Error opening video stream or file" << endl;
return -1;
}
int frame_width = (int)vcap.get(CV_CAP_PROP_FRAME_WIDTH);
int frame_height = (int)vcap.get(CV_CAP_PROP_FRAME_HEIGHT);
VideoWriter video("out.avi",CV_FOURCC('M','J','P','G'),10, Size(frame_width,frame_height),true);
while (1)
{
Mat frame;
vcap >> frame;
video.write(frame);
imshow( "Frame", frame );
char c = (char)waitKey(33);
if( c == 27 ) break;
}
return 0;
}
具体不明白的细节请自行查找。。

接下来对记录的视频画面进行处理。

读取视频文件

本文实现的功能是,对一段实时画面中的某一个片段循环播放,并能够保证前后播放流畅。具体如下:

初次尝试:

固定视频中的某一帧。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(){
VideoCapture vcap("out.avi");
if(!vcap.isOpened()){
cout << "Error opening video stream or file" << endl;
return -1;
}
int frame_width = (int)vcap.get(CV_CAP_PROP_FRAME_WIDTH);
int frame_height = (int)vcap.get(CV_CAP_PROP_FRAME_HEIGHT);
int fps = vcap.get(CV_CAP_PROP_FPS);
int frame_size = vcap.get(CV_CAP_PROP_FRAME_COUNT);
cout<<frame_size<<endl;
int i = 0;
Mat frame;
while (vcap.read(frame))
{
if (frame.empty())break;
i++;
if (i == 100 )waitKey(10*1000);
imshow( "Frame", frame );
char c = (char)waitKey(33);
if( c == 27 ) break;
}
return 0;
}
本段代码实现将第一百帧延时10s,其他画面保持不变。

更进一步的说:

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                                                                      //
//        Edit by Call_Me_Yang  Date: 2014-12-02                        //
//                                                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(){
VideoCapture vcap("out.avi");                                  //建立VidepCapture结构,打开视频文件。
if(!vcap.isOpened()){                                          //打开视频文件
cout << "Error opening video stream or file" << endl;
return -1;
}
int frame_width = (int)vcap.get(CV_CAP_PROP_FRAME_WIDTH);
int frame_height = (int)vcap.get(CV_CAP_PROP_FRAME_HEIGHT);
int rate = vcap.get(CV_CAP_PROP_FPS);                           //视频的帧率
int frame_size = vcap.get(CV_CAP_PROP_FRAME_COUNT);            //视频的帧数
cout<<frame_size<<endl;
int i = 0;                                                     //计算当前的帧数
Mat frame;
while (vcap.read(frame))                                       //读取当前帧图像
{
if (frame.empty())break;                                   //判断当前帧是否为空,结束时自动跳出while循环
i++;                                                       //当前帧自动加一
if ( i < 100)                                              //前面100帧图像保持不变,顺序播放
{
imshow( "Frame", frame );
char c = (char)waitKey(33);
if( c == 27 ) break;
}
if (i == 100)                                              //第100帧时
{
for (int j = 0; j < 3; j++)                            //循环播放次数,这里循环播放3次
{
//vcap.release();
long frameToStart = 100;                           //设置开始帧
vcap.set( CV_CAP_PROP_POS_FRAMES,frameToStart);
cout<<"从第"<<frameToStart<<"帧开始读"<<endl;
int frameToStop = 200;                             //设置结束帧
if(frameToStop < frameToStart)
{
cout<<"结束帧小于开始帧,程序错误,即将退出!"<<endl;
return -1;
}
else
{
cout<<"结束帧为:第"<<frameToStop<<"帧"<<endl;
}
bool stop = false;                                 //定义一个用来控制读取视频循环结束的变量
Mat frame;                                         //承载每一帧的图像
int delay = 1000/rate;                             //两帧间的时间间隔
long currentFrame = frameToStart;                  //currentFrame是在循环体中控制读取到指定的帧后循环结束的变量
while(!stop)
{
if(!vcap.read(frame))                          //读取下一帧
{
cout<<"读取视频失败"<<endl;
break;
}
cv::imshow("Frame",frame);
cout<<"正在读取第"<<currentFrame<<"帧"<<endl;
int c = waitKey(delay);
if((char) c == 27 || currentFrame >= frameToStop)
{
stop = true;
}
if( waitKey(delay) >= 0)                     //按下按键后会停留在当前帧,等待下一次按键
{
waitKey(0);
}
currentFrame++;
}
}
}
if ( i >= 200 )
{
if(!vcap.isOpened()){                                          //打开视频文件
cout<<"fail to open!"<<endl;
return -1;
}

double rate = vcap.get(CV_CAP_PROP_FPS);                       //获取整个帧数
int delay = 1000/rate;
long frameToStart = 200;
vcap.set( CV_CAP_PROP_POS_FRAMES,frameToStart);
bool stop = false;
Mat frame;
while(!stop)
{
if(!vcap.read(frame))
{
cout<<"读取视频失败"<<endl;
break;
}
if (frame.empty())break;
imshow("Frame",frame);
int c = waitKey(delay);//waitKey(int delay=0)当delay ≤ 0时会永远等待;当delay>0时会等待delay毫秒
//当时间结束前没有按键按下时,返回值为-1;否则返回按键
if((char) c == 27 )    //按下ESC或者到达指定的结束帧后退出读取视频
{
stop = true;
}
if( c >= 0)            //按下按键后会停留在当前帧,等待下一次按键
{
waitKey(0);
}
}                         //while循环结束
}                             //if(i >= 200)循环结束

}                                 //while循环结束
return 0;
}
最后得到循环播放视频文件中的片段,并保持整个视频完整。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: