2013-08-05 7 views
5

저는이 문제를 오랫동안 연구 해 왔으며 창의력이 끝나면 다른 누군가가 올바른 방향으로 나를 도와 줄 수 있기를 바랍니다. 저는 Kinect와 함께 MATLAB에 데이터를 캡처하려고했습니다. 다행히도 그렇게하는 데는 몇 가지 방법이 있습니다 (현재 http://www.mathworks.com/matlabcentral/fileexchange/30242-kinect-matlab을 사용하고 있습니다). 캡처 된 데이터를 3D로 투영하려고 시도했을 때 기존의 방식으로는 재구성 결과가 좋지 않았습니다.왜 색상과 깊이가 올바르게 정렬되지 않습니까?

짧게 요약하자면, 재구성 및 정렬을 수행하는 matlab 용 Kinect SDK 래퍼를 작성했습니다.

enter image description here

모델에 너무 가까이 보지 마십시오 : 재건은 당신이 여기에서 볼 수 있듯이 내가 정렬에 문제의 톤 데

... 꿈처럼 작동하지만 : 당신이 볼 수 있듯이 (.

, 정렬이 올바르지 않습니다. 나는 그런 경우 이유를 모르겠어요. 나는 다른 사람들이 같은 방법으로 I보다 더 많은 성공을 거두었습니다 포럼을 많이 읽었습니다.

현재 파이프 라인에서 Ki를 사용하고 있습니다. Kinect SDK를 사용하여 재구성 한 다음 Kinect SDK를 사용하여 정렬 (NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution)하여 Matlab (Openni 사용)에서 데이터를 캡처합니다. 아마 Openni 때문일 것으로 추측되었지만 Kinect SDK를 사용하여 캡처하기 위해 mex 함수 호출을 만드는 데 거의 성공하지 못했습니다.

누구든지 나를 더 깊게 파고 들어야하는 방향으로 나를 가리킬 수 있다면, 대단히 감사하겠습니다.

편집 :

그림 일부 코드를 게시해야합니다. 이것은 정렬을 위해 사용하는 코드입니다.

/* The matlab mex function */ 
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, 
      const mxArray *prhs[]){ 

     if(nrhs < 2) 
     { 
      printf("No depth input or color image specified!\n"); 
      mexErrMsgTxt("Input Error"); 
     } 

     int width = 640, height = 480; 

     // get input depth data 

     unsigned short *pDepthRow = (unsigned short*) mxGetData(prhs[0]); 
     unsigned char *pColorRow = (unsigned char*) mxGetData(prhs[1]); 

     // compute the warping 

     INuiSensor *sensor = CreateFirstConnected(); 
     long colorCoords[ 640*480*2 ]; 
     sensor->NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution(
       NUI_IMAGE_RESOLUTION_640x480, NUI_IMAGE_RESOLUTION_640x480, 
       640*480, pDepthRow, 640*480*2, colorCoords); 
     sensor->NuiShutdown(); 
     sensor->Release(); 

     // create matlab output; it's a column ordered matrix ;_; 

     int Jdimsc[3]; 
     Jdimsc[0]=height; 
     Jdimsc[1]=width; 
     Jdimsc[2]=3; 

     plhs[0] = mxCreateNumericArray(3, Jdimsc, mxUINT8_CLASS, mxREAL); 
     unsigned char *Iout = (unsigned char*)mxGetData(plhs[0]); 

     for(int x = 0; x < width; x++) 
      for(int y = 0; y < height; y++){ 

       int idx = (y*width + x)*2; 
       long c_x = colorCoords[ idx + 0 ]; 
       long c_y = colorCoords[ idx + 1 ]; 

       bool correct = (c_x >= 0 && c_x < width 
         && c_y >= 0 && c_y < height); 
       c_x = correct ? c_x : x; 
       c_y = correct ? c_y : y; 

       Iout[ 0*height*width + x*height + y ] = 
         pColorRow[ 0*height*width + c_x*height + c_y ]; 
       Iout[ 1*height*width + x*height + y ] = 
         pColorRow[ 1*height*width + c_x*height + c_y ]; 
       Iout[ 2*height*width + x*height + y ] = 
         pColorRow[ 2*height*width + c_x*height + c_y ]; 

      } 

    } 
+0

질문에 대한 답변이 관련성이 있고 문제를 해결했는지 다른 사람에게 알려야합니다. 그렇지 않다면 왜? 그것이이 커뮤니티가 작동하는 방식입니다. – masad

+0

masad하려면 : 네 답장을 보내 주셔서 감사합니다. 귀하의 답변이 아직 작동하는지 여부를 확인할 기회가 없었지만 지금하고 있습니다. 조금이라도 알려 드리겠습니다. – vsector

답변

5

이것은 스테레오 비전 시스템에서 잘 알려진 문제입니다. 나는 같은 문제를 가지고 있었다. 게시 한 원래 질문은 here입니다. 내가하려고 한 일은 이와 비슷한 일이었습니다. 그러나 많은 연구 끝에 포착 된 데이터 세트를 쉽게 정렬 할 수 없다는 결론에 도달했습니다.

반면 데이터 세트를 기록하는 동안 함수 호출을 사용하여 RGB 데이터와 깊이 데이터를 쉽게 정렬 할 수 있습니다. 이 방법은 OpenNI 및 Kinect SDK에서 모두 사용할 수 있습니다 (기능은 동일하지만 기능 호출의 이름은 각각 다릅니다)

Kinect SDK를 사용하여 데이터 세트를 캡처하고 Kinect SDK와 데이터를 정렬하는 것처럼 보입니다 MapDepthFrameToColorFrame을 사용할 수 있습니다.

OpenNI 사용에 관해 언급 했으므로 AlternativeViewPointCapability을 살펴보십시오.

depth.GetAlternativeViewPointCap().SetViewPoint(image); 

image 이미지 생성기 노드는 다음과 같습니다

나는 그러나 OpenNI 1.5 버전으로이 모든 문제가 레코더 노드를 등록하기 전에, 다음 함수를 호출하여 해결되었다, 키 넥트 SDK와 경험이 없다 depth은 깊이 생성기 노드입니다. 이 SDK는 OpenNI 2.0 SDK로 대체되었습니다. 따라서 최신 SDK를 사용하는 경우 함수 호출이 다를 수 있지만 전체 절차가 비슷할 수 있습니다.

나 또한 몇 가지 예제 이미지를 추가하고 : 거기에 깊이 가장자리가 완벽하게 정렬됩니다 함수 호출을 사용할 때 (위의 정렬 기능은 RGB에 깊이 가장자리 전화를 사용하지 않고

Without Alignment

정렬되지 않은 . With Alignment

+0

응답 해 주셔서 감사합니다. 나는 이미 정렬을 시도했지만 성공하지 못했습니다. 결국, 나는 올바른 호출을 사용하고 있었지만 Kinect는 여분의 "잡았다 (gotcha)"를 가지고 있습니다. "일반적인 NUI 문제 및 FAQ"(http://social.msdn.microsoft.com/Forums/en-US/4da8c75e-9aad-4dc3-bd83-d77ab4cd2f82/common-nui-problems-and-faq)에서 Kinect에서 얻은 깊이 값은 플레이어의 인덱스도 깊이 값에 저장되기 때문에 비트를 3만큼 시프트해야 함을 나타냅니다. 조정 후 원래 코드를 사용하여 정렬 작업이 정상적으로 작동합니다. 나는 당신의 연결없이 이것을 찾아 내지 못했을 것이다. – vsector

+1

나는 당신의 대답을 대답으로 정할 것이다. 그것은 또한 정렬의 문제에 대한 중요한 배경, 예제 및 코드를 제공하기 때문이다. – vsector

1

enter image description here depth.GetAlternativeViewPointCap() SetViewPoint (이미지)) 일부 모서리를 표시 일부 적외선 그림자 영역이 있지만, 그들은 단지 잘못된 깊이 영역이고;

잘 작동하지만 문제는 깊이 이미지를 (FOCAL_rgb/FOCAL_kinect로) 축소하고 불일치로 깊이 픽셀을 이동한다는 것입니다. d = focal * B/z; 공장 설정에 따라 약간의 회전이있을 수도 있습니다.

따라서 이러한 변환을 실행 취소하지 않고도 3 개의 실제 좌표를 모두 복구 할 수는 없습니다. 즉, 정확하게 x, y에 의존하지 않고 z를 고려한 (세분화와 같은) 메소드는 시프트 된 시프트 맵에서도 제대로 작동 할 수 있습니다. 또한 그들은 더 나은 세분화를 수행하기 위해 색상과 깊이를 이용할 수 있습니다.

1

Kinect SDK를 사용하여 U, V 텍스처 매핑 매개 변수를 읽어서 깊이 프레임과 색상 프레임을 쉽게 정렬 할 수 있습니다. 깊이 프레임 D (i, j)의 모든 픽셀 좌표 (i, j)에 대해 색상 프레임의 해당 픽셀 좌표는 (U (i, j), V (i, j)) C (U (i, j), V (i, j))에 의해 결정된다.

U, V 기능은 각 Kinect의 하드웨어에 포함되어 있으며 공장에서 하드웨어 보드에 부착 할 때 약간의 차이로 인해 깊이 카메라가 비디오 카메라와 다르게 정렬되므로 Kinect와 Kinect가 다릅니다. . 그러나 Kinect SDK에서 U, V를 읽으면 걱정할 필요가 없습니다.

public class Kinect extends J4KSDK{ 

    VideoFrame videoTexture; 

public Kinect() { 
    super(); 
    videoTexture=new VideoFrame(); 
} 

@Override 
public void onDepthFrameEvent(short[] packed_depth, int[] U, int V[]) { 
    DepthMap map=new DepthMap(depthWidth(),depthHeight(),packed_depth); 
    if(U!=null && V!=null) map.setUV(U,V,videoWidth(),videoHeight()); 
} 

@Override 
public void onVideoFrameEvent(byte[] data) {  
    videoTexture.update(videoWidth(), videoHeight(), data); 
} } 

같은 깊이 비디오 정렬 프레임의 3 개 가지 관점을 보여주는 이미지 예 : 내가 당신에게 이미지의 예와 J4K open source library 자바에서 키 넥트 SDK를 사용하여 실제 소스 코드 예제를 제공 아래

enter image description here

이 정보가 도움이 되었기를 바랍니다.