OpenCV基础操作_视频读取

Posted 孤独的小丑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV基础操作_视频读取相关的知识,希望对你有一定的参考价值。

1 视频文件读取

1.1 cv2.VideoCapture() 

在OpenCV中,可以使用VideoCapture来读取视频文件,或是摄像头数据。

函数定义:Reading and Writing Images and Video — OpenCV 2.4.13.7 documentation

Python: cv2.VideoCapture() → <VideoCapture object>

Python: cv2.VideoCapture(filename) → <VideoCapture object>

Python: cv2.VideoCapture(device) → <VideoCapture object>

1.2 cv2.VideoCapture.isOpened()

判断文件打开是否成功,可以使用cv2.VideoCapture.isOpened()这个函数。

函数定义:Reading and Writing Images and Video — OpenCV 2.4.13.7 documentation

Python: cv2.VideoCapture.isOpened() → retval

返回值是True/False。如果视频文件打开成功,返回值为True。

1.3 cv2.VideoCapture.read()

在python中,我一般比较习惯用这样的方式进行操作:

先Open一个文件,然后通过cv2.VideoCapture.read()的方式,读取每一帧数据。

cv2.VideoCapture.read()提供了一个最简单的视频帧处理方式,集合了抓起Grab(),解码retrieve()两个功能,返回解码之后的数据。需要特别注意的是,如果获取到空帧,抓取失败或是文件结束,返回值会是一个空指针。

 函数定义:Reading and Writing Images and Video — OpenCV 2.4.13.7 documentation

1.4 示例代码:

import cv2


video = cv2.VideoCapture("./1.mp4")

if video.isOpened():
    # video.read() 一帧一帧地读取
    # open 得到的是一个布尔值,就是 True 或者 False
    # frame 得到当前这一帧的图像
    open, frame = video.read()
else:
    open = False

while open:
    ret, frame = video.read()
    # 如果读到的帧数不为空,那么就继续读取,如果为空,就退出
    if frame is None:
        break
    if ret == True:
        cv2.imshow("video",frame)
        # 这里使用 waitKey 可以控制视频的播放速度,数值越小,播放速度越快
        # 这里等于 27 也即是说按下 ESC 键即可退出该窗口
        if cv2.waitKey(10) & 0xFF == 27:
            break
video.release()
cv2.destroyAllWindows()

2 读取摄像头

VideoCapture也是支持读取摄像头的。我这边是一个摄像头,可以提供rtsp码流,码流地址是:rtsp://192.168.0.200:554/av0_0

实现的示例代码如下:

import cv2


video = cv2.VideoCapture("rtsp://192.168.0.200:554/av0_0")

if video.isOpened():
    # video.read() 一帧一帧地读取
    # open 得到的是一个布尔值,就是 True 或者 False
    # frame 得到当前这一帧的图像
    open, frame = video.read()
else:
    open = False

while open:
    ret, frame = video.read()
    # 如果读到的帧数不为空,那么就继续读取,如果为空,就退出
    if frame is None:
        break
    if ret == True:
        # 转换为灰度图
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        cv2.imshow("video",gray)
        # 这里使用 waitKey 可以控制视频的播放速度,数值越小,播放速度越快
        # 这里等于 27 也即是说按下 ESC 键即可退出该窗口
        if cv2.waitKey(1) & 0xFF == 27:
            break
video.release()
cv2.destroyAllWindows()

上面代码处理摄像头数据,现在转换为gray,然后显示。

在实际项目中,可能会发现现实出来的摄像头数据会有延时,主要有如下几种可能:

1)摄像头本身做了buffer,可以通过配置摄像头的缓存帧,降低延时;

2)视频播放软件有buffer,比如vlc,也是可以调整的;

3)网络带宽,实践中,多路摄像头(比如说16路)在100M网络环境和1000M网络环境表现明显不同。这里面的网络环境是指全链路:包括网线、集线器、路由器、显示终端(电脑)等;

4)AI处理时间过长。如果在实际项目中,是直接采用串行设计,来一帧分析一帧,而这帧数据每一办法在固定的时间内分析完成(比如40ms),这样就会造成摄像头数据延时。一般有两种解决办法:

a、做丢帧处理,这需要依据场景来决定;

