티스토리 뷰

Kinect

[Kinect 프로젝트] The Color Image Stream

생각많은 소심남 2012. 5. 4. 00:47

매일 복잡한 것만 하다가 한번쯤은 되돌아봐야 할 듯해서 아주 기초적인 내용부터 다시 다루고자 합니다.

맨처음으로 다룰 내용은 바로 ColorImageStream입니다.

 

키넥트에는 IR 카메라와 일반 카메라 이렇게 두개가 있습니다. 보통 IR라고 하면 InfraRed, 즉 적외선인데 IR 카메라는 이를 감지하는 카메라지요. 여러분들도 아시겠지만 빛은 직사광선입니다. 앞에 장애물이 있지 않는 한 직선으로 쭉 뻗는 Ray 입니다. 그런데 우리가 사물의 색과 거리를 인지할 수 있는 이유는 가시광선이 사물에 부딪치고 우리 눈으로 반사되기 때문입니다. 사실 IR 카메라의 원리도 똑같은 겁니다. 적외선이 사물에 부딪치면 다시 카메라쪽으로 반사할 것이고 그때의 시간을 계산해서 사물간의 거리를 인지할 수 있는 겁니다. 이걸 다르게 표현하면 깊이(Depth)라고 하지요. 이건 다른 때에 소개할 예정이고 이번 포스팅에서 다루는 내용은 ColorImageStream이라고 해서 그냥 일반 카메라로 보는 겁니다.

 사실 이건 일반 웹캠과 별반 차이가 없습니다. 그냥 렌즈를 통해서 본 이미지를 컴퓨터에게 뿌려주는 원리이기 때문입니다.  우선 키넥트가 ColorStream을 이용하는 순서는 다음과 같습니다.

- Kinect의 colorStream을 뽑는 기능을 활성화(Enable)시킨다.

- Kinect가 ColorStream을 뽑은 후 byte형 배열에 저장한다.

- byte형 배열에 저장된 data를 어플리케이션이 이용한다.

 

이정도 순서가 되겠습니다. 이걸 코드로 표현해보도록 하겠습니다.

 

자 우선은 WPF 로 프로젝트를 하나 생성합니다. 이름은 ColorTest로 하면 되겠지요.

 

 

우선 맨 처음으로 해야 할 일은 레퍼런스 추가입니다. Kinect SDK를 설치했지만 이건 하나의 SDK이기 때문에 레퍼런스가 자동으로 추가되지 않습니다. 결론적으로 사람이 일일이 추가를 해야 된다는 말입니다. 그런데 방법은 매우 쉽습니다.

 우측 상단에 보면 Solution Explorer라는 창이 하나 있습니다. 여기에 폴더 모양의 Reference가 있는데 여기를 우클릭해서 Add Reference를 선택하면 됩니다.

 

 

정상적으로 SDK가 설치된 상태라면 위 레퍼런스에도 당연히 있어야 합니다. 이걸 더블클릭을 하셔서 추가하시면 됩니다. 그러면 실제 Solution Explorer에도 아래와 같이

 

 

Microsoft.Kinect가 추가되게 됩니다. 여기가 끝이 아닙니다. 이건 참고할 수 있는 레퍼런스가 있다는 거지 실제로 이용하기 위해서는 네임 스페이스로 추가시키는 과정이 필요합니다.  바로 이렇게 말이죠.

 

 

여기까지가 키넥트 프로그래밍을 위한 기본 설정과정이었습니다.

자 우선은 cs 코드상에서 Kinect에 대한 동작을 감지하는 코드를 구현합니다. 우선 변수 선언이 필요합니다.

 

 

 앞에서와 같이 네임스페이스틀 추가하면 위와 같이 KinectSensor라는 자료형을 사용할 수 있게 됩니다. 이 변수에는 Kinect 센서의 제어와 정보에 대한 모든 변수를 다룰 수 있습니다. 이걸 키넥트의 상태를 판단하는데 사용할 겁니다.

 

우선은 우리가 맨처음에 본 흰창이 바로 MainWindow 창입니다. 거기서 모든 활동들이 일어납니다. 어떻게 보면 우리가 이미지를 내 보낼 곳도 이 MainWindow가 되겠지요. cs코드에도 이창에서 무슨 일을 할건지 정의하는 곳이 있습니다. 여기다가 다음과 같이 씁니다.

 

 

위의 항목은 Mainwindow가 켜졌을 때 키넥트 센서를 찾으라는 메서드를 이벤트로 실행되게끔 한 것이고 그 밑의 Unload과정은 그에 반대되는 예외처리를 해준겁니다. 자 일단 키넥트 센서를 찾고 나서는 현재 키넥트가 어떤 상태인지를 알아야 하겠지요.

 

 

이 메서드가 실행되면서 KinectSensor의 상태 변화를 감지할겁니다.  그 다음은 그 상태에 대한 구문을 switch를 통해서 제어하는 겁니다.

 

 

사실 키넥트의 상태는 속성으로 찍어보시면 아시겠지만 많은 경우의 수를 가집니다. 물론 정상적으로 연결된 과정인 Connected, 해제된 상태인 Disconnected도 있지만 고장난 상태를 여러 경우의 수로 표현한 것도 있습니다. 심지어는 전원이 안들어온 것이 대한 상태도 인지할 수 있습니다.(Kinect for Windows를 보신 분은 아시겠지만 전원 외에도 usb를 따로 꽂아야 합니다. 그리고 재미있는 것은 전원을 빼도 키넥트가 동작한다는 겁니다. 물론 정상동작을 하는 것은 아니지만요.) 아무튼 각 상태에 대한 정의는 위와 같이 적어주면 되겠네요.

 

