#OpenCVアドベントカレンダー2015の記事のまとめ
OpenCVをコアに理解するために理解するために,以下の順番で記事を読むと分かりやすいでしょう.(一部,アドベントカレンダーの記事ではないものも含まれてます.)
- OpenCVのモジュールの作られ方に関連する項目
- OpenCVのモジュールや関数自身の作られ方(このページ)
- 汎用入出力InputArray, OutputArrayの使い方(入門編)
- 汎用入出力InputArray, OutputArrayの使い方(応用編)
- cv::Pointやcv::Vecを入出力とする座標変換の演算の落とし穴
- Matのアロケータとガベージコレクション
- エラーコード,エラーメッセージ表示機能,例外処理機能
- CV_Assert, CV_DbgAssert, CV_StaticAssert
- 色とビット深度に応じて最適化された関数群
- UMatの内部処理
- HALモジュールと高速な数値計算ライブラリ
- 線形システム・最小二乗問題ソルバcv::solve (HALモジュールの例)
- 並列化クラスParallelLoopBodyとparallel_for_ (並列化した関数を自作するために)
- 並列化クラスParallelLoopBodyとparallel_for_ (OpenCVの関数を並列化するために)
- cv::Mat::forEachを使った高速なピクセル操作
- Algorithm基底クラスとFileStorage
- enum CV_**について
- OpenCVのRNG(Random Number Generator)クラスで乱数を生成
- まとめ
- モジュールの紹介や応用例
- ビルド方法
- もうすこし書けたらよかったな
- 並列化方法のもう少し詳しい説明
- 単体テストプロジェクトの作り方
- パフォーマンステストプロジェクトの作り方
- Matのfloat計算結果をの四捨五入する方法
- Algorithm基底クラスとFileStorageの基本的な使い方
- コマンドラインパーサ,XML保存など,実験のお供になるお役立ちツール紹介
#はじめに
このアドベントカレンダー中で連載する@fukushima1981の書く記事は,もっとより多くのOpenCVコードが公開されることを期待して書かれたものです.特に,OpenCVの関数を使うことよりも,新しい関数を作るために使われている関数や,デバッグするために使う関数など,あまり普段はつかわれない関数を中心に紹介する予定です.まず,第一回は,OpenCVのモジュールや関数について概説してきます.
もちろん,このテーマに関係ない記事も絶賛募集中です.
(このままだと,25日分埋めれる気がしません...埋まらないときは小ネタでもはさみます.)
#OpenCVのモジュールの作られ方
OpenCVの関数は,細かなモジュール単位に分割されており,それぞれのモジュールに対応するヘッダをincludeすることで各関数が使えるようになります.例えば,必須となるcoreモジュールや,画像のIOを担当するimgcodecsモジュール,GUIを担当するhighguiモジュール,基礎的な画像処理を担当するimgprocモジュールなどがあります.
そのOpenCVモジュールを作るためのプロジェクトのファイル構成として,主に5つのフォルダを含んでいます.
- ヘッダが入っているincludeフォルダ
- ソースが入っているsrcフォルダ
- 関数のパフォーマンスを計測するためのテストプロジェクトが含まれるperfフォルダ
- 単体テストをするためのプロジェクトが含まれるtestフォルダ
- ドキュメントやチュートリアルが含まれるdocフォルダ
つまり,全てのモジュールに対して原則,ドキュメントやチュートリアルが含まれ,単体テストとパフォーマンステストのプロジェクトがある状態を求められています.これは,外部からOpenCVに貢献するために公開されているcontribのプロジェクト (https://github.com/Itseez/opencv_contrib) に対しても同様です.
特に,(良くも悪くも)抜本的な仕様変更が頻繁にされているOpenCVでは,単体テストやパフォーマンステストのプロジェクトは,開発する上で非常に重要な要素になっています.(しかし,ステレオマッチングの関数は,2.4.10あたりの更新で,大きな規模のコア数に向けて並列化対応するコードに変わっており,残念ながら普通のマルチコアマシンだと性能がダウンしていることなどもテストからわかります...)
なお,OpenCV3.0から,ドキュメントの記述方式SphinxからDoxygenに変わっています.Sphinxのほうが,読みやすいドキュメントが生成されると思いますが,更新頻度や管理の関係から変更したのでしょうか?
#OpenCVの関数の作られ方
OpenCVの関数は,2通りの形式で作られていることが多いです.
一つ目は,通常の関数で作る方法(大体この方法で実装されています)と二つ目はAlgorithmクラスを継承して作る方法(複雑なアルゴリズムはこちらで作りたい)です.
##(1) 通常の関数で作る方法
- OpenCVの関数は,InputArrayで入力データをOutputArrayで出力データを引数にとり関数に入ります.
- その後,CV_Assertなどで,受け付けない入力データの型が入ってきたら例外を出すなどの処理を記述します.
- 次に,Intelから提供されている高速化された画像処理ライブラリであるのippの関数の有無をチェックし,あるようならippの関数を呼びます.
- 無いようなら,並列化した関数を呼び出すためにcv::ParallelLoopBodyを継承した並列化用のclassを定義した後,そのclassをparallel_for_で呼び出して並列化実行します.
- これらは,入力の型のdepthやchannlesの数に応じて適切な関数やクラスが呼び出されるように設定されています.
- 最後に出力形式にあわせてキャストしたり四捨五入したりしした後に出力します.
##(2) Algorithmクラスを継承して作る方法
特徴点抽出やHDRなど,少し複雑で,多数のアルゴリズムが提案されている機能がこの形式で作られてほしいなぁという感じで作られていますが,全てこの形式に対応しているわけではなりません.このクラスには,パラメータの保存,呼び出し,パラメータの全表示など,複雑なアルゴリズムにとってあるとうれしい機能が付いています.
- Algorithmクラスを基底として継承しつつ,アルゴリズム全体を現す抽象クラス(特徴点抽出とかHDRトーンマップなど)をまず定義されます.(Algorithmも抽象クラスです.)
- 各アルゴリズムの実装クラス(Implが付いているクラス)で中身が定義されます.
- 各メソッドが作られます.メソッドの作り方は上記関数の作り方と同じです.
現在,どのような関数・クラスがAlgorithmクラスで実装されているか,ドキュメントを見ればわかります.
http://docs.opencv.org/master/d3/d46/classcv_1_1Algorithm.html#gsc.tab=0
#まとめ
OpenCVの関数の作られ方の概略を述べました.
上記目次にある関連記事を読むことでより詳細な作り方がわかります.