티스토리 뷰

Processing

[Kinect with Processing] 손에서 생기는 Particle

생각많은 소심남 2012. 11. 14. 01:01

요즘 방명록으로 많이들 물어보십니다만.. 저도 그렇게 잘 아는 수준이 아니고 책에 있는 내용을 복습하는 수준이라서 더 상세하게 답변을 못드리고 있습니다.

 그중 전에 저한테 손에서 Particle이 생기게 할 수 있지 않느냐는 질문을 했었고, 이번 포스트에서 한번 시도해보고자 합니다. 


기본적인 접근은 이렇습니다. 이 섹션의 지난 포스트 중에서는 Wave 제스처를 통해서 손을 인식하고 그 손의 움직임에 따라서 LED의 밝기를 조절할 수 있었습니다. 그 밝기를 조절하는 기능대신에 손의 위치를 따라서 Particle이 생기게 할 겁니다. 만약 3차원으로 표현하고 싶다면 Particle 대신에 Sphere가 생기게 하면 좋겠지요. 저는 일단 Particle로 해보겠습니다.


자 우선 간단하게 Depth Image상에 Hand Tracking부터 구현해보도록 하겠습니다. 다 이전에 다뤘던 내용입니다.

당연히 키넥트를 쓰기 위해서는 키넥트를 위한 프로세싱 라이브러리인 SimpleOpenNI를 불러오고 키넥트를 정의해줍니다. 추가적으로 손의 위치도 초기화시켜주면 좋겠지요?



handVec은 실질상으로 키넥트에 대한 손의 상대적인 좌표입니다. 하지만 우리가 쓸 것은 화면상의 x,y 픽셀값이므로 현재창으로 매핑시켜줄 값이 필요하고 이 역할을 mapHandVec이 해줍니다. 그래서 정상적으로 추적되면 어떤 색이 나타나야 하는데 일단은 빨간색으로 초기화했습니다.

 이제 기본적인 설정을 해줘야 합니다. 바로 Setup()을 채워야 하겠지요.



SimpleOpenNI에는 기본적으로 제스처인식에 관한 함수가 정의되어 있고 그중 가장 대표적인 제스처가 바로 Wave(흔들기)입니다. 물론 다른 제스처에 대해서도 확인할 수 있지만 일단 손이라는 것을 알기 위해서 기본적으로 흔든다는 초기 행동을 선언하려고 합니다. 그래서 제스처에 관한 함수를 몇가지 정의해줍니다. 

 필요한게 딱 3가지인데 첫번째로 제스처를 인식하는 과정, 그 후에 제스처를 취한 손을 판단하는 과정, 그리고 그 손의 위치을 계속적으로 받아오는 과정으로 나눠서 볼수 있습니다. 그래서 다음과 같이 표현됩니다.



앞에서 말한 과정이 하나의 코드로 구현되었습니다. Wave 제스처가 들어오면 그걸 통해서 손을 추적하기 시작하고 정상적으로 추적됬을 경우에는 초록색으로 색이 바뀌게 됩니다. 그래서 지속적으로 그손을 따라다니게 되는 것이죠. 다들 아시겠지만 onUpdateHands함수는 매 프레임마다 실행되는 함수입니다. 그래서 handposition을 넘겨주는데 여기서 유의할 것은 pos 값이 화면상의 픽셀값이 아니라 world상의 좌표라는 겁니다. 그래서 뒤의 draw과정에서 그걸 픽셀로 변환해주는 과정을 거치게 됩니다. draw를 작성하면 다음과 같습니다.



앞에서 말한 변환과정이라는 것이 바로 convertRealWorldToProjective인데 일종의 투사형태를 띕니다. 그래서 좌표를 그대로 창 값으로 변환시켜주는 역할을 합니다. 여기까지 하면 기본적인 Depth화면을 출력할 수 있게 됩니다. 


초록색 점 보이시지요? 이게 바로 mapHandVec의 정체입니다. 

 자 그럼 본래의 목적인 Particle을 형성해보도록 하겠습니다. 사실 Particle example은 Daniel Shiffman씨의 Learning Processing의 예제로도 소개되어 있고 궁금하신분은 해당 링크를 통해서 보실 수 있습니다.

http://www.learningprocessing.com/examples/chapter-23/example-23-2/

이걸 그대로 적용해보겠습니다.


우선은 Particle이라는 class를 하나 생성해야 합니다. 클래스를 어떻게 만드느냐 싶은데 다음과 같이 만듭니다.



오른쪽 상단에 보면 오른쪽을 가리키는 화살표가 하나 있는데 여기서 New Tab을 선택하게 되면 새로운 스크립트를 만들 수 있는 창이 하나 생성됩니다. 저는 Particle이라고 하고 예제 코드를 그대로 받아왔습니다. 물론 여기 프로젝트에서 쓰기 위해서는 한가지 수정해야 될 부분이 있습니다.


바로 Particle의 x와 y를 정의하는 부분인데 이전에는 이부분이 mouseX와 mouseY로 되어 있었습니다. 우리는 손의 위치에 따라서 Particle이 움직여야 하니까 앞에서 생성한 mapHandVec을 가져온 겁니다. 

 이게 클래스를 정의했으니까 실제로 쓰기 위해서는 앞의 스크립트에 Particle에 대한 개체를 생성해야 합니다. 그런데 생각해볼게 사실 Particle이 여러개 있어야 Particle의 느낌이 있는 것이지 하나만 똑 튀어나온다면 별 느낌이 없겠지요. 그래서 이걸 배열화시켜서 위치를 저장시킵니다.



당연히 setup에서는 이 particles에 대한 초기화가 이뤄집니다. 그와 동시에 뭔가 좀 부드럽게 해주면 좋겠지요



이제 매프레임마다 이 Particle을 어떻게 표현할 것이지에 대한 정의만 해주면 끝나게 됩니다. 예제에서는 for루프를 돌려서 100개 이상이 넘어갈 시에 없어지게끔 했습니다. 저도 그대로 삽입해봤습니다.



예제를 보신 분은 감이 오시겠지만 결과가 이렇게 나옵니다.



영상으로 보는게 더 실감나겠지요.



물론 Particle에 대한 속성을 변화시켜주고 싶다 하시는 분이라면 아까 복사해서 넣은 Particle 클래스를 적절히 수정한다면 원하시는 결과를 얻으실 수 있을겁니다. 그런데 Particle의 테두리는 stroke를 0으로 했음에도 저렇게 두껍게 나오네요. 아예 없이 나온다면 조금더 깔끔했을텐데 말이지요.


아무튼 조잡하게나마 hand를 따라서 떨어지는 Particle을 구현해봤습니다.

댓글