OpenCVで動画処理する際のメモリリーク

動画処理でメモリをバカ食いしてた件を解決したので書き残しておきます。参考記事に大感謝。

現象

15秒、フレーム数480の動画処理で実メモリを1GB以上使用しており、プログラム書き出しに支障が出ていた。

dst = cvCloneImage(src);//dstを処理

原因

フレームループ内にcvCloneImage()があったため。cvCloneImage()は暗黙的にメモリを使うためループさせればさせるほどメモリを使ってしまい、使ったメモリを解放する関数がない。

対策

必ずcvCopy()を用いてコピーしたものをループに用いる。

cvCopy(src, dst, NULL);//dstを処理
cvReleaseImage(& dst);//ループの外でこれを記述

結果

実メモリ40MB〜45MB付近で落ち着くようになりました。
卒論がんばっぞー。

参考記事URL

次回予告

Mac OS X 10.6+OpenCVで使えるcodec一覧とその特徴

Video I/O をQTKitでビルドしたOpenCVでこのページQTMovieのaddImage:forDuration: withAttributes:で使えるコーデック - Yanagi Entertainmentを参考にしながらいろいろなcodecを試してみました。時間があったら他のコーデックでも試してみます。

環境

Mac OS X version 10.6.5
Xcode 3.2.5 64-bit (IDE:1760.0, Core:1763.0, ToolSupport:1758.0)
Macports 1.9.2 for Snow Leopard
ffmpeg未インストール
OpenCV 2.2 rev.4303
Perian 1.2.1
QuickTime Player 10.0 (118)
QuickTime Player 7 7.6.6 (1710) (1756)

codec15種を試した結果をわかりやすいように表にまとめました

[変換元ファイルについて]
コンテナ:5.7MB、MPEG-4 ビデオ、Sony PSPプロファイル、codecID:"MSNV"
ビデオ:VGAサイズ、MPEG-4 Visual、ビットレート=固定、フレームレート=固定、プログレッシブ、不可逆圧縮

項目:スピードはmp4v基準で、あくまでも印象で判断したことを断っておきます。
FOUR_CCとは、codecの種類を示す4レターコードです。

FOUR_CC 使用可否 QTインスペクタ内名称 品質 圧縮スピード データサイズ その他特記事項
"mp4v" MPEG-4 (Perian) (基準) 22.63MB -
"avc1" H.264 高速 12.99MB ビットレート可変
"mjpb" Apple モーションJPEG B 高速 26.25MB ビットレート可変
"mjpa" Apple モーションJPEG A 高速 26.38MB ビットレート可変
"png " Apple PNG 中速 6.73MB ビットレート可変、可逆圧縮
"h263" H.263 高速 13.68MB ビットレート可変、サイズ変更
"mjp2" JPEG 2000 デコーダ 低速 33.68MB ビットレート可変、フレーム落ち発生
"yuv2" Appleコンポーネントビデオ - YUV422 低速 280.08MB -
"dvpp" DVCPRO 低速 65.64MB PAL、インターレース、YUV=4:1:1、サイズ変更
"raw " None 超低速 560.16MB ※ファイル容量と処理時間に注意
"h264" × (H.264) - - - -
"pim1" × (MPEG-1) - - - -
"mjpg" × (Motion-JPEG) - - - -
"y420" × (YUV420?) - - - -
"dib " × (非圧縮) - - - -

OpenCV格闘記 その1

前回の日記の最後にエラー吐くって言っていたけど、ようやく原因がわかったので記録しておきます。

内部エラーの概要

cvQueryFrame > cvConvertImage(swap RB) > cvCvtColor(RGB2GRAY) > cvCanny > cvWriteFrame
コンパイルは出来るけど、OpenCVの内部エラーを示すエラーメッセージがコンソールに表示される。

原因と解決法

  • cvQueryFrameで得たフレームを直接叩いていた為→cvCloneImageでクローンを作ったフレームを叩く
  • cvWriteFrameに暗黙の制限がある(?)→cvCannyの次にcvCvtColor(GRAY2BGR)ならいける(3chじゃないとマズいのかもしれない)

