ofxOpenNI ofxLimb position and orientation

Hi,

I wonder how can I get the ofxLimb positions in 3D, the struct have 2 ofVec2f properties begin and end, but it also have 2 XnSkeletonJoint properties start_joint and end_joint, I look into XnSkeletonJoint but from there I got lost, any ideas how can I get the 3d position vectors of the limbs?

Cheers

  • rS

in ofxLimb, each limb has

XnSkeletonJoint start_joint;
XnSkeletonJoint end_joint;

(their storage format)

in function updateLimb() in ofxLimb this gets the limb data if its found

  
  
	XnSkeletonJointPosition a,b;  
	xn_user_generator->GetSkeletonCap().GetSkeletonJointPosition(id, rLimb.start_joint, a);  
	xn_user_generator->GetSkeletonCap().GetSkeletonJointPosition(id, rLimb.end_joint, b);  
	if(a.fConfidence < 0.3f || b.fConfidence < 0.3f) {  
		rLimb.found = false;   
		return;  
	}  
  

Then it updates them in the addon like this

  
  
	XnPoint3D pos[2];  
	pos[0] = a.position;  
	pos[1] = b.position;  
	depth_generator->getXnDepthGenerator()  
		.ConvertRealWorldToProjective(2, pos, pos);  
  

So its storing the real world perspective x,y.

I agree it would be better if we could store the xyz in the addon easily too. Am playing around with is unless someone beats me to it.

Thanks I will try it out over the weekend

  • rS

Hey if that can help I put some code on github that allow control of an ofNode armature with ofxOpenNI ( I couldn’t push it to the point I could control an actual collada armature though )

https://github.com/kikko/ofApps/tree/master/Skel3D

AWESOME!!! I will play with this tonight

Thanks a lot for sharing

  • rS

Hi kikko,

I got it working, but the legs are not rotating, they do get to the right positions but no orientation is apply to them, any ideas what could be the problem? I am still studying your code

Cheers

  • rS

oups I’ve commited the wrong version! should be fixed this evening

Yesterday I fix it, not sure if this is the best approach.

All I did was, check if the limb is different than the hips or knees, if so do
testNodes[nodeNum].setOrientation(testNodes[nodeNum].bindPoseOrientation*q);
else if they are hips and knees do
testNodes[nodeNum].setOrientation(q);

Maybe this could also be fix by initializing the bindPoseOrientation in the setup method like you did for the neck, and arms, I will jump back into it over the weekend.

Thanks

  • rS

hey nardove, actually the code was the good one!
I didn’t set any specific orientation for the bind pose of the legs because OpenNI expect them to have no rotation.
So testNodes[nodeNum].bindPoseOrientation*q is equal to q because testNodes[nodeNum].bindPoseOrientation is (0, 0, 0, 1) for the bones of the legs. Not sure why it’s not working in you project.
It’s should work correcly with the latest master/origin version on github!

:frowning: arrgg! i’m just too stupid, i dont get this rotation/quaternitaion/openGl-stuff!
could someone help me out with a code snippet where i can put in two points and get the resulting openGLrotate ?

works.
http://vimeo.com/20385613

  
ofxVec3f normal = end - begin;  
		  
	float length = normal.length();  
	normal.normalize();  
		  
	ofxVec3f forward(0, -1, 0);  
	ofxVec3f axis   = forward.crossed(normal);  
	float angle      = forward.angle(normal);  
  
	glTranslatef(begin.x, begin.y, begin.z);  
	ofRotate( angle,axis.x,axis.y,axis.z);  

greetings

I tinkered a bit with kikkos example code and now i want to draw the stickman on the actual person from the kinect camera (similar to ascorbins video)… not as a small stickfigure in the corner.

can anyone tell me how to do that?

  
  
