OpenCV-Python学习之视频流API接口

本文介绍OpenCV中的VideoCapture和VideoWriter类使用方法,包括视频读取、保存接口及属性设置等,并提供示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

视频读取接口VideoCapture类

Python调用VideoCapture类API接口:

'''
    VideoCapture(params) :  
         0 为计算机默认摄像头  1 为自定义的视频文件或摄像头来源
'''
cap = cv2.VideoCapture(params)

  我们知道Python调用底层C++的VideoCapture类API接口,下面我们在OpenCV源码中videoio.hpp查看一下VideoCapture类的声明:

VideoCapture类构造函数(c/c++两种):

C_API  VideoCapture::VideoCapture();
C++_API VideoCapture::VideoCapture(const String& filename, int apiPreference = CAP_ANY);
C++_API VideoCapture::VideoCapture(int index, int apiPreference = CAP_ANY);

参数解释:

  filename : 图像序列或者视频连接URL地址或者视频的路径;
  index : 打开设备ID号(下面会有ID号解释);
  apiPreference : VideoCapture API backends identifier,默认CAP_ANY;

附1:(为apiPreference 接口的设备ID对应)

enum VideoCaptureAPIs {
       CAP_ANY          = 0,            //!< Auto detect == 0
       CAP_VFW          = 200,          //!< Video For Windows (platform native)
       CAP_V4L          = 200,          //!< V4L/V4L2 capturing support via libv4l
       CAP_V4L2         = CAP_V4L,      //!< Same as CAP_V4L
       CAP_FIREWIRE     = 300,          //!< IEEE 1394 drivers
       CAP_FIREWARE     = CAP_FIREWIRE, //!< Same as CAP_FIREWIRE
       CAP_IEEE1394     = CAP_FIREWIRE, //!< Same as CAP_FIREWIRE
       CAP_DC1394       = CAP_FIREWIRE, //!< Same as CAP_FIREWIRE
       CAP_CMU1394      = CAP_FIREWIRE, //!< Same as CAP_FIREWIRE
       CAP_QT           = 500,          //!< QuickTime
       CAP_UNICAP       = 600,          //!< Unicap drivers
       CAP_DSHOW        = 700,          //!< DirectShow (via videoInput)
       CAP_PVAPI        = 800,          //!< PvAPI, Prosilica GigE SDK
       CAP_OPENNI       = 900,          //!< OpenNI (for Kinect)
       CAP_OPENNI_ASUS  = 910,          //!< OpenNI (for Asus Xtion)
       CAP_ANDROID      = 1000,         //!< Android - not used
       CAP_XIAPI        = 1100,         //!< XIMEA Camera API
       CAP_AVFOUNDATION = 1200,         //!< AVFoundation framework for iOS (OS X Lion will have the same API)
       CAP_GIGANETIX    = 1300,         //!< Smartek Giganetix GigEVisionSDK
       CAP_MSMF         = 1400,         //!< Microsoft Media Foundation (via videoInput)
       CAP_WINRT        = 1410,         //!< Microsoft Windows Runtime using Media Foundation
       CAP_INTELPERC    = 1500,         //!< Intel Perceptual Computing SDK
       CAP_OPENNI2      = 1600,         //!< OpenNI2 (for Kinect)
       CAP_OPENNI2_ASUS = 1610,         //!< OpenNI2 (for Asus Xtion and Occipital Structure sensors)
       CAP_GPHOTO2      = 1700,         //!< gPhoto2 connection
       CAP_GSTREAMER    = 1800,         //!< GStreamer
       CAP_FFMPEG       = 1900,         //!< Open and record video file or stream using the FFMPEG library
       CAP_IMAGES       = 2000,         //!< OpenCV Image Sequence (e.g. img_%02d.jpg)
       CAP_ARAVIS       = 2100,         //!< Aravis SDK
       CAP_OPENCV_MJPEG = 2200,         //!< Built-in OpenCV MotionJPEG codec
       CAP_INTEL_MFX    = 2300,         //!< Intel MediaSDK
       CAP_XINE         = 2400,         //!< XINE engine (Linux)
     };

VideoCapture类open函数:

virtual bool VideoCapture::open(const String& filename, int apiPreference = CAP_ANY);
virtual bool VideoCapture::open(int index, int apiPreference = CAP_ANY);

参数解释:同VideoCapture()构造函数一致;

调用方式只是先声明VideoCapture类对象,然后调用open函数;

cap = cv2.VideoCapture()
cap.open("fruit.avi")

直接使用构造函数方式:

cap = cv2.VideoCapture("fruit.avi")

VideoCapture::isOpened() 判断设备或视频文件是否成功打开,打开true,失败为false:

virtual bool VideoCapture::isOpened() const;

VideoCapture::release() 关闭设备或视频流文件,成功返回true,失败返回false;

