opencv(2)---摄像头/视频读取_写入

VideoCapture类用于处理摄像头/视频读取_写入操作。

一 基本概念

VideoCapture

1.VideoCapture有三种构造方法

 /** @brief
    @note In C API, when you finished working with video, release CvCapture structure with
    cvReleaseCapture(), or use Ptr\<CvCapture\> that calls cvReleaseCapture() automatically in the
    destructor.
     */
    CV_WRAP VideoCapture();

    /** @overload
    @param filename name of the opened video file (eg. video.avi) or image sequence (eg.
    img_%02d.jpg, which will read samples like img_00.jpg, img_01.jpg, img_02.jpg, ...)
    */
    CV_WRAP VideoCapture(const String& filename);

    /** @overload
    @param filename name of the opened video file (eg. video.avi) or image sequence (eg.
    img_%02d.jpg, which will read samples like img_00.jpg, img_01.jpg, img_02.jpg, ...)

    @param apiPreference preferred Capture API to use. Can be used to enforce a specific reader
    implementation if multiple are available: e.g. CAP_FFMPEG or CAP_IMAGES
    */
    CV_WRAP VideoCapture(const String& filename, int apiPreference);
   /** @overload
    @param index = camera_id + domain_offset (CAP_*). id of the video capturing device to open. If there is a single
    camera connected, just pass 0. Advanced Usage: to open Camera 1 using the MS Media Foundation API: index = 1 + CAP_MSMF
    */
    CV_WRAP VideoCapture(int index);

2.两种取帧方法

   virtual VideoCapture& operator >> (CV_OUT Mat& image);

    CV_WRAP virtual bool read(OutputArray image);

3.常用函数

这里写图片描述
功能介绍:
1)open()—打开视频文件或者摄像头
2)isOpened()–判断读取视频文件是否正确,正确返回true
3)release()—关闭视频流文件
4)grab()—抓取下一帧的视频文件或设备
5)Retrieve()—解码并返回视频帧
6)get()—返回指定视频类的相关参数信息
7)set()—设置类信息的一个属性
4.视频文件的属性
cap.get(…)

   /** @brief Returns the specified VideoCapture property

    @param propId Property identifier. It can be one of the following:
     -   **CAP_PROP_POS_MSEC** Current position of the video file in milliseconds or video
         capture timestamp.
     -   **CAP_PROP_POS_FRAMES** 0-based index of the frame to be decoded/captured next.
     -   **CAP_PROP_POS_AVI_RATIO** Relative position of the video file: 0 - start of the
         film, 1 - end of the film.
     -   **CAP_PROP_FRAME_WIDTH** Width of the frames in the video stream.
     -   **CAP_PROP_FRAME_HEIGHT** Height of the frames in the video stream.
     -   **CAP_PROP_FPS** Frame rate.
     -   **CAP_PROP_FOURCC** 4-character code of codec.
     -   **CAP_PROP_FRAME_COUNT** Number of frames in the video file.
     -   **CAP_PROP_FORMAT** Format of the Mat objects returned by retrieve() .
     -   **CAP_PROP_MODE** Backend-specific value indicating the current capture mode.
     -   **CAP_PROP_BRIGHTNESS** Brightness of the image (only for cameras).
     -   **CAP_PROP_CONTRAST** Contrast of the image (only for cameras).
     -   **CAP_PROP_SATURATION** Saturation of the image (only for cameras).
     -   **CAP_PROP_HUE** Hue of the image (only for cameras).
     -   **CAP_PROP_GAIN** Gain of the image (only for cameras).
     -   **CAP_PROP_EXPOSURE** Exposure (only for cameras).
     -   **CAP_PROP_CONVERT_RGB** Boolean flags indicating whether images should be converted
         to RGB.
     -   **CAP_PROP_WHITE_BALANCE** Currently not supported
     -   **CAP_PROP_RECTIFICATION** Rectification flag for stereo cameras (note: only supported
         by DC1394 v 2.x backend currently)

    @note When querying a property that is not supported by the backend used by the VideoCapture
    class, value 0 is returned.
     */
    CV_WRAP virtual double get(int propId) const;

EX1:

int width=cap.get(CAP_PROP_FRAME_WIDTH);
int height=cap.get(CAP_PROP_FRAME_HEIGHT);
int frameRate=cap.get(CAP_PROP_FPS);
int totalFrames=cap.get(CAP_PROP_FRAME_COUNT);

