OpenCV读取具有多个流/轨道的视频文件

我有一个视频文件,其中包含使用VLC媒体播放器显示的多个流,如下所示: Video Information

当我尝试使用Python + OpenCV使用以下代码读取它时:

vidObj = cv2.VideoCapture("video.avi")
ret,frame = vidObj.read()

我只能阅读视频的第一首曲目。如何同时阅读所有视频轨道?

zhansir720 回答:OpenCV读取具有多个流/轨道的视频文件

据我所知,OpenCV不允许选择视频流,因此这是不可能的。但是,您可以使用ffmpeg命令行实用工具轻松地做到这一点:

import numpy as np
import json
import subprocess

def videoInfo(filename):
    proc = subprocess.run([
        *"ffprobe -v quiet -print_format json -show_format -show_streams".split(),filename
    ],capture_output=True)
    proc.check_returncode()
    return json.loads(proc.stdout)

def readVideo(filename):
    cmd = ["ffmpeg","-i",filename]
    streams = 0
    for stream in videoInfo(filename)["streams"]:
        index = stream["index"]
        if stream["codec_type"] == "video":
            width = stream["width"]
            height = stream["height"]
            cmd += "-map",f"0:{index}"
            streams = streams + 1
    cmd += "-f","rawvideo","-pix_fmt","rgb24","-"
    shape = np.array([streams,height,width,3])
    with subprocess.Popen(cmd,stdout=subprocess.PIPE) as proc:
        while True:
            data = proc.stdout.read(shape.prod())  # One byte per each element
            if not data:
                return
            yield np.frombuffer(data,dtype=np.uint8).reshape(shape)

请注意,该代码读取所有视频流,并假定每个视频流具有相同的分辨率。它缺乏适当的错误处理,但是在我的科学项目中完成了工作。

例如,读取立体流:

import matplotlib.pyplot as plt

for left,right in readVideo("testvideo.mkv"):
    plt.imshow(left)
    plt.show()
    plt.imshow(right)
    plt.show()
本文链接:https://www.f2er.com/3115006.html

大家都在问