b、做异步架构调整。一个线程用来读取数据,一个线程用了做AI分析;

5)显示终端处理不过来。比如我们有关项目的架构是采用WebSocket的方式,把数据传给QT(大屏展示)和WebUI(浏览器),结果浏览器的渲染速度没有办法跟上,导致显示数据堆积。

6)其他情况

以上一些情况,供大家参考处理。

【参考文献】

[1] 每周一课 | OpenCV :图像基本操作

OpenCV学习笔记2基础:读取播放保存视频

使用 OpenCV 也可以非常方便地读取、播放、保存视频,下面分别介绍。

1. 读取摄像头

VideoCapture 类用于从视频、图像序列、摄像头获取输入。先看如何读取摄像头输入:

import cv2

capture = cv2.VideoCapture(0) # 创建一个视频捕获对象,参数为摄像头编号

print('width = ', capture.get(3), ' height = ', capture.get(4)) # 查看摄像头参数

while True:
    ret, frame = capture.read() # 读取一帧,ret表示是否读取成功
    cv2.imshow('video 0', frame) # 显示一帧

    if cv2.waitKey(1) == ord('q'): # 等待1毫秒,检测到Q键按下则退出
        break

构造函数:cv.VideoCapture(index[, apiPreference])

第一个参数是摄像头的设备号,一般默认为 0 ,即第一个摄像头,如果有多个摄像头,可以设为 1、2、3 等等。

第二个参数指定用于读取视频的后端API,如 cv::CAP_FFMPEGcv::CAP_IMAGEScv::CAP_DSHOW(参考 VideoCaptureAPIs)。

2. 读取视频

读取视频文件例子:

import cv2

capture = cv2.VideoCapture('test.mp4')

while capture.isOpened():
    ret, frame = capture.read()
    cv2.imshow('test video', frame)
    if cv2.waitKey(1) == ord('q'):
        break

构造函数:cv.VideoCapture(filename[, apiPreference])

第一个参数是文件名,可以是如下几类:

  • 视频文件名 (如 video.avi)
  • 图像序列模式串 (如 img_%02d.jpg, 会依次读取img_00.jpg, img_01.jpg, img_02.jpg, …)
  • 视频流URL (如 protocol://host:port/script_name?script_params|auth)
  • GStreamer pipeline string in gst-launch tool format in case if GStreamer is used as backend

前两种较简单,后两种可自己尝试。第二个参数用于指定读取视频的后端API。

3. 保存视频

VideoWriter 类用于保存视频。把摄像头输入保存为视频文件的例子:

import cv2

capture = cv2.VideoCapture(0)

fourcc = cv2.VideoWriter_fourcc(*'MJPG')
output = cv2.VideoWriter('videos/output.avi', fourcc, 30, (640, 480))

while True:
    ret, frame = capture.read()
    if ret:
        output.write(frame)
        cv2.imshow('camera', frame)
        if cv2.waitKey(1) == ord('q'):
            break
    else:
        break

VideoWriter_fourcc 函数用于通过字符创建 fourcc 码,该编码用于指示一个视频的编码压缩格式等信息。什么是 fourcc 码可以参考:What is a FOURCC?

VideoWriter 是一个用于写视频的类。第一个参数是文件名, 第二个参数是 fourcc 码,第三个参数为帧率,第四个参数为视频大小。


References

  1. OpenCV: cv::VideoCapture Class Reference
  2. OpenCV: cv::VideoWriter Class Reference
  3. What is a FOURCC?
  4. Opencv中FOURCC详解_持久决心的博客-CSDN博客
  5. Video Codecs by FOURCC - fourcc.org
  6. Getting Started with Videos

QQ交流群:点击链接加入群聊【Python练习生】532232743
我的知乎:AXin啊
公众号:请叫我AXin

以上是关于OpenCV基础操作_视频读取的主要内容,如果未能解决你的问题,请参考以下文章

2018传智黑马Python人工智能视频教程(基础+就业+面试)

opencv-python——2(颜色分割(RGBHSV)读取摄像头和视频并保存)

python_Opencv_读取视频_摄像头

Python OpenCv学习基础知识一

python-opencv-视频的读取与分解

Python opencv 常用操作