기본적으로 키넥트를 쓰는 이유중 한가지가 바로 Point cloud 때문이지 않을까 생각됩니다.

 

이는 여러 분야에서 아주 범용적으로 쓰이는 유용한 데이터 라고도 할 수 있겠네요.

 

Kinect를 활용하여 Point cloud를 만들기 위해서는 두가지의 다른 영상정보 (RGB, Depth (or Z)) 를 정합을 해야 합니다.

 

이는 Kinect v1.0때도 마찬가지였지만, v2.0에서도 방법이 있지 않을까 해서 해당 방법을 알아보았습니다.

 

역시 클래스와 함수로 잘 정리 되어있었네요.

 

아래 링크를 들어가보시면 아시겠지만, 이번 SDK 에서 확실하게 강화시켜 놓았습니다.

 

CoordinateMapper Class가 따로 있고, 밑에는 해당 methods 들이 나열 되어있는것을 확인 하실수 있어요.

 

http://msdn.microsoft.com/en-us/library/windowspreview.kinect.coordinatemapper.aspx

 

더욱 더 인상 적인점은, 키넥트 1.0 에서는 없었던 RGB camera to IR camera mapping 기능이 들어있습니다.

 

(저는 이 방법이 필요해서 직접 구현을 했다만.. 이제는 편해졌네요 ㅎㅎ)

 

 

 

 

아래는 저의 소스 및 결과물 입니다.

 

RGB 영상 좌표를 Depth 영상 좌표로 변환, 매핑하는 방법인데요,간단히 설명 드리면..

 