virtual void VideoCapture::release();

VideoCapture::grab() 从设备或者视频流文件中抓取下一帧图片,抓取成功返回true,抓取失败返回false;

virtual bool VideoCapture::grab();

VideoCapture::retrieve() 解码并且返回刚刚抓取的视频帧,假设没有捕获视频帧将会返回false;

virtual bool VideoCapture::retrieve(OutputArray image, int flag = 0);

VideoCapture::read()该函数通过结果VideoCapture::grab()或者VideoCapture::retrieve()其中一个函数一起调用,用在捕获或解码和返回下一帧视频帧,假设没有捕获视频帧将会返回false;

virtual VideoCapture& operator >> (CV_OUT Mat& image);
virtual VideoCapture& operator >> (CV_OUT UMat& image);
virtual bool VideoCapture::read(OutputArray image);

获取视频帧的多种方式:

# methods 1
cap.read(frame)
# methods 2
cap.grab()
# methods 3 
cap.retrieve(frame)
# methods 4
cap >> frame

VideoCapture::set()为设置视频流属性,VideoCapture::get()为获取视频流的属性;

virtual bool VideoCapture::set(int propId, double value);
virtual double VideoCapture::get(int propId) const;

参数解释:

  propId 为属性的ID;
  value 为属性ID对应要设置的值;

其中,枚举VideoCaptureProperties 使用最多的几个ID属性分别为:

CAP_PROP_POS_MSEC   // 视频当前位置(毫秒)
CAP_PROP_POS_FRAMES  // 视频当前位置(帧)
CAP_PROP_FRAME_WIDTH  // 视频帧的宽度
CAP_PROP_FRAME_HEIGHT  // 视频帧的高度
CAP_PROP_FPS  // 视频流速率(帧率 帧/秒)
CAP_PROP_FOURCC  // 视频流编码格式(四字符编码)
CAP_PROP_FRAME_COUNT  // 视频流总帧数统计

附2 下面是属性ID所有参数:

enum VideoCaptureProperties {
       CAP_PROP_POS_MSEC       =0, //!< Current position of the video file in milliseconds.
       CAP_PROP_POS_FRAMES     =1, //!< 0-based index of the frame to be decoded/captured next.
       CAP_PROP_POS_AVI_RATIO  =2, //!< Relative position of the video file: 0=start of the film, 1=end of the film.
       CAP_PROP_FRAME_WIDTH    =3, //!< Width of the frames in the video stream.
       CAP_PROP_FRAME_HEIGHT   =4, //!< Height of the frames in the video stream.
       CAP_PROP_FPS            =5, //!< Frame rate.
       CAP_PROP_FOURCC         =6, //!< 4-character code of codec. see VideoWriter::fourcc .
       CAP_PROP_FRAME_COUNT    =7, //!< Number of frames in the video file.
       CAP_PROP_FORMAT         =8, //!< Format of the %Mat objects returned by VideoCapture::retrieve().
       CAP_PROP_MODE           =9, //!< Backend-specific value indicating the current capture mode.
       CAP_PROP_BRIGHTNESS    =10, //!< Brightness of the image (only for those cameras that support).
       CAP_PROP_CONTRAST      =11, //!< Contrast of the image (only for cameras).
       CAP_PROP_SATURATION    =12, //!< Saturation of the image (only for cameras).
       CAP_PROP_HUE           =13, //!< Hue of the image (only for cameras).
       CAP_PROP_GAIN          =14, //!< Gain of the image (only for those cameras that support).
       CAP_PROP_EXPOSURE      =15, //!< Exposure (only for those cameras that support).
       CAP_PROP_CONVERT_RGB   =16, //!< Boolean flags indicating whether images should be converted to RGB.
       CAP_PROP_WHITE_BALANCE_BLUE_U =17, //!< Currently unsupported.
       CAP_PROP_RECTIFICATION =18, //!< Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently).
       CAP_PROP_MONOCHROME    =19,
       CAP_PROP_SHARPNESS     =20,
       CAP_PROP_AUTO_EXPOSURE =21, //!< DC1394: exposure control done by camera, user can adjust reference level using this feature.
       CAP_PROP_GAMMA         =22,
       CAP_PROP_TEMPERATURE   =23,
       CAP_PROP_TRIGGER       =24,
       CAP_PROP_TRIGGER_DELAY =25,
       CAP_PROP_WHITE_BALANCE_RED_V =26,
       CAP_PROP_ZOOM          =27,
       CAP_PROP_FOCUS         =28,
       CAP_PROP_GUID          =29,
       CAP_PROP_ISO_SPEED     =30,
       CAP_PROP_BACKLIGHT     =32,
       CAP_PROP_PAN           =33,
       CAP_PROP_TILT          =34,
       CAP_PROP_ROLL          =35,
       CAP_PROP_IRIS          =36,
       CAP_PROP_SETTINGS      =37, //!< Pop up video/camera filter dialog (note: only supported by DSHOW backend currently. The property value is ignored)
       CAP_PROP_BUFFERSIZE    =38,
       CAP_PROP_AUTOFOCUS     =39,
       CAP_PROP_SAR_NUM       =40, //!< Sample aspect ratio: num/den (num)
       CAP_PROP_SAR_DEN       =41, //!< Sample aspect ratio: num/den (den)
       CAP_PROP_BACKEND       =42, //!< current backend (enum VideoCaptureAPIs). Read-only property
#ifndef CV_DOXYGEN
       CV__CAP_PROP_LATEST
#endif
     };

