티스토리 뷰

드디어 DepthStream에 관한 세번째내용이군요. 지난 포스팅을 통해서 손가락을 추적할 수 있는 원리에 대해 잠깐 언급해봤습니다. 이제 이걸 토대로 마우스 커서를 만들어보고자 합니다.

그 전에 앞서서 Resolution을 조절하는 방법에 대해서 언급해보고자합니다. 기존 프로젝트를 수정하는 선에서 진행하겠습니다. 전의 결과물을 보셨으면 아시겠지만 명암의 차이를 조금 알아보기가 힘들었지요.


이 결과에 영향을 끼치는 부분은 바로 여기입니다.


5bit씩 shift되어 있는 부분을 아래와 같이


4bit만 shift하면 어떻게 될까요?


뭔가 뚜렷해진 결과가 보이시나요? 사실 정확한 결과는 위의 사진이 맞습니다. 분명 16bit중 5bit shift를 시켜야 컬러로 다시 뿌릴 수 있는 정보로 받는거지요. 하지만 너무 높은 해상도는 오히려 사물을 인지하는데 방해가 될 수 있는 겁니다. 그만큼 오차에 대해서도 민감해지고요. 그래서 Color 정보로 낼때 한 bit을 더 내보내고 오차를 넓힌겁니다. 그만큼 noise에 대한 jitter도 줄어들게 됩니다. 문서에서는 이로 인한 효과로 기존 5bit shift했을때 1mm의 차이 인식을 4bit shift함으로써 16mm의 차이인식으로 변화시켰다고 하네요. 이를 이용하려고 합니다.

자 지난번에 손가락을 인식하는 것도 보았지만 여러개가 인식범위안에 들어갔을때는 어떻게 처리하는게 좋을까요?
이 문서에서는 인식된 값들의 평균값들을 내서 그 위치를 커서로 잡는 것을 언급했습니다. 그걸 따라가보겠습니다.

Color형 배열이 있는 곳 밑을 지우고 이곳에 새로운 변수를 지정합니다. 바로 인식된 값들의 x의 값들의 합과 y값들의 합 그리고 인식된 형태의 갯수말입니다.


이제 이 변수들에 대한 조건문을 작성해야 겠지요. 


물론 가장 가까운 지점일때를 인지할때만 활성화되어야합니다.

이제 여기서 원리에 대한 설명이 조금 들어가야 될 듯합니다.

우리는 DepthByte라는 정보를 통해서 그 시간까지 받아둔 모든 DepthStream 정보를 모두 가지고 있고 그중 키넥트와 가장 가까운 곳의 위치에 대한 정보를 closesetByte란 정보로 뺐습니다. 그런데 우리는 이를 byte형 1차원 배열로 저장합니다. 


지금 XNA상에서 DepthStream을 뽑았을때 해상도는 640*480입니다.
가령 위의 사진과 같이 (300,2)의 위치에 있는 pixel의 정보를 뽑기 위해서는 가장가까운 closestByte를 찾기위해서 몇번의 과정을 거쳐야 할까요? 1차월 배열이란 점을 주목했을때 이 과정은 1580번의 과정을 거쳐야 합니다. 즉 i값이 1580이 되어야 해당 픽셀 정보를 찾을 수 있는 겁니다. 바로 순차적으로 픽셀에 대한 정보를 읽기 때문이지요. 
이번 프로그램에서는 이 정보를 x와 y라는 변수를 따뤄둬서 기존에 받았던 배열의 위치를 x와 y로 변환시키는 작업을 추가했습니다. 이에 대한 구문은 다음과 같습니다.


생각해세요. 1580에서 300이란 값을 구하기 위해서는 640으로 나눠서 나머지를 구하면 되는 것이고 2는 640으로 나눴을때의 몫으로 생각하면 되는 겁니다. 이걸 total값과 count에 삽입하면 되는 겁니다. 조건문에 대한 완성코드는 다음과 같습니다.

 
이제 정확한 x와 y 값은 count값으로 나눠주면 됩니다. 이에 대한 자료형은 float형으로 합니다 왜냐면 정확해야 하니까..


참 이전에 실제로 전역적으로 쓸 변수가 필요합니다. 가장 바깥의 자료형 선언 부분에서 다음 변수를 선언해줍니다.


그리고 이 변수를 아까 ClosestX와 Y가 같게끔 해주면 되겠지요. 참고로 그냥 같게 할게 아니라 각각의 이미지에 대한 width와 height로 나눠줘야합니다. 그 후에 이미지로 컬러데이터를 넘겨주면 이부분에 대한 이벤트는 끝납니다. 


이제 이 커서를 표시해줄 ball을 하나 만들어야 하는데요. 개체를 추가시켜야 합니다. 
참고로 XNA에서는 Content라는 요소가 따로 있기에 이부분에 이미지와 같은 개체를 삽입해야 합니다.


여기서 새로운 개체를 만들어야 합니다.


bitmap 이미지로 ball이란 개체를 만들고 Ellipse를 이용해서 큰 원을 하나 만들어놓습니다.


물론 위와 같이 Filled Ellipse를 만들면 속꽉원이 됩니다.

이를 저장하고 사용하기 위해서는 다른 개체와 마찬가지로 변수 선언이 되어야 하겠지요.


이 이미지의 호출은 LoadContent에서 이뤄집니다. 다음과 같이 정의해줍니다.


그리고 아까 얻은 Cursor의 위치를 Update항목에서 매핑해야 합니다.


마지막 과정이 하나 더 남았습니다. 바로 Draw과정에서 아까 호출했던 공의 이미지를 불러와야겠지요.


완성입니다. 한번 실행해보겠습니다.


조금 정확성 측면에서 부족한 면이 있지만 이런걸 조금더 보완한다면 하나의 멋진 손가락 트래킹이 이뤄지지 않을까요?
여기까지가 세번에 걸친 DepthStream에 대한 내용이었습니다.읽어주셔서 감사합니다.

댓글