その他気づいたこと

  • cvSaveImageにはリファレンスにない隠された(?)3番目の引数がある。int型で圧縮品質のパラメータ。100が最高でデフォルトは95みたい。

cvGetCapturePropertyのCV_CAP_PROP_FRAME_COUNTでフレーム総数が取得出来ない

解決法

srcは入力(CvCapture*)、FRAMESはフレーム総数(int)

cvSetCaptureProperty(src, CV_CAP_PROP_POS_AVI_RATIO, 1);
FRAMES = (int)cvGetCaptureProperty(src, CV_CAP_PROP_POS_FRAMES);

フレーム総数がわかったら必ずリセットしておく!

cvSetCaptureProperty(src, CV_CAP_PROP_POS_AVI_RATIO, 0);//Reset video position
cvSetCaptureProperty(src, CV_CAP_PROP_POS_MSEC, 0);//Reset video position

フレーム総数の件はtwitterで教えてもらいました!けいそ氏(@sasrai)、ありがとう!><

Snow LeopardにOpenCVをインストールしてXcodeで使う

いろいろ大変だったのでここに記録しておきます。もっと他にいい方法があるかもしれません。

⌥=optionキー、⌘=commandキー、⇧=shiftキー、↩=enter[return]キー

環境

Mac OS X version 10.6.5
Xcode 3.2.4 (1708)
Macports 1.9.2 for Snow Leopard
OpenCV 2.1.1

手順

1. "Mac OS X Install DVD"を挿入し、"オプションインストール"フォルダ内のXcode.mpkgでXcodeをインストール。
2. 隠しファイルを表示させるため、ターミナルで以下を実行。

defaults write com.apple.finder AppleShowAllFiles TRUE

killall Finder


3. /usr/localが存在するか確認。なければ以下を作る。(いらない工程かもしれない)

  • /usr/local/bin
  • /usr/local/include
  • /usr/local/lib
  • /usr/local/share

4. Macports(disk image版)を導入。
5. /home/.profileに以下の記述があることを確認。なければ追記。(後者を追記することになると思う)

export PATH=/opt/local/bin:/opt/local/sbin:$PATH
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/lib/pkgconfig


/*** 以下ターミナル内での操作 ***/
6. Macports経由でpkgconfig, subversion, cmake, jpeg, tiff, libpngをインストールするため以下を実行。

sudo port install pkgconfig subversion cmake jpeg tiff libpng

↩ ->(パスワード入力)
インストールが終わったら一旦ターミナルを閉じて、今のアカウントからログアウト(⌥+⌘+⇧+Q)、再度ログインする。
7. 再びターミナル内。env↩、手順3で記述したPATHとPKG_CONFIG_PATHの項目が含まれているか確認する。svnで最新のOpenCVをダウンロード(チェックアウト)するため、ダウンロードしたいディレクトリに移行し以下を実行。(/homeで以下を実行すると/home/opencvが作られ、その中にいろいろ入ってくる。)

svn co https://code.ros.org/svn/opencv/trunk/opencv


ルート証明うんぬん言ってくるので承認する。ダウンロード後、

cd opencv

8. cmakeでOpenCVのインストールオプションをカスタム。以下を実行。

cmake .

ccmake .

9. ccmake実行中。Tキーを叩いてアドバンスモードにする。上下で項目移動、↩で編集またはON,OFF切り替えができる。編集中の場合は↩で編集完了。以下項目の内容を編集。

  • CMAKE_CXX_COMPILER /usr/bin/g++-4.0
  • CMAKE_C_COMPILER /usr/bin/gcc-4.0
  • CMAKE_C_FLAGS -m32
  • CMAKE_CXX_FLAGS -m32
  • CMAKE_OSX_ARCHITECTURES i386
  • WITH_1394 OFF
  • WITH_CARBON OFF
  • WITH_FFMPEG OFF

