细说opencv中的HIGHGUI结构(二)

     上篇我们说到HIGHGUI的一些基本应用,本文主要讲HIGHGUI对视频读取与写入的处理.由于opencv现在大部分已经由c++改写,我主要介绍c++下的一些函数
VideoCapture类
VideoCapture从视频文件或摄像机中扑捉视频信息,提供c++API借口。先来简单的熟悉下吧。
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    //VideoCapture cap("g:\\1.avi");
    if(!cap.isOpened())  // check if we succeeded
        return -1;
    Mat edges;
    namedWindow("edges",1);
    for(;;)
    {
        Mat frame;
        cap >> frame; // get a new frame from camera
        cvtColor(frame, edges, CV_BGR2GRAY);
        GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
        Canny(edges, edges, 0, 30, 3);
        imshow("edges", edges);
        if(waitKey(30) >= 0) break;
    }
    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;

1 VideoCapture::VideoCapture     (VideoCapture  构造函数  )
      
VideoCapture::VideoCapture()
VideoCapture::VideoCapture(const string & filename)
VideoCapture::VideoCapture(int device)
参数解释:
           filename: 要打开的视频文件或者图像序列(比如:img_%02d.jpg,img_%03d.jpg.....)
           device  : 捕捉视频设备的ID号,如果只有一个相机时,输入0

2 VideoCapture::open
打开视频文件或者视频设备(比如摄像机)
         bool VideoCapture::open(const string & filename)
         bool VideoCapture::open(int device)
参数含义见上面
3 VideoCapture::isOpened
如果捕捉视频成功即返回true
         bool VideoCapture::isOpened()
4 VideoCapture::release
关闭视频文件和关闭视频设备
        void VideoCapture::release() 
该方法会自动被VideoCapture::open()和构造函数调用
5 VideoCapture:;grab
获视频文件或视频设备的下一帧,如果成功就返回true。该函数将视频文件复制到了一个用户看不到的空间,获取的视频并没有经过处理。这样做的目的是为了快速将视频读入内存。
             bool VideoCapture::grab()
6 VideoCapture::retrieve
解码工作并返回grab()读入的帧,实际上就是从内存中独处视频的帧图像。如果没有frame被grab(),返回false
         bool VideoCapture::retrieve(Mat &image,int channel=0)
7 VideoCapture::read
捕获,解码,返回下一帧,是grab(),retrieve()的功能和。如果没有帧被获取,返回false
        VideoCapture & VideoCapture::operator >> (Mat &image)
        bool VideoCapture::read(Mat &image)
8 VideoCapture::get
返回特定的视频属性,如果没有支持的属性,返回0
        double VideoCapture::get(int propId)
参数propId可以有以下属性
 
 
propId属性
CV_CAP_PROP_POS_MSEC值为0,指向视频的当前位置,以毫秒为单位
CV_CAP_PROP_POS_FRAMES值为1,以帧为单位的当前位置
CV_CAP_PROP_POS_AVI_RATIO 值为2,视频文件的相对位置:0代表视频开始,1代表视频结束
CV_CAP_PROP_FRAME_WIDTH 值为3,当前读取帧的宽度
CV_CAP_PROP_FRAME_HEIGHT 值为4,当前读取帧的高度
CV_CAP_PROP_FPS 值为5,记录了视频录入时每秒的帧数,实际上就是帧率
CV_CAP_PROP_FOURCC 值为6,由四个字节组成,表示视频文件的压缩方法
CV_CAP_PROP_FRAME_COUNT 视频文件的总帧数
 
当然,还有一些其他的属性,这里就不都写了,不过表格里的属性是经常用到的。
8  VideoCapture::set
设置视频属性
       bool VideoCapture::set(int propId,double value)
 参数解释:propId:见上面表格,
           value :对应属性的值

好的,VideoCapture类基本介绍完了,下面开始介绍VideoWriter类。

VideoWriter 写入视频类

1 VideoWriter::VidoeWriter   类构造函数
        VideoWriter::VideoWriter()
        VideoWriter::VideoWriter(const string &filename,int fourcc,double fps,Size farmeSize,bool isColor=true)
参数解释:
        finename: 输出的文件名
        fourcc  : 四个字节的视频文件压缩方法,比如,CV_FOURCC('P','I','M','L'),CV_FOURCC('M','P','E','G')
        fps     : 要创建视频流的帧率
        frameSize:视频帧的大小
        isColor:  如果为非0,编码器将要解码为颜色帧,否则为灰度帧
2 VideoWriter::open
初始化video writer
        bool VideoWriter::open(const string &filename,int fourcc,double fps,Size frameSize,bool isColor=true)
