【问题标题】:OpenCV VideoCapture closes with videos from GoProOpenCV VideoCapture 关闭来自 GoPro 的视频
【发布时间】:2018-08-10 03:11:23
【问题描述】:

我有一个来自 GoPro 设备的视频文件,我只需像这样从 VideoCapture 处理它:

cap = cv2.VideoCapture(path)
        index = 0
        start = time.time()

        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break
            # do something here
        end = time.time()

这很奇怪,但我可以操作除在 GoPro 上捕获的文件以外的任何文件。由于ret 值变为Falseframe 变为None,因此流会在某个时候关闭。没有例外或其他任何东西。

谷歌搜索帮助我找到了this question。我已经使用 ffmpeg 工具从文件中删除了音频流,然后一切正常。那么为什么会这样呢?请帮忙!

我正在使用 Python 3.6.4 x64、Windows 10(但在 Linux 上相同)和来自 this resource 的 OpenCV 预编译二进制文件。

【问题讨论】:

  • 视频的文件扩展名是什么?
  • @Jello 它是 MP4,但我尝试过的松下相机的视频是相同的扩展名,效果很好
  • 我也发现了这个问题。就去专业吧。 OSX 由自制软件构建。这是下面“答案”中 ffmpeg 的输出。

标签: python opencv ffmpeg


【解决方案1】:

我也遇到了这个问题,并且能够在不修剪音频的情况下解决它。事实上,我不相信音轨是问题所在。

我在这个问题上看到的所有 ffmpeg 转换命令都有意想不到的副作用,即从视频文件中剥离所有元数据轨道。 GoPro 实际上将大量原始传感器数据直接打包到 MP4 数据中。我认为这更有可能是罪魁祸首,因为它是文件中存在的最不“标准”的数据类型。

我通过使用以下命令剥离只是音轨来测试这个理论:

ffmpeg -i GH010001.MP4 -map 0 -map -0:a -c copy GH010001_MUTED.MP4

这个新的静音文件表现出同样的问题行为,所以简单地删除音轨是行不通的。

现在,如果您不关心元数据轨道,则可以使用其他 ffmpeg 调用将它们剥离出来!我实际上想使用那个传感器,所以我不得不另辟蹊径。

解决方法

下面的代码在概念层面上非常粗略,但它确实有效。我们不是像通常使用 OpenCV 那样检查空帧,而是简单地计算我们知道应该存在的帧数,并在空帧到来时跳过它们。

auto expectedFrameCount = videoCapture.get(cv::CAP_PROP_FRAME_COUNT);
for(auto frameIndex = 0; frameIndex < expectedFrameCount; frameIndex++) {
  videoCapture >> frame;
  if(frame.empty()) {
    frameIndex--;
    continue;
  }
  // Do useful things with the frame here...
}

忽略文件末尾的通常标志肯定感觉不对,但它有效,我能够播放原始视频文件的所有帧,而无需先进行任何 ffmpeg 转换。

