6

opencv を使用してビデオを書き込もうとしています。これを正確に行うことが重要です。つまり、ロスレス コーデックである必要があります。Ubuntu 12.04でOpenCV 2.4.1を使用しています

以前は、fourcc コード 0 を使用していました。これにより、希望どおりの結果が得られ、イメージを完全に復元することができました。

何が起こったのかわかりませんが、最近の更新 (2012 年 7 月 20 日頃) の時点で何か問題が発生し、この fourcc コードでファイルを書き込むことができなくなりました。それが何であったかは本当に覚えていませんが、更新を行ったり、ソフトウェアセンターからいくつかのソフトウェアを削除したり、一般的なクリーニング中に行ったその他のことが原因である可能性があります...

古いファイルを mediainfo (http://www.fourcc.org/identifier/) でチェックすると、次の結果が表示されます。

Complete name                            : oldsample.avi
Format                                   : AVI
Format/Info                              : Audio Video Interleave
Format profile                           : OpenDML
File size                                : 1.07 GiB
Duration                                 : 41s 467ms
Overall bit rate                         : 221 Mbps
Writing application                      : Lavf53.5.0
Video
ID                                       : 0
Format                                   : RGB
Codec ID                                 : 0x00000000
Codec ID/Info                            : Basic Windows bitmap format. 1, 4 and 8 bpp     versions are palettised. 16, 24 and 32bpp contain raw RGB samples
Duration                                 : 41s 467ms
Bit rate                                 : 221 Mbps
Width                                    : 640 pixels
Height                                   : 4294966 816 pixels
Display aspect ratio                     : 0.000
Frame rate                               : 30.000 fps
Bit depth                                : 8 bits
Stream size                              : 1.07 GiB (100%)

ここで、0 fourcc コーデックを使用して書き込むと、プログラムは実際にはデフォルトで i420 コーデックになることがわかります。これは、私が今書き込もうとしているファイルの 1 つからの出力です。

Complete name                            : newsample.avi
Format                                   : AVI
Format/Info                              : Audio Video Interleave
File size                                : 73.0 MiB
Duration                                 : 5s 533ms
Overall bit rate                         : 111 Mbps
Writing application                      : Lavf54.6.100
Video
ID                                       : 0
Format                                   : YUV
Codec ID                                 : I420
Codec ID/Info                            : 8 bit Y plane followed by 8 bit 2x2 subsampled U and V planes.
Duration                                 : 5s 533ms
Bit rate                                 : 111 Mbps
Width                                    : 640 pixels
Height                                   : 480 pixels
Display aspect ratio                     : 4:3
Frame rate                               : 30.000 fps
Compression mode                         : Lossless
Bits/(Pixel*Frame)                       : 12.000
Stream size                              : 72.9 MiB (100%)

この形式、および私が使用しようとしている他の形式 (huffyuv HFYU など) は、http: //imgur.com/a/0OC4yのような効果になってしまうため、うまくいきません。私が想定しているのは、可逆圧縮であるはずの HFYU の場合、可逆圧縮またはクロマ サブサンプリングのいずれかです。あなたが見ているのは、私のビデオの赤いチャンネルです。3 つのチャンネルすべてを同時に見た場合、知覚効果は無視できますが、画像を正確に再構成することが不可欠です。

さらに、vlc などのメディア プレーヤーで古いファイルを再生できますが、opencv と完全に互換性がないことに突然気付きました。ビデオ キャプチャで古いファイルを開こうとすると、開く手順は正常に機能しますが、読み取り操作を実行しようとすると segfault が発生します。さらに、次のいずれかで書き込もうとすると:

CV_FOURCC(0,0,0,0)
0

Opencv は、何らかの理由で I420 にデフォルト設定されています。

次に、いくつかの代替コーデックを使用してみました。「DIB」は私にとってはうまくいくように思えます.opencv Webサイト(http://opencv.willowgarage.com/wiki/VideoCodecs)では、「推奨」コーデックとしてリストされています。ただし、これを使用しようとすると、次のメッセージが表示されます。

OpenCV-2.4.1/modules/highgui/src/cap_gstreamer.cpp:483: error: (-210) Gstreamer Opencv backend doesn't support this codec acutally. in function CvVideoWriter_GStreamer::open

Aborted (core dumped)

このコーデックの opencv ソースを確認したところ、次のことがわかりました。

cd OpenCV-2.4.1/modules
grep -i -r "CV_FOURCC" ./*
...
./highgui/src/cap_qt.cpp:    /*if( fourcc == CV_FOURCC( 'D', 'I', 'B', ' ' ))
./highgui/include/opencv2/highgui/highgui_c.h:#define CV_FOURCC_DEFAULT CV_FOURCC('I', 'Y', 'U', 'V') /* Use default codec for specified filename (Linux only) */

qt4 をインストールして、WITH_QT フラグを付けて再構成しようとしましたが、何も変わりませんでした。コードのその部分のコメントを外してopencvを再インストールしようとしましたが、それもうまくいきませんでした。

私の究極の目標は、あらゆる方法で効率的にビデオ ストリームを格納および取得し、各ピクセルに 16 ビットを使用することです (32float が正常に動作するように、完璧である必要はありません)。現在、16 ビットを赤と緑のチャネルにアンパックしています。これが、赤チャネルの 1 のエラーが最終結果で 256 倍になるため、完全にする必要がある理由です。利用可能な fourcc コードのいずれでも成功していません。

4

2 に答える 2

0

ほとんどの場合、コーデックをアンインストールまたは更新しました。新しいコーデックパックをインストールするか、ffmpegまたはgstreamerを更新してみてください

于 2012-07-22T12:50:19.430 に答える
0

私は少し前にこれを理解することになり、ついにみんなのためにそれを書く機会を得ました. ここで私の(かなりハックな)ソリューションを見ることができます:

http://denislantsman.com/?p=111


編集: ウェブサイトがダウンしているため、Wayback Machine から何が見つかるかを以下に要約します。

  • フレームを個別の PNG 画像として保存する
  • ffmpeg を実行して、OpenCV で開くことができるファイルを生成します。

    ffmpeg -i ./outimg/depth%d.png -vcodec png depth.mov

  • 次の Python スニペットは、個々のフレームを保存するのに役立つ場合があります

    std::ostringstream out_depth;
    ...
    expand_depth(playback.pDepthMap, expanded_depth, playback.rows, playback.cols);
    out_depth << root << "/outimg/depth" << framecount << ".png";
    cv::imwrite(out_depth.str(), expanded_depth);
    framecount++;
    

    ...

于 2012-08-31T03:07:51.770 に答える