[Stereo Vision] Disparity Map 생성
1. Disparity Map 이란?
Disparity는 Stereo 정합을 위한 두 이미지(left image, right image, 또는 왼쪽에서 보는 시야와 오른쪽에서 보는 시야를 말함)에서의 객체의 위치 상의 다른 차이를 말한다. 이 차이를 parallax 하게 만드는 것을 Disparity Map 이라고 한다. 우리의 뇌는 2차원 이미지로부터 Depth information을 계산하여 disparity를 계산하게 된다.
간단히 말해서 Pixel의 Disparity는 그 픽셀에 대한 최소 제곱 합들의 Shift value와 같다.
Disparity 는 왼쪽 시야와 오른쪽 시야로부터 보이는 특징의 position 사이의 2D vector라고 설명할 수 있다. 이는 깊이에 반비례하고, 3차원 위치에 (x, y, d) 점으로부터 mapping 될 수 있다.
2. Calculating Disparity Map
이미지들은 SSD/SAD 윈도우 연산에 용이하게 하기 위해 zero pixels의 frame으로 채워진다. (SSD - Sum of Squared Differences SAD - Sum of Absolute Differences)
1) 먼저 차이의 제곱이나 절대적인 차이를 화소마다 계산하고, 모든 값을 window W에 더한다.
2) 오른쪽 이미지의 각 shift value 값은 이미지 크기와 동일한 SSD / SAD map이다. Disparity Map은 3차원 공간에서부터 줄어든 2차원 Map이다. Pixel의 차이는 픽셀의 SSD/SAD 최소 시프트 값과 동일하다.
3. OpenCV를 이용한 Disparity Map 생성
OpenCV 레퍼런스에 나와있기도 하고, 3.1.0 버전에 포함되어있는 StereoMatcher 클래스에 포함되어있는 StereoBM, StereoSGBM을 사용함으로써 Disparity Map을 생성할 수 있다. 다음과 같은 구조로 구성되어있다.
[그림 1] StereoMatcher의 클래스 구성도
3.1 StereoBM or StereoSGBM 을 사용하기 위한 공통 코드
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/contrib/contrib.hpp"
#include <stdio.h>
using namespace cv;
using namespace std;
Load Images and initialize parameters.
Mat img1, img2, g1, g2;
Mat disp, disp8;
img1 = imread("leftImage.jpg");
img2 = imread("rightImage.jpg");
cvtColor(img1, g1, CV_BGR2GRAY);
cvtColor(img2, g2, CV_BGR2GRAY);
<< 이 부분에 StereoBM 코드 또는 StereoSGBM 코드 추가 >>
imshow("left", img1);
imshow("right", img2);
imshow("disp", disp8);
3.2 StereoBM 코드 일부
StereoBM sbm;
sbm.state->SADWindowSize = 9;
sbm.state->numberOfDisparities = 112;
sbm.state->preFilterSize = 5;
sbm.state->preFilterCap = 61;
sbm.state->minDisparity = -39;
sbm.state->textureThreshold = 507;
sbm.state->uniquenessRatio = 0;
sbm.state->speckleWindowSize = 0;
sbm.state->speckleRange = 8;
sbm.state->disp12MaxDiff = 1;
- minDisparity – Minimum possible disparity value.
- numDisparities – Maximum disparity minus minimum disparity. This parameter must be divisible by 16.
- SADWindowSize – Matched block size. It must be an odd number >=1 .
- disp12MaxDiff – Maximum allowed difference (in integer pixel units) in the left-right disparity check.
- preFilterCap – Truncation value for the prefiltered image pixels.
- uniquenessRatio – Margin in percentage by which the best (minimum) computed cost function value should “win” the second best value to consider the found match correct. Normally, a value within the 5-15 range is good enough.
- speckleWindowSize – Maximum size of smooth disparity regions to consider their noise speckles and invalidate.
- speckleRange – Maximum disparity variation within each connected component.
And compute Disparity. Since Disparity will be either CV_16S
or CV_32F
, it needs to be compressed and normalized to CV_8U
sbm(g1, g2, disp);
normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U);
3.3 StereoSGBM 코드 일부
StereoSGBM sgbm;
sgbm.SADWindowSize = 5;
sgbm.numberOfDisparities = 192;
sgbm.preFilterCap = 4;
sgbm.minDisparity = -64;
sgbm.uniquenessRatio = 1;
sgbm.speckleWindowSize = 150;
sgbm.speckleRange = 2;
sgbm.disp12MaxDiff = 10;
sgbm.fullDP = false;
sgbm.P1 = 600;
sgbm.P2 = 2400;
Notice there are few parameters different from StereoBM. Compute Disparity and normalize. You should look at OpenCV documentation for detailed information.
sgbm(g1, g2, disp);
normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U);
[그림 2] StereoBM 사용한 DepthMap 생성
[그림 3] StereoSGBM 사용한 DepthMap 생성
확실히 초당 프레임 수준은 StereoBM이 더 좋고 속도가 빠르나, 불분명하다 (파라미터 조절을 더 해야 한다...), 반면 StereoSGBM은 느리지만 정확한 결과를 생성할 수 있다는 것을 확인했다. 전처리 기법을 하여 더 Robust한.. Depth Image 생성을 해야겠다.
참고자료 1 : http://www.jayrambhia.com/blog/disparity-mpas
참고자료 2 : http://docs.opencv.org/master/d9/dba/classcv_1_1StereoBM.html#details
참고자료 3 : http://docs.opencv.org/master/d2/d85/classcv_1_1StereoSGBM.html
참고자료 4 : http://answers.opencv.org/question/29392/big-different-between-stereosgbm-and-gpustereobm_gpu/
참고자료 5 : http://docs.opencv.org/master/d9/dba/classcv_1_1StereoBM.html
참고자료 6 : http://davidpritchard.org/graphics/msc_thesis/4_Disparity_Map.html
'AI Research Topic > 3D Reconstruction' 카테고리의 다른 글
[Stereo Vision] kinect 설치하기 (Visual Studio 2015, Windows 10, 64 bit, usb 3.0) (0) | 2017.01.19 |
---|---|
[3D Reconstruction] Trifocal tensor 정리 (0) | 2016.12.27 |
[Stereo Vision] Epipolar Geometry (에피폴라 기하학) (3) | 2016.10.26 |
[Stereo Vision] Stereo Image Processing (0) | 2016.07.12 |
[3D Reconstruction] 3D Reconstruction 접근법 (1) | 2016.04.12 |