引き続きOpenCV 1.1preについて。
カメラキャリブレーション・ステレオ処理関連でいろいろ調べています。
ステレオカメラでの歪み補正用関数が増えてるのはありがたいんですが、
その関数の引数が15個とかあったりするので使うのがちょっと大変;
あと、距離計測アルゴリズムのベースであるブロックマッチングとグラフカット。
これらは速度と精度のトレードオフになっています。
ChangeLogのブロックマッチング法に関する記述、
*processes the Tsukuba stereo pair in <10ms on Core2Duo laptop
という内容が本当かどうか確かめてみました。
環境はCore2Duo 3.0GHz, 2GB RAMのマシン、検証画像は同じTsukuba stereo pairです。
この画像はステレオ画像処理分野では大変有名ですね。
・出力:距離画像 (ブロックマッチング) (距離が近い:白、距離が遠い:黒)
個人的に精度はこれで満足だったりします。
処理時間はcvGetTickCount()で計測して15~20msくらいでした。
10ms以下とはいきませんでしたが、それでも十分な速度が出ています。
グラフカットベースの方も試しました。(参考文献 → pdf)
この手法はエネルギー最小化問題を画像処理に応用したもので、ちょうど僕の研究分野とも関係しています。
・出力:距離画像 (グラフカット)
こちらはしっかりと領域分割されていてグラフカット法の性質がよく表れています。
non-realtimeとリファレンスにもあるように、処理には2秒ちょっとかかりました。
テスト用の簡易コード(C++)を載せておきます。(コマンドラインでステレオペア画像を指定)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// 距離計測(グラフカット) #include <cv.h> #include <highgui.h> #include <cvwimage.h> int main(int argc, char **argv) { cv::WImageBuffer1_b left, right, dst; // 符号なし8ビット, 1チャンネル cv::WImageBuffer1_16s dispLeft, dispRight; // 符号付き16ビット, 1チャンネル CvStereoGCState *state = cvCreateStereoGCState(16, 2); //距離計測(GC版)用 構造体 CvSize size; const char *winName = "Stereo Correspondence"; assert(argc == 3); left.SetIpl(cvLoadImage(argv[1], 0)); // 入力画像:左 right.SetIpl(cvLoadImage(argv[2], 0)); // 入力画像:右 // 領域確保 size = cvGetSize(left.Ipl()); dispLeft.Allocate(size.width, size.height); dispRight.Allocate(size.width, size.height); dst.Allocate(size.width, size.height); // 距離計測とスケーリング cvFindStereoCorrespondenceGC(left.Ipl(), right.Ipl(), dispLeft.Ipl(), dispRight.Ipl(), state, 0); cvConvertScale(dispLeft.Ipl(), dst.Ipl(), -16); // 出力画像表示 cvNamedWindow(winName, CV_WINDOW_AUTOSIZE); cvShowImage(winName, dst.Ipl()); cvWaitKey(0); cvReleaseStereoGCState(&state); cvDestroyAllWindows(); return 0; } |
上のコードでは1.1preで新しく追加されたWImageクラスを使っています。
このクラスの詳細は後で別エントリーかTech Noteにまとめておくつもりなのでここでは省略。
今後はカメラキャリブレーション周りについて調べていくつもりです。
One thought