OpenCV-python视频入门

目标

  • 学习阅读视频、显示视频和保存视频。
  • 学习从相机捕捉视频并显示它。
  • 您将学习这些函数​ :
    cv.VideoCapture() 从视频文件、图像序列或相机中捕获视频的类
    cv.VideoWriter() 捕获一个视频并逐帧处理它,保存想要的视频

从相机捕捉视频

通常,我们必须用相机捕捉实时流。OpenCV 提供了一个非常简单的接口来执行此操作。让我们从相机中捕捉视频(我使用笔记本电脑上的内置网络摄像头),将其转换为灰度视频并显示。只需一个简单的任务即可开始。

要捕获视频,您需要创建一个VideoCapture对象。它的参数可以是设备索引或视频文件的名称。设备索引只是指定哪个相机的数字。通常会连接一台相机(如我的情况)。所以我只是传递0(或-1)。您可以通过传递 1 来选择第二个相机,依此类推。之后,您可以逐帧捕获。但最后,不要忘记释放捕获。

源代码

  • Code at glance:
    import numpy as np
    import cv2 as cv
    cap = cv.VideoCapture(0)
    if not cap.isOpened():
        print("Cannot open camera")
        exit()
    while True:
        # Capture frame-by-frame(逐帧捕捉)
        ret, frame = cap.read()
        # if frame is read correctly ret is True(如果帧被正确读取 ret 为 Tru)
        if not ret:
            print("Can't receive frame (stream end?). Exiting ...")
            break
        # Our operations on the frame come here(我们对帧的操作到这里)
        gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
        # Display the resulting frame(显示结果帧)
        cv.imshow('frame', gray)
        if cv.waitKey(1) == ord('q'):
            break
    # When everything done, release the capture(一切完成后,释放捕获)
    cap.release()
    cv.destroyAllWindows()
  • Result at glance:

OpenCV-python视频入门_第1张图片

 解释

cap.read()返回一个布尔值TrueFalse)。如果帧被正确读取,它将是True. 因此,您可以通过检查此返回值来检查视频的结尾。

有时,cap 可能没有初始化捕获。在这种情况下,此代码显示错误。您可以通过cap.isOpened()方法检查它是否已初始化。如果是True,好的。否则使cap.open()打开它。

您还可以使用cap.get(propId)方法访问此视频的某些功能,其中 propId 是从 0 到 18 的数字。每个数字表示视频的一个属性(如果它适用于该视频)。完整的细节可以在这里看到cv::VideoCapture::get()。其中一些值可以使用cap.set(propId, value)进行修改。值是您想要的新值。

例如,我可以通过和检查框架的宽度和高度。默认情况下它给我 640x480。但我想将其修改为 320x240。只需使用cap.get(cv.CAP_PROP_FRAME_WIDTH)cap.get(cv.CAP_PROP_FRAME_HEIGHT)
ret = cap.set(cv.CAP_PROP_FRAME_WIDTH,320)ret=cap.set(cv.CAP_PROP_FRAME_HEIGHT,240)

笔记

如果您遇到错误,请确保您的相机在使用任何其他相机应用程序(如 Linux 中的 Cheese)时工作正常。

从文件播放视频

从文件播放视频与从相机捕获视频相同,只需将相机索引更改为视频文件名即可。此外,在显示框架时,请使用适当的时cv.waitKey()。如果太少,视频会很快,如果太高,视频会很慢(嗯,这就是您可以慢动作显示视频的方式)。在正常情况下,25 毫秒就可以了。

import numpy as np
import cv2 as cv
cap = cv.VideoCapture('vtest.avi')
while cap.isOpened():
    ret, frame = cap.read()
    # if frame is read correctly ret is True(如果帧被正确读取 ret 为 True)
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    cv.imshow('frame', gray)
    if cv.waitKey(1) == ord('q'):
        break
cap.release()
cv.destroyAllWindows()

笔记

确保安装了正确版本的 ffmpeg 或 gstreamer。有时使用视频捕获很头疼,主要是由于 ffmpeg/gstreamer 安装错误。

保存视频

所以我们捕获一个视频并逐帧处理它,我们想要保存该视频。对于图像,它非常简单:只需使cv.imwrite(). 在这里,需要做更多的工作。

这次我们创建了一个VideoWriter对象。我们应该指定输出文件名(例如:output.avi)。然后我们应该指定FourCC代码(下一段中的详细信息)。然后应传递每秒帧数 (fps) 和帧大小。最后一个是isColor标志。如果是True,编码器期望彩色帧,否则它适用于灰度帧。

FourCC是一个 4 字节的代码,用于指定视频编解码器。可用代码列表可fourcc.org中找到。它依赖于平台。以下编解码器对我来说很好用。

  • 在 Fedora 中:DIVX、XVID、MJPG、X264、WMV1、WMV2。(XVID 更可取。MJPG 产生大尺寸视频。X264 提供非常小尺寸的视频)
  • 在 Windows 中:DIVX(更多有待测试和添加)
  • 在 OSX 中:MJPG (.mp4)、DIVX (.avi)、X264 (.mkv)。

FourCC 代码作为 MJPG 的 `cv.VideoWriter_fourcc('M','J','P','G') or cv.VideoWriter_fourcc(*'MJPG')` 传递。

下面的代码从相机捕获,在垂直方向翻转每一帧,并保存视频。

import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
# Define the codec and create VideoWriter object
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640,  480))
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    frame = cv.flip(frame, 0)
    # write the flipped frame
    out.write(frame)
    cv.imshow('frame', frame)
    if cv.waitKey(1) == ord('q'):
        break
# Release everything if job is finished
cap.release()
out.release()

其他资源

练习

你可能感兴趣的:(OpenCV,#OpenCV中的GUI功能,opencv,python,音视频)