위와 같이 구성을 하면 Kinect가 있는지 없는지를 하나의 value로 받는 겁니다. 당연히 없을때는 Kinect의 동작이 멈춰야 할 것이고 있는 상태에서 더구나 연결된 상태라면 Color Stream을 받아올 준비를 해야됩니다. 그에 대한 메서드를 각각 UninitializeKinectSensor와 InitializeKinectSensor로 구분했습니다. 그럼 바로 밑에는 이 메서드의 정의가 이뤄져야 합니다.

바로 밑에 다음과 같이 적습니다.

 

 

위에 나와있다시피 +=까지 써주면 아래에 EventHandler에 대한 안내 구문이 뜹니다. 여기서 탭키를 연속으로 따닥 눌러주면

 

 

위와 같이 관련된 이벤트 핸들러를 자동으로 생성시켜줍니다. 이는 즉, 힘들게 타자칠 필요가 없다는 겁니다. 아직 InitializeKinectSensor 메서드가 끝난게 아닙니다. 활성화를 시켰으니 다음 동작에 대해서 키넥트를 움직여야 합니다. 그걸하는 것이 바로 Start 메서드 입니다.

 

아니면 이벤트를 위와 같이 자동으로 만들게 아니라 자신이 직접 만들어도 됩니다.

 

 

자 UninitializeKinectSensor는 반대의 과정을 거칩니다. 키넥트를 멈춘 상태에서 ColorFrameReady를 점점 줄이는 과정을 수행해야 합니다. 그걸 코드로 표현하면 다음과 같습니다.

 

 

자 이제 해야 될건 바로 Kinect_ColorFrameReady라는 이벤트를 정의해야 합니다. 그 전에 이렇게 뽑은 칼라 이미지를 MainWindow상에 뿌려주는 것이 필요합니다. 처음 프로젝트를 열었을 때 가운데 흰창이 있는 것을 확인할 수 있을겁니다. 이게 xaml코드의 디자인뷰 상태입니다. 여기다가 image control을 삽입하겠습니다.

 

 

ToolBox에 있는 Image를 그대로 MainWindow상에 옮기셔도 되고 아니면 직접 xaml코드상에 만들어도 됩니다. 코드는 다음과 같습니다.

 

 

자 이렇게 하면 이제 이 이미지의 이름은 ColorImageElement가 된겁니다. 이렇게 하면 cs 코드상에서도 그대로 써먹을 수가 있지요. 바로 Source라는 속성을 이용하면 됩니다. 다시 cs 코드로 넘어가서 아까 이름만 써놨던 Kinect_ColorFrameReady를 다음과 같이 정의합니다.

 

이게 ColorImageFrame을 사용하기 위한 전부입니다. 앞에서 말한 순서가 그대로 나타나있습니다. 먼저 키넥트로부터 받은 이미지의 정보를 연 후에 byte형 배열인 pixelData에 넣고 그 값을 복사하는 과정을 거치고 있습니다. 이제 마지막 과정인 어플리케이션으로의 사용이 남아있습니다. 앞에서 잠깐 언급한 것처럼 Image의 이름이 ColorImageElement이고 source속성을 사용하면 다음과 같이 쓸 수 있습니다.

 

 

자 우선은 이렇게 받은 이미지를 비트맵 파일로 처리하려고 BitmapImage.Create 메서드를 사용했습니다. 그런데 여기에 필요한 인수가 총 8개입니다. 조금 많아 보이지만 사실 별 것도 없고 그냥 이미지로 불러오기 위해서는 위 변수가 필요하다는 것을 알고 그냥 필요할 때 인용하시면 될거 같습니다.

 

 

그냥 알아둘것은 Pixel의 format은 어떻게 할 것인지, 해당 ImageFrame의 폭과 높이는 얼마로 할건지 에 대한 이해만 있으면 나머지는 거의 고정값이라고 보셔도 무방할 것 같습니다. 

지금까지 쭉 읽어내려오면 괜히 예외처리를 해줄 필요도 없는데 해준 부분도 있고, 코드가 괜히 복잡해진 감도 있습니다만 센서의 특성상 민감한 외부반응에도 변화가 잘 일어나기 때문에 이런 예외처리가 필수적입니다. 다음이 결과 영상입니다.

 

 

뭐 이렇게 보면 일반 웹캠과 별반 차이는 없어보이지만 이제 키넥트만이 할 수 있는 기능을 언급하고자 합니다. 여기까지가 Kinect의 동작 설정 및 ColorImageStream을 처리하는 방법을 언급한 겁니다.

아참! 참고로 창이 꺼져있는데 키넥트가 동작이 되고 있다면 이때는 window_Closing이라는 이벤트를 생성하면 됩니다. xaml상에서 MainWindow를 선택하면 properties창에 event라는 메뉴가 있습니다. 여기서 잘 찾아보면 Closing이란게 있을겁니다.

 

 저기를 더블클릭하면 옆에 Window_closing이라는 이름이 생기면서 cs 코드상에도 같은 이름의 이벤트 핸들러가 자동 생성됩니다. 여기에 다음과 같이 채워주면 됩니다.

 

 

댓글