2011-09-07 3 views
4

Kinect SDK WPF 응용 프로그램을 빌드하고 Kinect를 사용하여 "커서"/ 손 객체를 움직입니다.점진적 커서 이동 알고리즘 - Kinect SDK

내가 겪고있는 문제는 Kinect의 정밀도 (즉, 손을 잡은 채로 5px 공간 내에서 개체가 움직이기 때문에)에 커서가 실제로는 약 1 초에 30 프레임 씩 점프하는 것입니다.

내 "커서"스프린트의 X/Y를 화면의 오른쪽 위치로 옮기지 않고 "손을 움직여"방향으로 방향으로 X/Y 좌표 "를 사용하여 더 부드럽게 움직 이도록하십시오.

다른 누군가가 작성한 좋은 메시지를 누군가가 가리킬 수있게하여 바퀴의 재발 명을 피할 수 있습니까?

나는 이것이 아마도 매우 일반적이라는 것을 알고 있지만, 비즈니스 개발자로서 더 많은 것을 알고 있습니다. 그런 기능에 대한 이름이 확실하지 않으므로 사전에 사과해야합니다.

답변

4

Kinect와 함께 작업했을 때, 저는 몇 가지 간단한 수학 (선형 회귀라고 부름)을 사용하여 커서의 현재 위치와 목표 위치 사이의 어느 정도 거리를 가리 킵니다. 커서의 위치를 ​​얻고, 사용자의 손이있는 위치를 얻은 다음 (화면 좌표로 변환) 커서를 그 사이의 어떤 지점으로 이동합니다.

float currentX = ..., currentY = ..., targetX = ..., targetY = ...; 
float diffX = targetX - currentX; 
float diffY = targetY - currentY; 
float delta = 0.5f; // 0 = no movement, 1 = move directly to target point. 

currentX = currentX + delta * diffX; 
currentY = currentY + delta * diffY; 

델타에 따라 지터가 발생하지만 훨씬 더 부드럽고 일반적으로 작은 영역에 나타납니다.

관련 메모에서 Kinect의 골격 스무딩 매개 변수를 살펴 보았습니까? 실제로 SDK가 일부 필터링을 처리하도록 할 수 있습니다.

+0

위대한 작품 - 나는 kinect SDK를 부드럽게하는 것을 알아 채지 못했습니다. http://channel9.msdn.com/Series/KinectSDKQuickstarts/Skeletal-Tracking-Fundamentals – Doug

0

이 문제를 해결하기위한 하나의 아주 간단한 아이디어는 이전 위치 수의 평균 인 위치에 커서를 표시하는 것입니다. 예를 들어 손의 마지막 5 개 위치를 추적 한 다음 그 위치에 커서를 표시한다고 가정합니다. 그런 다음 사용자의 손이 상대적으로 여전히 길다면 마지막 5 개 프레임이 거의 같은 위치에 손을 잡고 소음이 사라지기 때문에 프레임에서 저속으로의 경도가 비교적 낮아야합니다. 사용자가 화면에서 커서를 움직이면 커서는 이전 위치에서 새 위치로 움직일 때 움직입니다. 손의 마지막 다섯 위치를 고려할 때 평균 위치가 이전 위치와 새 위치 사이를 서서히 보간하기 때문입니다 위치.

이 접근법은 매우 쉽게 조정할 수 있습니다. 이전 포인트가 새로운 포인트보다 크거나 작게 가중되도록 데이터 포인트를 변형 할 수 있으며 보유한 기록의 길이를 조정할 수 있습니다.

희망이 도움이됩니다.

4

입력 값 (점프 위치)을 저주파와 고주파 부분이 모두 포함 된 신호로 간주하십시오. 낮은 주파수는 대략적인 위치/움직임을 나타내며 고주파 부품은 더 짧은 거리 내에서 빠른 점프를 포함합니다.

그래서 필요한 필터는 저역 필터입니다. 고주파 파트를 걸러 내고 올바른 매개 변수로 설정하면 거친 (Kinect가 얻을 수있는만큼 정확한) 위치를 끝냅니다. 이 파라미터는 필터의 크로스 오버 주파수입니다. 너는 조금 놀아야하고 너는 볼 것이다.

시간 이산 값에 대한 구현의 예는 (원래 wikipedia에서) here에서 다음과 같습니다

static final float ALPHA = 0.15f; 

protected float[] lowPass(float[] input, float[] output) { 
    if (output == null) return input; 

    for (int i=0; i<input.length; i++) { 
     output[i] = output[i] + ALPHA * (input[i] - output[i]); 
    } 
    return output; 
} 

당신은이 기능으로 사용자의 위치 벡터의 X와 Y 두 구성 요소의 마지막 값을 넣을 수 있습니다 그들을 부드럽게합니다 (X는 input[0]이고 Y는 input[1], output[0]output[1]은 이전 함수 호출 결과 임).

  • 너무 크고 신호가 충분히 부드럽게되지 않습니다, 효과 : 이미 말했듯이

    , 당신은 평활 계수 ALPHA(0 ≤ ALPHA ≤ 1)에 대한 좋은 균형을 찾을 수있다 수식보면 커서가 (, 사용자의 움직임 후행 너무 많은 관성

것, 늘

  • 너무 작은 충분하고 신호가 '너무 많은'부드럽게됩니다, 알파 값이 0 인 경우 이전 out 값을 다시 가져 오므로 값이 변경되지 않습니다. 값이 1 인 경우 newout = out + in - out이 있습니다. 즉, 아무 것도 부드럽게하지 말고 항상 최신 값을 받아들입니다.)