Негладкое масштабирование изображений с помощью Kinect - требуется коррекция при приближении - PullRequest
2 голосов
/ 29 января 2012

Я пытаюсь получить эффект увеличения / уменьшения масштаба с помощью Kinect.Основная идея:

  1. Определить, подняты ли обе руки bool lefthand, righthand;
  2. Рассчитать расстояние между руками prevDistance
  3. В следующем снятом кадре, если расстояние между руками меньше prevDistance, тогда ZoomOut else ZoomIn

Это работает для меня, но подход не приводит к оченьплавное увеличение / уменьшение.

    bool lefthand=false, righthand=false;
    float prevDistance=0;

//Inside SkeletonFrameReady event

if(lefthand && righthand && prevDistance=0)
{
prevDistance = skeleton.Joints[JointID.HandRight].Postion.X - skeleton.Joints[JointID.HandLeft].Position.X;
}
if(lefthand && righthand)
{
ZoomingFunction(skeleton.Joints[JointID.HandRight].Postion.X, skeleton.Joints[JointID.HandLeft].Position.X, prevDistance);
}
if(!lefthand && !righthand)
{
prevDistance =0;
}

Функция масштабирования:

private void ZoomingFunction(double RPostion, LPosition, double curDistance)
{
//0.3 has been added to get kind of integral points to zoom, else the zooming occurs very fast to control
    if(RPosition - LPosition < curDistance - 0.3F)
    {
//Zoom out
    img.Width -=20;
    }
    if(RPosition - LPosition > curDistance + 0.3F)
    {
//Zoom in
    img.Width +=20;
    }
}

Подход не выглядит для меня очень элегантно.Я пытался получить эффект плавного масштабирования, как в этой демонстрации Kinect Worldwide Telescope.Ссылка: http://www.youtube.com/watch?v=1-tMp4WkQjA

Есть предложения по улучшению?

Ответы [ 2 ]

1 голос
/ 30 января 2012

Я думаю, что здесь есть две возможные проблемы.

первый - накопление ошибок. Это происходит, когда на каждом кадре вы получаете с SD позицию для рук + небольшая ошибка (или шум). Мое решение для этого будет:

  1. Когда вы обнаружите, что пользователь поднял руки, и вы готовы начать масштабирование, сохраните расстояние между стрелками и уровень масштабирования в этот момент (назовем их startDistance and startZoom)

  2. В каждом кадре рассчитывается новый уровень масштабирования на основе исходного значения, исходного расстояния руки и нового расстояния. Вы могли бы сделать что-то вроде этого:


float newWidth = startWidth * currentDistance / startDistance;
float newHeight = startHeight * currentDistance / startDistance;

Это должно минимизировать накопление ошибок.

Вторая проблема заключается в улучшении плавности вашего зума и удалении любых шумов, которые вы можете получить из SDK. Это довольно просто. Вы можете попробовать интерполировать значения расстояния между текущим и предыдущим кадром. При необходимости вы можете попробовать интерполировать несколько кадров, если вы действительно получаете шумные значения.

Вы можете сделать что-то вроде этого:


float interpolatedDistance = (currentDistance + prevDistance) / 2;
float newWidth = startWidth * interpolatedDistance / startDistance;
float newHeight = startHeight * InterpolatedDistance / startDistance;
prevDistance = currentDistance;

Где currentDistance - расстояние между руками в этом кадре, а prevDistance - расстояние между руками в предыдущем кадре.

Скажите нам, если это помогло

0 голосов
/ 29 января 2012

Единственное, что я могу предложить, это иметь ScaleTransfrom на UIElemnt для изменения размера и использования привязки. Единственное, я верю, что это так. Неустойчивый, потому что вы двигаетесь слишком высоко в дельте. Иметь еще несколько операторов if, которые захватывают разные диапазоны с разными дельтами, такими как 1, 4 и 6, возможно

EDIT

Вам придется поиграться со значениями, но я бы начал что-то вроде этого:

double deltaPosition = RPosition - LPosition;
if(deltaPosition  < curDistance - 0.3f)
    img.Width -= 4;

else if(deltaPosition  < curDistance - 0.2f)
    img.Width -= 2;

else if(deltaPosition  < curDistance - 0.1f)
    img.Width -= 1;

else if(deltaPosition  > curDistance + 0.3F)
    img.Width += 4;

else if(deltaPosition  > curDistance + 0.2F)
    img.Width += 2;

else if(deltaPosition  > curDistance + 0.1F)
    img.Width += 1;
...