OpenCV 3.1がリリースされたらしいのでC++でSGBMを試してみる
OpenCVのChangeLogによれば、OpenCV3.1において
“Recent advances in edge-aware filtering, improved SGBM stereo algorithm” – opencv/calib3d and opencv_contrib/ximgproc (Alexander Bokov, Maksim Shabunin)
らしいので、SGBMを試してみようと思う。
というか、バージョンアップによりstereoSGBMの実行の仕方が変わっているので、各種ハウツーを紹介しているサイトの 情報が今回のバージョンでは使えないので、メモ的な側面が強い。
なお、今回のプログラムはかなり手探りで書いたので、書き方が間違っている・こう書いたほうがスマートだとかいうのは超コメントが欲しい。
ソース
まずはクラスを用意する。StereoSGBM::create
関数ってのに変わっていて戸惑った。パラメータは適当である。
int window_size = 3; int minDisparity = 0; int numDisparities = 32; int blockSize = 3; int P1 = 8 * 3 * window_size * window_size; int P2 = 32 * 3 * window_size * window_size; int disp12MaxDiff = 1; int preFilterCap = 0; int uniquenessRatio = 10; int speckleWindowSize = 100; int speckleRange = 32; cv::Ptr<cv::StereoSGBM> ssgbm = cv::StereoSGBM::create( minDisparity, numDisparities, blockSize, P1, P2, disp12MaxDiff, preFilterCap, uniquenessRatio, speckleWindowSize , speckleRange, cv::StereoSGBM::MODE_SGBM);
画像をロードする。あんまり画素数が多いとうまく結果が出ないので適宜cv::pyrDown
関数などでダウンサンプリングしてあげたほうが良い。
cv::Mat imgLeft = cv::imread(strImageNameLeft,1); cv::Mat imgRight = cv::imread(strImageNameRight,1);
結果を格納するためのMatを用意する。stereoSGBMの計算結果はCV_16Sで格納される。
cv::Mat disparity; //((cv::MatSize)leftImg.size, CV_16S);
ssgbm->compute(imgLeft,imgRight, disparity);
結果を表示する。0~255の値にしてやってグレースケールで表示する。
cv::Mat disparity_map; double min, max; cv::minMaxLoc(disparity, &min, &max); disparity.convertTo(disparity_map, CV_8UC1, 255.0 / (max - min), -255.0 * min / (max - min)); cv::imshow("result", disparity_map);
大体こんな感じだろうか。過去のバージョンと結果を比較できるとよいなぁ。