类似构造函数
3 VideoWriter::isOpened
如果videowriter成功被初始化,返回true,否则返回0
        bool VideoWriter::isOpened()
4 videoWriter::write
写入视频的下一帧给视频文件,所有的帧务必有相同的大小。
        VideoWriter &VideoWriter::operator <<(const Mat & image)
        void VideoWriter::write(const Mat & image)
参数解释:
        image:被写入的帧




视频读取与写入就这些内容了,下面练习下吧。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
	//打开视频文件:其实就是建立一个VideoCapture结构
	VideoCapture capture("D:/videos/PetsD2TeC2.avi");
	//检测是否正常打开:成功打开时,isOpened返回ture
	if(!capture.isOpened())
		cout<<"fail to open!"<<endl;
	//获取整个帧数
	long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
	cout<<"整个视频共"<<totalFrameNumber<<"帧"<<endl;


	//设置开始帧()
	long frameToStart = 300;
	capture.set( CV_CAP_PROP_POS_FRAMES,frameToStart);
	cout<<"从第"<<frameToStart<<"帧开始读"<<endl;


	//设置结束帧
	int frameToStop = 400;

	if(frameToStop < frameToStart)
	{
		cout<<"结束帧小于开始帧,程序错误,即将退出!"<<endl;
		return -1;
	}
	else
	{
		cout<<"结束帧为:第"<<frameToStop<<"帧"<<endl;
	}


	//获取帧率
	double rate = capture.get(CV_CAP_PROP_FPS);
	cout<<"帧率为:"<<rate<<endl;



	//定义一个用来控制读取视频循环结束的变量
	bool stop = false;
	//承载每一帧的图像
	Mat frame;
	//显示每一帧的窗口
	namedWindow("Extracted frame");
	//两帧间的间隔时间:
	//int delay = 1000/rate;
	int delay = 1000/rate;


	//利用while循环读取帧
	//currentFrame是在循环体中控制读取到指定的帧后循环结束的变量
	long currentFrame = frameToStart;


	//滤波器的核
	int kernel_size = 3;
	Mat kernel = Mat::ones(kernel_size,kernel_size,CV_32F)/(float)(kernel_size*kernel_size);

	while(!stop)
	{
		//读取下一帧
		if(!capture.read(frame))
		{
			cout<<"读取视频失败"<<endl;
			return -1;	
		}
		
		//这里加滤波程序
		imshow("Extracted frame",frame);
		filter2D(frame,frame,-1,kernel);

		imshow("after filter",frame);
		cout<<"正在读取第"<<currentFrame<<"帧"<<endl;
		//waitKey(int delay=0)当delay ≤ 0时会永远等待;当delay>0时会等待delay毫秒
		//当时间结束前没有按键按下时,返回值为-1;否则返回按键


		int c = waitKey(delay);
		//按下ESC或者到达指定的结束帧后退出读取视频
		if((char) c == 27 || currentFrame > frameToStop)
		{
			stop = true;
		}
		//按下按键后会停留在当前帧,等待下一次按键
		if( c >= 0)
		{
			waitKey(0);
		}
		currentFrame++;
	
	}
	//关闭视频文件
	capture.release();
	waitKey(0);
	return 0;
}
再来一个写入视频的,
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
	VideoCapture capture;
	capture.open("g:\\1.avi");
	if(!capture.isOpened())
	{
		cout << "打开视频失败!";
		return 0;
	}
	int FPS=capture.get(CV_CAP_PROP_FPS);
	cout << "帧率为:" << FPS<<endl;
	int count =capture.get(CV_CAP_PROP_FRAME_COUNT);
	cout << "总帧数为:"  << count << endl;
	int width=capture.get(CV_CAP_PROP_FRAME_WIDTH);
	int height=capture.get(CV_CAP_PROP_FRAME_HEIGHT);
	Size size(width,height);
	int framestart=100,framestop=300;
	//设置开始帧
	capture.set(CV_CAP_PROP_POS_FRAMES,framestart);

	Mat frame;
	namedWindow("yuan");
	VideoWriter writer;
	writer.open("g:\\jingwei.avi",CV_FOURCC('M','P','E','G'),FPS,size);
	while(1)
	{
		if(capture.get(CV_CAP_PROP_POS_FRAMES)>framestop)
		{
			break;
		}
		capture >>frame;
		imshow("yuan",frame);
		writer <<frame;
		waitKey(1000/FPS);
	}
	capture.release();
	return 0;
}


好的,今天内容就到这里,下次再见哦!
 
 
 

                
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值