cout<<"宽度:"<<width<<endl;
cout<<"高度"<<height<<endl;
cout<<"频率"<<frameRate<<endl;
cout<<"视频帧数"<<totalFrames<<endl;

VideoWriter

1.构造函数
/** @brief VideoWriter constructors

The constructors/functions initialize video writers. On Linux FFMPEG is used to write videos; on
Windows FFMPEG or VFW is used; on MacOSX QTKit is used.
 */
CV_WRAP VideoWriter();

/** @overload
@param filename Name of the output video file.
@param fourcc 4-character code of codec used to compress the frames. For example,
VideoWriter::fourcc('P','I','M','1') is a MPEG-1 codec, VideoWriter::fourcc('M','J','P','G') is a
motion-jpeg codec etc. List of codes can be obtained at [Video Codecs by
FOURCC](http://www.fourcc.org/codecs.php) page. FFMPEG backend with MP4 container natively uses
other values as fourcc code: see [ObjectType](http://www.mp4ra.org/codecs.html),
so you may receive a warning message from OpenCV about fourcc code conversion.
@param fps Framerate of the created video stream.
@param frameSize Size of the video frames.
@param isColor If it is not zero, the encoder will expect and encode color frames, otherwise it
will work with grayscale frames (the flag is currently supported on Windows only).
*/
CV_WRAP VideoWriter(const String& filename, int fourcc, double fps,
            Size frameSize, bool isColor = true);

2.写入帧方式

1)writer.write(frame);
2)writer<<frame;

3.注意事项
1)安装相应的编解码器
xvid.exe
2)生成视频是否支持彩色应与构造函数设置一致

  VideoWriter writer("D:\\out.avi",CV_FOURCC('P','I','M','1'),20,size0,false);

VideoWriter中的最后一个参数用于设置写入的视频格式是否为彩色

3)生成视频尺寸需与读取视频尺寸一致

 Size size0=Size(cap.get(CV_CAP_PROP_FRAME_WIDTH),cap.get(CV_CAP_PROP_FRAME_HEIGHT));
    //定义了一个写入视频的对象
 VideoWriter writer("D:\\out.avi",CV_FOURCC('P','I','M','1'),20,size0,false);

二 实例代码

读取视频

视频读取本质上就是读取帧,原因是视频是由帧组成的
1.实现功能:读取视频,并按照一定的频率进行播放

#include "mainwindow.h"
#include<iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    VideoCapture cap;
    cap.open("D:\\1.avi");
    //VideoCapture cap("1.avi");
    if(!cap.isOpened())
         return;
     Mat frame;
     while(1){
         //cap>>frame;
         cap.read(frame);
         if(frame.empty())
             break;
         imshow("video",frame);
         waitKey(20);

     }
     cap.release();

}

MainWindow::~MainWindow()
{

}

读取摄像头

1. 简单读取
mainwindow.cpp

#include "mainwindow.h"
#include<iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    VideoCapture cap;
    cap.open(0);
    if(!cap.isOpened())
         return;

     Mat frame;
     while(1){
         //cap>>frame;
         cap.read(frame);
         if(frame.empty())
           break;

         imshow("video",frame);
         //用于关掉窗口
         if(waitKey(20)>0)
             break;


     }
     cap.release();
     //销毁所有窗口
     destroyAllWindows();

}

MainWindow::~MainWindow()
{

}

2. 图像处理

 Mat frame;
     while(1){
         //cap>>frame;
         cap.read(frame);
         //Canny(frame,frame,30,200);
         cvtColor(frame,frame,CV_BGR2HSV);
         if(frame.empty())
           break;
         imshow("video",frame);
         if(waitKey(20)>0)
             break;
     }

写入视频

1.未经处理直接写入

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    VideoCapture cap;
    Size size0=Size(320,240);
    //定义了一个写入视频的对象
    VideoWriter writer("D:\\out.avi",CV_FOURCC('P','I','M','1'),15,size0,true);
   // VideoWriter writer("D:\\out.avi",-1,15,size0,true);
    cap.open("D:\\1.avi");

    if(!cap.isOpened())
         return;

     Mat frame;
     while(1){
         //cap>>frame;
         cap.read(frame);
         //Canny(frame,frame,30,200);
         //cvtColor(frame,frame,CV_BGR2HSV);
         if(frame.empty())
           break;
         writer<<frame;
         //writer.write(frame);
         imshow("video",frame);
         if(waitKey(20)>0)
             break;
     }
     cout<<"Write endl"<<endl;
     cap.release();
     destroyAllWindows();
}

