簡體   English   中英

OpenCV VideoCapture 以來自 GoPro 的視頻結束

[英]OpenCV VideoCapture closes with videos from GoPro

我有一個來自 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 捕獲的任何文件之外的任何文件。 Stream 只是在某個時候關閉,因為ret值變為Falseframe變為None 沒有例外或其他任何事情。

谷歌搜索幫助我找到了這個問題 我已經使用ffmpeg工具從文件中刪除了音頻流,然后一切正常。 那么為什么會這樣呢? 請幫忙!

我正在使用 Python 3.6.4 x64、Windows 10(但在 Linux 上相同)和來自該資源的OpenCV 的預編譯二進制文件。

我也遇到了這個問題,並且能夠在不修剪音頻的情況下解決它。 事實上,我不相信音軌是問題所在。

我在這個問題上看到的所有 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 轉換。

我和邁克爾有同樣的問題,想添加 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 和 GoPro - VideoCapture 流中的空幀

視頻在 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 的 x264 文件的問題。 但不是 x265 文件。 嘗試在您的相機中將壓縮模式從兼容更改為 HEVC。 對於 x264,我使用“ffmpeg -i video.mp4 -sn -an -vcodec mpeg4 -q:v 0 output.mp4”解壓縮它,但之后文件大了大約 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);
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM