일단 UV-disparity map을 생성하기 위해서는 disparity map을 만드는 것이 필요하다.
이를 위하여 SGM(Semi Global Matching)을 사용하였다.
이론적인 내용은 일단 다 뒤로하고 구현 과정 중에 발생한 여러 문제들과 해결방법에 대하여 정리를 해보자.
SGM을 직접 코딩을 해서 구현하기 보다, git에 있는 오픈 소스를 사용하였다.
https://github.com/gishi523/semi-global-matching
일단, 코드 컴파일을 위하여 Visual Studio 15 및 OpenCV 3.2 버전이 컴퓨터에 설치되어 있다.
그럼 VS15에 OpenCV 개발환경을 구축한 뒤에, 위에서 다운받은
main.cpp
semi_global_matching.cpp
semi_global_matching.h
총 3개의 파일의 내용을 복붙해서 실행해보았다.
실험을 위한 Stereo image dataset으로 일단 cone, teddy를 사용하였다.
cone과 teddy 등 다양하게 스테레오 비전에서 사용하는 dataset은 아래 링크에서 다운받을 수 있다.
http://vision.middlebury.edu/stereo/data/
실행을 해보니 아래와 같이 __popcnt64 에러가 발생했다.
해결 방법이 맞는지는 모르지만, 일단은 OpenCV install 빌드할때 x86으로 빌드를 해서 사용하였기 때문에
x64 랑 안맞아서 그러지 않을까 했다.
그래서 그냥 저거 들어가는 부분은 전부 주석처리를 하였더니 더이상 오류는 뜨지 않았다. (당연....)
이제는 빌드에는 문제가 발생하지 않았다.
대신에 명령프롬프트를 이용하여 실행파일을 실행해보니
요딴 에러가 발생했다....
이건 또 머지... 라는 생각을 하며
일단 CV_8U라는 것을 자세히 찾아보았다.
CV_8U는 0~255까지 값을 가지는 unsigned Char 형식이라는 말인데,
채널 정보가 없어서 처음에는 CV_8U가 채널에 상관없이 모든 CV_8U,
즉, CV_8UC1, CV_8UC2, CV_8UC3 등 을 아우르는 마스터키 같은 거일줄 알았지만
자세히 찾아보니
CV_8U = CV_8UC1 이라는 것이었다!!!
즉, unsigned char크기를 가지는 Grayscale 이미지라는 것이었다.
그래서 보통 입력 영상의 형식이 CV_8UC3이므로 이거를 CV_8UC1으로 바꿔야되었다.
그래서 위와 같은 convertTo 함수를 기존에는 썻는데, 잘 되지 않아서 찾아보니
같은 크기영역, 즉, 같은 8U에서 채널만 바꿀때는 convertTo가 아니라 아래와 같이 cvtColor를 써야한다는 것이었다.
그래서 아래와 같이 코드를 변경해주니, 제대로 동작하였다.
또한, UV-disparity를 위하여 아래와 같은 코드를 넣어서 영상을 출력해보았다.
double max, min;
cv::minMaxLoc(draw, &min, &max);
std::cout << min << "\t" << max << std::endl;
cv::Mat vdis = cv::Mat(draw.rows, (draw.cols + max) / 2, CV_8UC1,cv::Scalar(0));
for (int i = 0; i < draw.rows ; i++)
{
for (int j = 0; j < draw.cols ; j++)
{
vdis.at<uchar>(i, draw.at<uchar>(i, j)) += 1;
}
}
cv::applyColorMap(vdis, vdis, cv::COLORMAP_JET);
cv::imshow("vdisparity", vdis);
cv::Mat udis = cv::Mat(max, draw.cols, CV_8UC1, cv::Scalar(0));
for (int i = 0; i < draw.cols; i++)
{
for (int j = 0; j < draw.rows; j++)
{
udis.at<uchar>(draw.at<uchar>(j, i), i) += 1;
}
}
cv::applyColorMap(udis, udis, cv::COLORMAP_JET);
cv::imshow("udisparity", udis);
<Cone Dataset>
<Teddy Dataset>
근데, UV-disparity map을 만들때 가장 헷갈렸던 점은 at을 할때의 (x,y) 좌표였다.
이 부분에 대해서는 조금더 정리를 한 다음, 따로 글을 올려야겠다.
'영상처리' 카테고리의 다른 글
[OpenCV 3.2] 비디오 영상으로부터 findcontours 적용 (0) | 2019.03.28 |
---|---|
[OpenCV 3.2] findcontours 함수를 이용한 외곽선 검출 (0) | 2019.03.28 |
OpenCV 3.2를 이용한 웸캡 입출력 코드 (0) | 2019.02.11 |
다양한 색공간에 대한 이해 (0) | 2019.01.22 |