【讨论】:

    【解决方案2】:

    我和 Michael 有同样的问题,想添加 ffmpeg 输出供人们查看。输出太长,无法添加到上面的编辑或评论中。

    MacBook-Pro:MacOS ben$ ffmpeg -i /Users/ben/Downloads/GP011399.MP4 ffmpeg version 3.3.4 Copyright (c) 2000-2017 the FFmpeg developers built with Apple LLVM version 8.1.0 (clang-802.0.42) configuration: --prefix=/usr/local/Cellar/ffmpeg/3.3.4 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libmp3lame --enable-libx264 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma --enable-vda libavutil 55. 58.100 / 55. 58.100 libavcodec 57. 89.100 / 57. 89.100 libavformat 57. 71.100 / 57. 71.100 libavdevice 57. 6.100 / 57. 6.100 libavfilter 6. 82.100 / 6. 82.100 libavresample 3. 5. 0 / 3. 5. 0 libswscale 4. 6.100 / 4. 6.100 libswresample 2. 7.100 / 2. 7.100 libpostproc 54. 5.100 / 54. 5.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/ben/Downloads/GP011399.MP4': Metadata: major_brand : mp41 minor_version : 538120216 compatible_brands: mp41 creation_time : 2015-02-11T13:46:48.000000Z firmware : HD4.01.02.00.00 Duration: 00:26:30.59, start: 0.000000, bitrate: 20127 kb/s Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1280x720 [SAR 1:1 DAR 16:9], 19979 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc (default) Metadata: creation_time : 2015-02-11T13:46:48.000000Z handler_name : GoPro AVC encoder : GoPro AVC encoder Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default) Metadata: creation_time : 2015-02-11T13:46:48.000000Z handler_name : GoPro AAC Stream #0:2(eng): Data: none (tmcd / 0x64636D74) (default) Metadata: creation_time : 2015-02-11T13:46:48.000000Z handler_name : GoPro TCD timecode : 13:46:07:17 Stream #0:3(eng): Data: none (fdsc / 0x63736466), 9 kb/s (default) Metadata: creation_time : 2015-02-11T13:46:48.000000Z handler_name : GoPro SOS

    可能和这里有关?

    OpenCV and GoPro - empty frames in VideoCapture stream

    视频在 VLC 中播放没有错误或明显损坏。相同的代码会打开我遇到的所有其他视频文件(我已经使用此代码至少一年了)。

    Opencv 和 Python 版本

    2.7.10 (default, Feb 7 2017, 00:08:15) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] Python Type "help", "copyright", "credits" or "license" for more information. import cv2 cv2.__version__ '3.3.0'

    与提交的 Q 相同的代码。我的流读取 26 帧,然后返回 ret=False。

    【讨论】:

    • 对不起,我不明白。当没有提供链接时,您从哪里/如何从迈克尔那里获得视频文件?我怎样才能得到它?
    • 也许我在劫持他的问题。他从来没有回应足够的信息。我对 gopro 视频也有同样的问题,而不是他提供的视频。我的文件太大而无法共享 (4gb)。在维护编解码器的同时,我将尝试使用 ffmpeg 进行剪切。
    • 我猜 50-100 帧就足够了......如果它在 26 点失败
    • 我可以提供文件的链接,但我认为没有必要。似乎来自 GoPro 摄像头的所有视频都与 OpenCV 存在此问题。作为一种解决方法,我在 python 中使用带有子进程的 ffmpeg 工具来静音所需的视频。 ffmpeg -i [input_file] -vcodec copy -an [output_file] 让我知道是否有人还需要关于我试图从 ffmpeg 处理的文件的输出数据。
    • 所以它的音频编解码器在做呢?很奇怪。
    【解决方案3】:

    您没有列出您的相机型号。但是我遇到了来自 GoPro 的 x264 文件的问题。但不是 x265 文件。尝试在您的相机中将压缩模式从兼容模式更改为 HEVC。对于 x264,我使用“ffmpeg -i video.mp4 -sn -an -vcodec mpeg4 -q:v 0 output.mp4”解压缩,但之后文件大约大 4 倍。

    【讨论】:

    • 这应该是评论,而不是答案。
    • x264 是一个编码器。 H.264 是格式。使用 -vcodec mpeg4 创建过时的格式:MPEG-4 Part 2 视频。
    【解决方案4】:

    使用 OpenCV 4.4.0 对此进行更新(参考 Matt Barulic 的回答): 使用 VideoCapture 抓取/接收方法,我们通过类似的解决方法解决了这个问题。此代码使用 C++,但假设此方法同样适用于 Python:

    frameOk = videoCapture.grab();
    if (!frameOk) {
        if (framei > 0 && framei < 100) {
            frameOk = true;
        }
    }
    if (frameOk)
        videoCapture.retrieve(image);
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 2021-03-22
      • 2020-12-19
      • 2014-04-30
      • 2018-07-26
      • 1970-01-01
      • 2020-03-09
      相关资源
      最近更新 更多