如何读取 scikit-image 处理的 mp4 视频?

Posted

技术标签:

【中文标题】如何读取 scikit-image 处理的 mp4 视频?【英文标题】:How to read mp4 video to be processed by scikit-image? 【发布时间】:2015-06-25 10:17:02 【问题描述】:

我想将scikit-image 函数(特别是模板匹配函数match_template)应用于mp4 视频的帧,h264 编码。对我的应用程序来说,跟踪每一帧的时间很重要,但我知道帧速率,所以我可以很容易地从帧数计算出来。

请注意,我在资源不足的情况下运行,我希望尽可能减少依赖关系:无论如何都需要numpy,并且由于我打算使用scikit-image,所以我会避免导入 (并编译)openCV 只是为了阅读视频。

我在this 页面的底部看到scikit-image 可以无缝处理存储为numpy 数组的视频,因此获得这将是理想的。

【问题讨论】:

好吧,我在 PC 上开发我的应用程序原型时尝试了 openCV。但由于我将在树莓派上交付应用程序,我正在评估更轻量级的替代方案,同时考虑在 raspi 上编译 opencv 的工作量和依赖性。 另见this overview,我们正在为用户指南做准备。 @StefanvanderWalt:概述实际上非常有用,谢谢。添加imageio 可能会有所改进,这也解决了访问您的评论中也提到的特定帧号的问题。 @gaggio 请您对拉取请求发表评论,然后我相信作者会很乐意将其合并。 【参考方案1】:

Imageio python 包应该做你想做的事。这是一个使用这个包的python sn-p:

import pylab
import imageio
filename = '/tmp/file.mp4'
vid = imageio.get_reader(filename,  'ffmpeg')
nums = [10, 287]
for num in nums:
    image = vid.get_data(num)
    fig = pylab.figure()
    fig.suptitle('image #'.format(num), fontsize=20)
    pylab.imshow(image)
pylab.show()

你也可以直接遍历文件中的图片(see the documentation):

for i, im in enumerate(vid):
    print('Mean of frame %i is %1.1f' % (i, im.mean()))

要安装 imageio,您可以使用 pip:

pip install imageio

另一种解决方案是使用moviepy(它使用类似的代码来读取视频),但我认为 imageio 更轻巧并且可以胜任。


回复第一条评论

为了检查整个文件的标称帧率是否相同,您可以计算迭代器中的帧数:

count = 0
try:
    for _ in vid:
        count += 1
except RuntimeError:
    print('something went wront in iterating, maybee wrong fps number')
finally:
    print('number of frames counted , number of frames in metada '.format(count, vid.get_meta_data()['nframes']))


In [10]: something went wront in iterating, maybee wrong fps number
         number of frames counted 454, number of frames in metada 461

为了显示每一帧的时间戳

try:
    for num, image in enumerate(vid.iter_data()):
        if num % int(vid._meta['fps']):
            continue
        else:
            fig = pylab.figure()
            pylab.imshow(image)
            timestamp = float(num)/ vid.get_meta_data()['fps']
            print(timestamp)
            fig.suptitle('image #, timestamp='.format(num, timestamp), fontsize=20)
            pylab.show()
except RuntimeError:
    print('something went wrong')

【讨论】:

感谢有用的链接和示例。这里遗漏的只是每一帧对应的时间。我试试看,时间可能在帧元数据中,否则必须从帧数计算,假设在整个视频录制过程中正确保持标称帧率,这是可以的。 好问题,在某些视频上,标称帧率没有正确保持。要检查它,您可以计算迭代器中的帧数,并与元数据中的帧数进行比较,如果它们相等,您可以根据 frame_number / fps_rate 计算每个帧的时间戳。我更新了我的答案来比较这两个数字。 这对我很有效。非常感谢。 IMO 比 ffmpeg / avconv / opencv / scikit-video 的 opencv 感觉友好得多。希望我早点发现这一点。【参考方案2】:

你可以使用scikit-video,像这样:

from skvideo.io import VideoCapture

cap = VideoCapture(filename)
cap.open()

while True:
    retval, image = cap.read()
    # image is a numpy array containing the next frame
    # do something with image here
    if not retval:
        break

这在引擎盖下使用 avconv 或 ffmpeg。性能相当不错,与仅在 avconv 中解码视频相比,将数据移动到 python 的开销很小。

scikit-video的优势在于API与OpenCV的视频读写API完全相同;只需将 cv2.VideoCapture 替换为 skvideo.io.VideoCapture。

【讨论】:

【参考方案3】:

在 python 中阅读视频的一种简单方法是使用 skviode。单行代码可以帮助阅读整个视频。

import skvideo.io  
videodata = skvideo.io.vread("video_file_name")  
print(videodata.shape)

http://mllearners.blogspot.in/2018/01/scikit-video-skvideo-tutorial-for.html

【讨论】:

以上是关于如何读取 scikit-image 处理的 mp4 视频?的主要内容,如果未能解决你的问题,请参考以下文章

scikit-image 安装错误

AI常用框架和工具丨6. 图像处理库Scikit-image

如何用 scikit-image 反转黑白?

使用 SciKit-Image 和 SciKit-Learn 进行图像预处理和聚类 - 需要一些建议

scikit-image 中用于图像分割的阈值算法

scikit-image:遥感图像geotiff格式转mat格式