2015-11-22 2 views
1

В настоящее время я использую XBOX KINECT модель 1414 и обработку 2.2.1. Я надеюсь использовать правую руку как мышь, чтобы вести персонажа через экран.Kinect & Processing - преобразовать положение сустава как мышь x и мышь y?

Мне удалось нарисовать эллипс, чтобы следовать за правым суставом на скелете киндекта. Как бы я мог определить положение этого сустава, чтобы я мог заменить mouseX и mouseY, если это необходимо?

Ниже приведен код, который будет отслеживать вашу правую руку и нарисовать красный эллипс над ним:

import SimpleOpenNI.*; 

SimpleOpenNI kinect; 

void setup() 
{ 
// instantiate a new context 
kinect = new SimpleOpenNI(this); 
kinect.setMirror(!kinect.mirror()); 
// enable depthMap generation 
kinect.enableDepth(); 

// enable skeleton generation for all joints 
kinect.enableUser(); 

smooth(); 
noStroke(); 

// create a window the size of the depth information 
size(kinect.depthWidth(), kinect.depthHeight()); 

} 



void draw() 
{ 

// update the camera...must do 
kinect.update(); 

// draw depth image...optional 
image(kinect.depthImage(), 0, 0); 

background(0); 


// check if the skeleton is being tracked for user 1 (the first user that detected) 
if (kinect.isTrackingSkeleton(1)) 
{ 
int joint = SimpleOpenNI.SKEL_RIGHT_HAND; 

// draw a dot on their joint, so they know what's being tracked 
drawJoint(1, joint); 

PVector point1 = new PVector(-500, 0, 1500); 
PVector point2 = new PVector(500, 0, 700); 
} 
} 

/////////////////////////////////////////////////////// 

void drawJoint(int userID, int jointId) { 
// make a vector to store the left hand 
PVector jointPosition = new PVector(); 
// put the position of the left hand into that vector 
kinect.getJointPositionSkeleton(userID, jointId, jointPosition); 
// convert the detected hand position to "projective" coordinates that will match the depth image 
PVector convertedJointPosition = new PVector(); 
kinect.convertRealWorldToProjective(jointPosition, convertedJointPosition); 
// and display it 
fill(255, 0, 0); 

float ellipseSize = map(convertedJointPosition.z, 700, 2500, 50, 1); 
ellipse(convertedJointPosition.x, convertedJointPosition.y, ellipseSize, ellipseSize); 
} 

//////////////////////////// Event-based Methods 

void onNewUser(SimpleOpenNI curContext, int userId) 
{ 
println("onNewUser - userId: " + userId); 
println("\tstart tracking skeleton"); 

curContext.startTrackingSkeleton(userId); 
} 

void onLostUser(SimpleOpenNI curContext, int userId) 
{ 
println("onLostUser - userId: " + userId); 
} 

Любой вид ссылок или помощь будет очень признателен, спасибо!

ответ

1

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

foreach (Skeleton skeleton in skeletons) { 
    Joint RightHand = skeleton.Joints[JointType.HandRight]; 

    double rightX = RightHand.Position.X; 
    double rightY = RightHand.Position.Y; 
    double rightZ = RightHand.Position.Z; 
} 

Помните о том, что мы смотрим на 3-х измерениях, так что вы будете иметь х, у и г координат.

FYI: Вам нужно будет вставить эти строки кода в обработчик события SkeletonFramesReady. Если вы все еще хотите, чтобы круг вокруг него взглянул на пример WPF Skeleton Basics в Kinect SDK.
Вам это помогает?

1

Немного непонятно, чего вы пытаетесь достичь. Если вам просто нужно положение руки в координатах 2D-экран, код вы вывесили уже включает в себя следующее:

  1. kinect.getJointPositionSkeleton() извлекает 3D координаты
  2. kinect.convertRealWorldToProjective() преобразует их в координаты 2D экрана.

Если вы хотите, чтобы иметь возможность переключаться между использованием Kinect отслеживаются координаты рук и координаты мыши, вы можете хранить PVector, используемые в 2D-преобразования, как переменная видна всем эскиз, который вы обновляли либо KINECT скелет, если это отслеживается или мышь иначе:

import SimpleOpenNI.*; 

SimpleOpenNI kinect; 

PVector user1RightHandPos = new PVector(); 
float ellipseSize; 

void setup() 
{ 
// instantiate a new context 
kinect = new SimpleOpenNI(this); 
kinect.setMirror(!kinect.mirror()); 
// enable depthMap generation 
kinect.enableDepth(); 

// enable skeleton generation for all joints 
kinect.enableUser(); 

smooth(); 
noStroke(); 

// create a window the size of the depth information 
size(kinect.depthWidth(), kinect.depthHeight()); 

} 



void draw() 
{ 

    // update the camera...must do 
    kinect.update(); 

    // draw depth image...optional 
    image(kinect.depthImage(), 0, 0); 

    background(0); 


    // check if the skeleton is being tracked for user 1 (the first user that detected) 
    if (kinect.isTrackingSkeleton(1)) 
    { 
     updateRightHand2DCoords(1, SimpleOpenNI.SKEL_RIGHT_HAND); 
     ellipseSize = map(user1RightHandPos.z, 700, 2500, 50, 1); 
    }else{//if the skeleton isn't tracked, use the mouse 
     user1RightHandPos.set(mouseX,mouseY,0); 
     ellipseSize = 20; 
    } 

    //draw ellipse regardless of the skeleton tracking or mouse mode 
    fill(255, 0, 0); 

    ellipse(user1RightHandPos.x, user1RightHandPos.y, ellipseSize, ellipseSize); 
} 

/////////////////////////////////////////////////////// 

void updateRightHand2DCoords(int userID, int jointId) { 
    // make a vector to store the left hand 
    PVector jointPosition = new PVector(); 
    // put the position of the left hand into that vector 
    kinect.getJointPositionSkeleton(userID, jointId, jointPosition); 
    // convert the detected hand position to "projective" coordinates that will match the depth image 
    user1RightHandPos.set(0,0,0);//reset the 2D hand position before OpenNI conversion from 3D 
    kinect.convertRealWorldToProjective(jointPosition, user1RightHandPos); 
} 

//////////////////////////// Event-based Methods 

void onNewUser(SimpleOpenNI curContext, int userId) 
{ 
    println("onNewUser - userId: " + userId); 
    println("\tstart tracking skeleton"); 

    curContext.startTrackingSkeleton(userId); 
} 

void onLostUser(SimpleOpenNI curContext, int userId) 
{ 
    println("onLostUser - userId: " + userId); 
} 

по желанию, вы можете использовать логическое значение для переключения между режимом мыши/KINECT при тестировании.

Если вам нужна координаты мыши, чтобы просто проверить, не попасть в из-за Kinect все время, я рекомендую иметь взглянуть на RecorderPlay пример (через Processing> Файл> Примеры> Внесенный Библиотеки> SimpleOpenNI > OpenNI> ​​RecorderPlay). OpenNI имеет возможность записывать сцену (включая данные глубины), которая упростит проверку: просто запишите файл .oni с наиболее распространенными взаимодействиями, на которые вы нацеливаетесь, а затем повторно используйте запись при разработке. Все, что потребуется использовать .oni файл использует другой конструктор подпись для OpenNI:

kinect = new SimpleOpenNI(this,"/path/to/yourRecordingHere.oni"); 

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