2.经过图像处理再写入

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    VideoCapture cap;
    Size size0=Size(320,240);
    //定义了一个写入视频的对象
    VideoWriter writer("D:\\out.avi",CV_FOURCC('P','I','M','1'),20,size0,false);
   // VideoWriter writer("D:\\out.avi",-1,15,size0,true);
    cap.open("D:\\1.avi");

    if(!cap.isOpened())
         return;

     Mat frame;
     while(1){
         //cap>>frame;
         cap.read(frame);
         //Canny(frame,frame,30,200);
         cvtColor(frame,frame,CV_BGR2GRAY);
         if(frame.empty())
           break;
         writer<<frame;
         //writer.write(frame);
         imshow("video",frame);
         if(waitKey(20)>0)
             break;
     }
     cout<<"Write endl"<<endl;
     cap.release();
     destroyAllWindows();

}

3.将摄像头读入的写入视频文件

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    VideoCapture cap;
    cap.open(0);
    Size size0=Size(cap.get(CV_CAP_PROP_FRAME_WIDTH),cap.get(CV_CAP_PROP_FRAME_HEIGHT));
    //定义了一个写入视频的对象
    VideoWriter writer("D:\\out.avi",CV_FOURCC('P','I','M','1'),20,size0,false);
   // VideoWriter writer("D:\\out.avi",-1,15,size0,true);
    if(!cap.isOpened())
         return;
     Mat frame;
     while(1){
         //cap>>frame;
         cap.read(frame);
         //Canny(frame,frame,30,200);
         cvtColor(frame,frame,CV_BGR2GRAY);
         if(frame.empty())
           break;
         writer<<frame;
         //writer.write(frame);
         imshow("video",frame);
         if(waitKey(20)>0)
             break;
     }
     cout<<"Write endl"<<endl;
     cap.release();
     destroyAllWindows();

}

三 知识点详解

读取视频

1.读取视频的两种方法
A.

   VideoCapture cap;
   cap.open(“1.avi”);

B.

VideoCapture cap(“1.avi”);

2.循环显示每一帧

while(1)
{
   Mat frame;  //定义Mat变量,用来存储每一帧
   cap>>frame; //读取当前fd帧方法一
 //cap.read(frame); //读取当前帧方法二
   imshow(“视频显示”, frame); //显示一帧画面
   waitKey(30); //延时30ms
}

3.注意点
1)打开的视频可以是本地视频如:

VideoCapture cap("1.avi");

也可以是网络视频如:

VideoCapture cap("http://www.laganiere.name/bike.avi");

2)读取视频一定要加异常判断
A.打开视频失败(各种原因)
B. 取帧失败异常(程序结尾判断)
ex1:

if(!cap.isOpened()) //检查打开是否成功
   return;

ex2:

cap>>frame;
if(!frame.empty()) //判断当前 帧是否为空
{
   imshow("video", frame);
   waitKey(30);
}
else  break;

4. waitKey
1)设置显示图像的频率
用于设置窗口video每隔20ms刷新一次

waitKey(20);

2)设置按键按下的事件
当按键为ESC时,退出运行

 if(waitKey(30)==27)
               break;

当按下任意按键时,退出运行
原因是:没有按键按下,返回值为-1;有按键按下,返回值都大于0

if(waitKey(30)>0)
   break;

读取摄像头

1.读取摄像头的方法

VideoCapture cap;
cap.open(int index);

索引 index
1)如果默认笔记本/台式机只有一个USB摄像头,Index=0; 如果有2个,一般Index为0和1,根据具体情况区分,摄像头接入和断开会改变Index值
2)如果接入2个以上,但只想用指定的一个,可以在设备管理器中禁用其他,同时Index设置为0.
2.WaitKey
用waitKey()返回值判断退出预览

 imshow("video", frame);
 if(waitKey(30)>0)//无按键按下返回-1
    break;

可以指定按键退出:

    if(waitKey(30)==27) //Esc键退出
    break;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值