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

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;
}
最后得到循环播放视频文件中的片段,并保持整个视频完整。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值