1. RGB 영상의 좌표정보(혹은 RGB coordinate's array)을 Depth 영상 좌표에 맞게 변환 (MapColorFrameToDepthSpace 함수 사용)

 

2. 변환된 RGB 영상 좌표정보를 활용하여 2가지 영상을 제작

a. Depth 영상 해상도 (512 X 424) 로 변환

b. RGB 영상 해상도 (1920 X 1080) 로 변환 

 

RGB to Depth resolution 결과물 (a) 영상에서는 노이즈를 보실수 있습니다.

 

이는 제가 겪었던 문제와 동일한데, 정수형의 픽셀배열이 사영변환 (projective transformation)을 통해서 재배치 될때 좌표가 실수형으로 바뀝니다. 

 

그리고 영상을 출력시 다시 정수형 좌표계(pixel coordinate)로 표현이 되는데, 이때 소숫점 자리는 무시가 됩니다. 

 

따라서, 결과적으로 픽셀 사이에 빈 공간이 생기게 되고, 이것이 저런 노이즈로 나타나게 됩니다.

 

 

 

 

아무튼 아래 소스코드들을 참고하셔서 활용하시면 될듯 하네요. (맘에 드신다면요.. ㅎㅎ)

 

 

 

 

RGB 영상 (1920 X 1080)

 

Depth 영상 (512 X 424)

 

a. Depth 영상 해상도 (512 X 424) 로 변환

 

b. RGB 영상 해상도 (1920 X 1080) 로 변환 

 

 

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
    //RGB frame to Depth space
    m_pCoordiMapper->MapColorFrameToDepthSpace(_IR_Width_ * _IR_Height_, m_pRealDepth, _Color_Width_ * _Color_Height_, m_pDepthSpacePoint);
 
    for(int h = 0; h < _Color_Height_; h++)
    {
        for(int w = 0; w < _Color_Width_; w++)
        {
            index = h*_Color_Width_+w;
            _X = (int)(floor(m_pDepthSpacePoint[index].X + 0.5f));
            _Y = (int)(floor(m_pDepthSpacePoint[index].Y + 0.5f));
 
            if ((_X >= 0) && (_X < _Color_Width_) && (_Y >= 0) && (_Y < _Color_Height_))
            {
                index_3_DtoRGB = h * m_pCVMgr->m_pImg_3_Merge_DtoRGB->widthStep + w * m_pCVMgr->m_pImg_3_Merge_DtoRGB->nChannels;
                index_3_RGBtoD = _Y * m_pCVMgr->m_pImg_3_Merge_RGBtoD->widthStep + _X *m_pCVMgr->m_pImg_3_Merge_RGBtoD->nChannels;
 
                //DepthtoRGB resolution
                m_pCVMgr->m_pImg_3_Merge_DtoRGB->imageData[index_3_DtoRGB] = m_pColorRGBX[index].rgbBlue;
                m_pCVMgr->m_pImg_3_Merge_DtoRGB->imageData[index_3_DtoRGB+1= m_pColorRGBX[index].rgbGreen;
                m_pCVMgr->m_pImg_3_Merge_DtoRGB->imageData[index_3_DtoRGB+2= m_pColorRGBX[index].rgbRed;
                //RGBtoDepth resolution
                m_pCVMgr->m_pImg_3_Merge_RGBtoD->imageData[index_3_RGBtoD] = m_pColorRGBX[index].rgbBlue;
                m_pCVMgr->m_pImg_3_Merge_RGBtoD->imageData[index_3_RGBtoD+1= m_pColorRGBX[index].rgbGreen;
                m_pCVMgr->m_pImg_3_Merge_RGBtoD->imageData[index_3_RGBtoD+2= m_pColorRGBX[index].rgbRed;
            }
        }
    }
cs

 

 

 

 

 

2015/10/29 - [[ Topics ]/Kinect 2.0] - Kinect 2.0 & Kinect SDK 2.0 (Sample source code uploaded)

 

2012/04/24 - [[ Topics ]/Kinect 1.0] - RGB 이미지와 Depth 이미지의 Calibration

 

2013/05/22 - [[ Topics ]/Kinect 2.0] - Xbox One & Kinect2 are announced!!

 

2013/03/26 - [[ Topics ]/3Gear System SDK] - 3Gear System SDK - Kinect Positioning and Setting

 

 

 

 

Posted by Tommy™
,

오랫만에 새글을 작성하는거 같다.

 

춘계 멀티미디어 학회 준비도 그렇고 연구실 프로젝트도 그렇고 이런저런 일이 겹쳐서 너무 정신없었던 나머지 업데이트도 하지 못했다.

 

어째뜬, 오늘 글을 끄적이는 주제는 RGB 이미지와 Depth 이미지의 Calibration 인데, 관련 자료를 찾아보는데, 너무나도 많은 시간을 허비한거 같다.

 

외국사이트에서는 OpenNI를 이용하여 RGB 와 Depth 카메라 각각에 접근, 체스보드판을 촬영하여 정확한 Calibration 값을 추출하여 Point Cloud를 구성 하는것을 많이 봤지만, SDK를 활용해서 만든 자료는 거의 없었다.

 

하지만 이번에 SDK 버전이 1.0으로 업뎃이 되면서 이런저런 좋은 함수가 지원이 되는데, 그중에 쓸만한것 2개정도만 간추려서 소개를 해볼까 한다.

 

각 함수의 매개변수는 구글에 복사해서 엔터키 땅 때리면 쫘르륵~~ 나오니깐 검색해보시길..

 

(솔직히 귀찮은것도..?? 하하..ㅋㅋㅋㅋ)

 

첫째. NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution()

 

아래 사진은 그 결과물이다.

 

하지만 결과물은.. 썩 맘에 들지 않는다. 왜냐하면 Depth 이미지가 오른쪽으로 2~3픽셀씩 시프팅 된거 같은데, 수동으로 반대로 이동 시키면 나머지 부분이 좀 매칭이 안되는 경향이 있다.

 

그래서... 패스!!

 

관련 함수 사용한 홈페이지의 레퍼런스 : http://kassymemo.blogspot.com/2012/04/kinect-for-windows-sdk3.html

 

 

두번째. NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution()

 

이함수는 결과물을 보면 알수있겠지만 어느정도 매칭이 되는것을 확인 할수가 있다.

 

너무나도 맘에 든다.

 

좀 울렁 거리는게 있지만, 저건 뭐 Image Processing 작업을 통해 해결 할수 있을거라 생각하고..

 

관련 함수 레퍼런스 링크 : http://stackoverflow.com/questions/10117396/trouble-fitting-depth-image-to-rgb-image-using-kinect-1-0-sdk

 

아래에는 관련 결과물을 촬영한 영상이다.

 

 

 

 

이제 Calibration 작업을 진행했으니 , 아마도 다음은 OpenGL 을 MFC에 붙여서 Point Cloud 환경을 구성하지 싶다.

그리고 이전에 진행하던 핸드트래킹 시스템을 Point Cloud 시스템에 붙여서 더욱 디테일 한 환경을 만들어보고싶다. 얼마나 걸릴지 모르지만..ㅋㅋ

앞으로 갈길은 정말 멀고도 험하구만.. 하지만 재밋다. 정말로 ^^

앞으로 어떠한 역경이 나를 또 괴롭힐지.. ㅎㅎ

 

------------------------------------------------------------------------------------


해당 프로젝트 파일을 원하시는 분들이 많아서 자로 함께 첨부합니다.

오래전 파일이라서 새로 프로젝트 파일 작성했구요,

구동환경은 VS2012, OpenCV 2.4.2, C++, Kinect SDK 1.8 이구요, Console 에서 구동 합니다.

RGB영상에 맞게 Depth 정보를 매핑 시키는 프로그램이구요, 이를 응용 및 활용하면 Point cloud 도 생성 가능합니다.


Kinect_DepthCalib_in_console(RGB, Depth with calib, OpenCV).vol1.egg


Kinect_DepthCalib_in_console(RGB, Depth with calib, OpenCV).vol2.egg


------------------------------------------------------------------------------------





Posted by Tommy™
,