void testApp::setup()   
{  
    ofDisableArbTex();  
	ofSetVerticalSync(true);  
	  
	cam.setFov(62.7);  
	cam.setFarClip(10000.f);  
      
    for(int i=0; i< 11; i++)   
    {  
		  
		testNodes[i].setPosition(ofRandomf()*10-5, ofRandomf()*10-5, ofRandomf()*10-5);  
		testNodes[i].setScale(10);  
		  
		// setup a traditional humanoid bind pose  
		  
		// LEFT ARM  
		if(i==2||i==4){  
			testNodes[i].bindPoseOrientation.makeRotate(-90.0, ofVec3f(0.0f, 0.0f, 1.0f));  
        // RIGHT ARM  
		} else if(i==3||i==5){  
			testNodes[i].bindPoseOrientation.makeRotate(90.0, ofVec3f(0.0f, 0.0f, 1.0f));  
        // NECK  
		} else if(i==10){  
			testNodes[i].bindPoseOrientation.makeRotate(180.0, ofVec3f(0.0f, 0.0f, 1.0f));  
		} else {  
			testNodes[i].bindPoseOrientation.set(0, 0, 0, 1);  
		}  
	}  
  
	  
}  
  
[.........]  
  
void testApp::update()  
{  
	hardware.update();  
	  
	recordContext.update();  
	//recordDepth.update();  
	recordImage.update();  
	  
    if (isTracking) recordUser.update();  
	  
	cam.orbit(180, 0, 10, ofVec3f(0,0,10));  
      
    if( recordUser.getNumberOfTrackedUsers() > 0 )  
    {  
          
        headRotation = atan2( recordUser.getTrackedUser(1)->neck.position[1].Y - recordUser.getTrackedUser(1)->neck.position[0].Y , recordUser.getTrackedUser(1)->neck.position[1].X - recordUser.getTrackedUser(1)->neck.position[0].X ) *180/PI - 90;  
        winkel = ofToString( headRotation );  
          
        transformObject(0, XN_SKEL_TORSO);  
		transformObject(1, XN_SKEL_WAIST);  
		transformObject(2, XN_SKEL_LEFT_SHOULDER);  
		transformObject(3, XN_SKEL_RIGHT_SHOULDER);  
		transformObject(4, XN_SKEL_LEFT_ELBOW);  
		transformObject(5, XN_SKEL_RIGHT_ELBOW);  
		transformObject(6, XN_SKEL_LEFT_HIP);  
		transformObject(7, XN_SKEL_RIGHT_HIP);  
		transformObject(8, XN_SKEL_LEFT_KNEE);  
		transformObject(9, XN_SKEL_RIGHT_KNEE);  
		transformObject(10, XN_SKEL_NECK);  
  
    }  
      
	  
}  
  
[.........]  
  
void testApp::transformObject(int nodeNum,XnSkeletonJoint skelJoint)  
{  
      
    XnUserID userId = recordUser.getTrackedUser(1)->id;  
      
    //get openni bone info  
    xn::SkeletonCapability pUserSkel = recordUser.getXnUserGenerator().GetSkeletonCap();  
	  
    XnSkeletonJointOrientation jointOri;  
    pUserSkel.GetSkeletonJointOrientation(userId, skelJoint, jointOri);  
      
    XnSkeletonJointPosition jointPos;  
    pUserSkel.GetSkeletonJointPosition(userId, skelJoint, jointPos);  
      
      
    if( jointOri.fConfidence > 0)  
    {  
          
        float * oriM = jointOri.orientation.elements;  
          
        ofMatrix4x4 rotMatrix;  
          
        rotMatrix.set(   oriM[0], oriM[3], oriM[6], 0.0f,  
                         oriM[1], oriM[4], oriM[7], 0.0f,  
                         oriM[2], oriM[5], oriM[8], 0.0f,  
                         0.0f, 0.0f, 0.0f, 1.0f );  
          
        ofQuaternion q = rotMatrix.getRotate();  
          
        testNodes[nodeNum].setPosition(jointPos.position.X, jointPos.position.Y, jointPos.position.Z);  
          
        testNodes[nodeNum].setOrientation(testNodes[nodeNum].bindPoseOrientation*q);  
          
    }  
      
      
      
}