示例代码:

# -*-coding: utf-8 -*-
import cv2
'''
    VideoCapture(params) :  0 为计算机默认摄像头  1 为自定义的视频文件或摄像头来源
'''
# methods 1 : 打开视频方式1
cap = cv2.VideoCapture(0)
# methods 2 : 打开视频方式2
# cap = cv2.VideoCapture()
# cap.open("fruit.avi")

# 设置显示图像宽高
cap.set(3, 320)
cap.set(4, 240)

cap_prop_frame_count = cap.get(propId=7) # 视频流帧数统计
print(cap_prop_frame_count)

while(cap.isOpened()):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # cap_prop_pos_msec = cap.get(propId=0) # 视频当前位置(毫秒)
    # cap_prop_pos_frames = cap.get(propId=1) # 视频当前位置(帧)
    # print(cap_prop_pos_msec, cap_prop_pos_frames)

    cap_prop_frame_width = cap.get(propId=3) # 视频流的宽度
    cap_prop_frame_height = cap.get(propId=4) # 视频流的高度
    print(cap_prop_frame_width, cap_prop_frame_height)
    #
    # cap_prop_fps = cap.get(propId=5) # 帧率(帧/秒)
    # print(cap_prop_fps)

    # our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # display the resulting frame
    cv2.imshow('frame', gray)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# when everything is done, release the capture
cap.release()
cv2.destroyAllWindows()
视频保存接口VideoWriter类

VideoWriter类C++构造函数

C_API   VideoWriter:: VideoWriter()
C++_API VideoWriter::VideoWriter(const String& filename, int fourcc, double fps,
                Size frameSize, bool isColor = true);
C++_API VideoWriter:: VideoWriter(const String& filename, int apiPreference, 
                int fourcc, double fps,Size frameSize, bool isColor = true);

参数解释:

filename: 保存写入视频流文件名;
fourcc: 编码四字符格式,MJPEG、XVID等等;
fps: 保存的帧率;
frameSize: 保存视频帧大小,(width, height);
isColor:非0时,期望是对彩色图像编码,为0时是对灰度图像进行编码;目前只支持在windows平台操作;

apiPreference:The apiPreference parameter allows to specify API backends to use. Can be used to enforce a specific reader implementation if multiple are available: e.g. cv::CAP_FFMPEG or cv::CAP_GSTREAMER.

初始化VideoWriter类时候,先声明编码保存方式:

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480), True)

FourCC编码方式如下图所示

VideoWriter::open()函数:

virtual bool VideoWriter::open(const String& filename, int fourcc, double fps,
                      Size frameSize, bool isColor = true);
bool VideoWriter::open(const String& filename, int apiPreference, int fourcc, 
                      double fps, Size frameSize, bool isColor = true);

参数解释:

  filename 视频文件名;
  fourcc: 编码格式;
  fps: 帧率;
  frameSize: 视频帧的宽高;
  isColor: 是否采取彩色编码;

判断VideoWriter::isOpened()是否成功初始化

virtual bool VideoWriter::isOpened() const;

VideoWriter::release()关闭视频流写入文件

virtual void VideoWriter::release();

VideoWriter::write()视频帧写入文件函数:

virtual VideoWriter& operator << (const UMat& image);
virtual VideoWriter& operator << (const Mat& image);
virtual void VideoWriter::write(InputArray image);

VideoWriter::set()与VideoWriter::get()函数意义:
  VideoCapture::set()与VideoCapture::get()一致,参数解释参考VideoCapture;

virtual bool VideoWriter::set(int propId, double value);
virtual double VideoWriter::get(int propId) const;

示例代码:

# -*- coding: utf-8 -*-
import cv2

cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480), True)

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret == True:
        frame = cv2.flip(frame, 1) # 水平反转

        # write the flipped frame
        out.write(frame)

        cv2.imshow('frame', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()

显示一帧图像:

原始视频流帧宽高为768x576,我们写入视频保存帧宽高为640x480。所以,展示图像帧率会有宽高比不一致的情况。

参考文献

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_video_display/py_video_display.html#display-video

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值