-WITH_QT ON
-WITH_QT_OPENGL ON

上位2項目はいらないかもしれない。他サイトに倣ってるだけ。デフォルトでは4.2だし...下位互換がないのかな?次3項目は強制的に32bitでビルドする為。その他はQTkitを使う為?-WITH_QTと-WITH_QT_OPENGLはQt用なので無関係。

    • Cキーを叩いた後、Gキーを叩く。ccmakeから抜ける。

10. makeしてinstallするため以下を実行。

sudo make -j8 && sudo make install

↩->(パスワード入力、ビルド完了後もう一回入力)

11. エラーなくインストールできたらサンプルファイルをコンパイルするための準備。

cd samples/c

12. あらかじめFinderウィンドウを開いておいて、ターミナルでpwd↩、出てきた文字列をコピー(⌘+C)。先ほどのFinderウィンドウを出して、フォルダへ移動(⌘+⇧+G)、ペースト(⌘+V)、OK。

13. "build_all.sh"をダブルクリックして以下を編集、保存。

  • 10行目: gcc -ggdb `pkg-... -> gcc-4.0 -ggdb `pkg-...
  • 14行目: g++ -ggdb `pkg-... -> g++-4.0 -ggdb `pkg-...

14. ターミナル内。コンパイルする為、以下実行。
エラーが出る場合はpkgconfigにパスが通っているか再度確認。

sh build_all.sh


成功したら ./lkdemo↩ で確認。他のバイナリファイルでも確認してみよう。

/*** ターミナル内の操作はここまで ***/

15. ~/opencv/unix-install/opencv.pc を以下にコピー。

  • /usr/local/lib/pkgconfig
  • /opt/local/lib/pkgconfig

16. ~/opencv/lib 内の全ファイルを以下にコピー。

  • /usr/local/lib
  • /opt/local/lib

17. ~/opencv/include/opencv 内の全ファイルを以下にコピー。

  • /usr/local/include
  • /opt/local/include

18. ~/opencv/lib 内のDynamic Libraryだけをプロジェクトファイル(.xcodeproj)がある(もしくは保存予定の)ディレクトリへコピー。


/*** 以下Xcodeの操作 ***/
19. 新規でXcodeプロジェクトを作る場合のテンプレートは Application - Command Line Tool (Type:C)を選択。

20. 情報を見る - 構成 - "Release" を複製 - 自由にリスト名をつける (intel_32bit) - "ビルドが使用するコマンドライン" にそれを必ずセットする。


21. ビルド - "構成" を複製したもの (intel_32bit) にセット - "表示" を すべての設定 にセット - アーキテクチャ グループ と 検索パス 以外のグループの▼をクリックしてたたむ。アーキテクチャ グループの値を以下の様にセット。それ以外の項目についてはそのまま。

※左下の-ボタンでi386以外を消せる。

22. 検索パス グループの値を以下の様にセット。それ以外の項目についてはそのまま。

  • 常にユーザーパスを検索 ☑
  • ヘッダ検索パス /opt/local/include と /usr/local/include の2項目
  • ライブラリ検索パス /opt/local/lib と /usr/local/lib の2項目

※両方とも左下の+ボタンで増やせる。

23. 情報ウィンドウを閉じて、新規グループ(⌥+⌘+N)、適当に名前を付ける (OpenCV_Framework)

24. プロジェクトに追加...(⌥+⌘+A)、".dylib"の拡張子を持つファイルを全て選択し追加。

追加。
25. プロジェクトの概要をintel_32bit | i386にする。
26. ビルドして実行(⌘+↩)で動くはず。

コンソール(⇧+⌘+R)で返り値やらエラーの詳細などを見ることができる。最近、Previous frame inner to this frame (gdb could not unwind past this frame)とエラー吐いてうまくいかない...orzなんでー!o(`ω´*)oプンスカプンスカ!!
→解決。詳細は次の日記へ。

追記

OpenCVのバージョンが2.2にあがってるのでインストールしました!
OpenCV 2.2 rev.4303