Skeleton alive

edited March 2014 in Kinect

Hi all. :)

I'm new with processing, kinect and simpleopenni.

I have a question, i want to track a seated skeleton and i know that i have to look for shoulders, head and arms joints, but i have a problem, how do you keep the skeleton alive? Mean, I stand in front of the kinect and it detects me, shows the skeleton, and i sit, and start moving my arms and shoulders doing activities (drinking water, eating, reading, etc.), but the skeleton disappears after a while (i think a min or two passes before it disappears), and to make it appear again, I have to stand again in front the kinect.

Or anyone has any idea on how to track a seated skeleton?

I'm singin Ubuntu 12.04.4, processing 2.1.1, simpleopenni 1.96, NiTE 2.2 Linux x64, and OpenNI 2.2 Linux x64

Thanks in advance.

Answers

  • edited March 2014

    Well, i still haven't solved how to keep the skeleton alive, but i have found the way to track skeleton joints (their coordinates) and normalize them, also i found the way to find their angles (lie, i found it in a book named Making things see, but it's outdated). Here is my code, hope it helps somebody in a future. If i find a way to keep the skeleton alive i will post it in here (in the forum)

    `import SimpleOpenNI.*;`
    `SimpleOpenNI  myKinect;`
    
    `PrintWriter output;`
    
    `//... declaraciones de los vectores ...`
        PVector rtKnee, leftKnee, rtShoulder, leftShoulder, rtElbow, leftElbow, rtHand, leftHand, rtFoot, leftFoot;
        PVector rtHip, leftHip;
    
    
    `void setup()`
    `{`
    
      ` myKinect = new SimpleOpenNI(this);`
    
          // enable depthMap generation
          if(myKinect.enableDepth() == false)
          {
             println("Can't open the depthMap, maybe the camera is not connected!");
             exit();
             return;
          }
    
          // enable skeleton generation for all joints
          //myKinect.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
          myKinect.enableUser();
    
          myKinect.setMirror(false);
    
          //Enable the Depth Camera
    
          myKinect.enableDepth();
    
    
    
          smooth();
          size(myKinect.depthWidth(), myKinect.depthHeight());
    
          background(200,0,0);
    
        }
    
        void draw()
        {
          background(0);
    
          //Get new data from the Kinect
          myKinect.update();
          //Draw camera image on the screen
          //image(myKinect.rgbImage(),0,0);
           image(myKinect.depthImage(),0,0);
    
          //Each new person is identified with a number, so draw up to 5 people
          for(int userId=1; userId<=5; userId++){
            //for (int userId=1; userId<=1;userId++){
              //Check to see if tracking
              if(myKinect.isTrackingSkeleton(userId)){
                stroke(255,0,0);
                strokeWeight(3);
                drawSkeleton(userId);
    
                getBodyPoints(userId);
    
                //There are 24 possible joints that openNI tracks.  If we can get the point, draw it.    
                for(int bodyPart=1; bodyPart<=24; bodyPart++){
    
                    //get the point as a vector
                    PVector bodyPoint = getBodyPoint(userId, bodyPart);
                     //System.out.println("Body point: " + bodyPoint);
    
    
    
                    fill(0,255,0,128);
                    ellipse(bodyPoint.x, bodyPoint.y, 15, 15);
                 }
    
                 //draw the head bigger -- Demonstrates use of Constant SKEL_HEAD
                // PVector headPoint = getBodyPoint(userId, SimpleOpenNI.SKEL_HEAD);
                // ellipse(headPoint.x, headPoint.y, 50,50);
    
                 PVector rtHand2D = new PVector(rtHand.x, rtHand.y);
                 PVector rtElbow2D = new PVector(rtElbow.x, rtElbow.y);
                 PVector rtShoulder2D = new PVector(rtShoulder.x, rtShoulder.y); 
    
                 PVector rtHip2D = new PVector(rtHip.x, rtHip.y);
    
                 // calcula los ejes contra los cuales queremos medir los ángulos
                 PVector torsoOrientation = PVector.sub(rtShoulder2D, rtHip2D);
    
                 PVector upperArmOrientation = PVector.sub(rtElbow2D, rtShoulder2D);
    
                 // calcula los ejes contra los cuales queremos medir nuestros ángulos
                 float shoulderAngle = angleOf(rtElbow2D, rtShoulder2D, torsoOrientation);
                 float elbowAngle = angleOf(rtHand2D, rtElbow2D, upperArmOrientation);
    
    
                 // ... izquierda (¿?) ...
                 PVector ltHand2D = new PVector(leftHand.x, leftHand.y);
                 PVector ltElbow2D = new PVector(rtElbow.x, leftElbow.y);
                 PVector ltShoulder2D = new PVector(rtShoulder.x, leftShoulder.y); 
    
                 PVector ltHip2D = new PVector(leftHip.x, leftHip.y);
    
                 // calcula los ejes contra los cuales queremos medir nuestros ángulos
                 PVector lttorsoOrientation = PVector.sub(ltShoulder2D, ltHip2D);
                 float ltshoulderAngle = angleOf(ltElbow2D, ltShoulder2D, lttorsoOrientation);
                 float ltelbowAngle = angleOf(rtHand2D, rtElbow2D, upperArmOrientation);
    
                 rtShoulder.normalize();
                 rtElbow.normalize();
                 rtHand.normalize();
    
                 leftShoulder.normalize();
                 leftElbow.normalize();
                 leftHand.normalize();
    
                 println("pos h der:" + (rtShoulder.x) + "," + (rtShoulder.y) + "," + (rtShoulder.z) +
                         " án h der: " + int(shoulderAngle) +
                         " pos codo der: " + (rtElbow.x) + "," + (rtElbow.y) + "," + (rtElbow.z) +
                         " án codo der: " + int(elbowAngle) +
                         " pos man der: " + (rtHand.x) + "," + (rtHand.y) + "," + (rtHand.z) +
                         " pos h izq: " + (leftShoulder.x) + "," + (leftShoulder.y) + "," + (leftShoulder.z) +
                         " án h izq: " + int(ltshoulderAngle) + 
                         " pos codo izq: " + (leftElbow.x) + "," + (leftElbow.y) + "," + (leftElbow.z) +
                         " án codo izq: " + int(ltelbowAngle) + 
                         " pos man izq: " + (leftHand.x) + "," + (leftHand.y) + "," + (leftHand.z));
    
    
              }
              else
              {
                //print("Skeleton is not being tracked\n");
              }
           }
        }
    
        /**
        * Translate vector for point on Skeleton from REAL 3D space into
        * 2D projection space for drawing.
        *
        */
    
        //// ... NEW ...
        PVector getBodyPoint(int user, int bodyPart) {
    
          PVector jointPos=new PVector(), jointPos_Proj=new PVector();
          myKinect.getJointPositionSkeleton(user, bodyPart, jointPos);
          myKinect.convertRealWorldToProjective(jointPos, jointPos_Proj);
          //System.out.println("Parte del cuerpo: " + bodyPart + " Posición " + jointPos);
          return jointPos_Proj;
        }
    
    
        void getBodyPoints(int userId) {
    
    
          rtKnee = getBodyPoint(userId, SimpleOpenNI.SKEL_RIGHT_KNEE);
          leftKnee = getBodyPoint(userId, SimpleOpenNI.SKEL_LEFT_KNEE);
    
    
          rtShoulder = getBodyPoint(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER);
    
          leftShoulder = getBodyPoint(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER);
    
          rtElbow = getBodyPoint(userId, SimpleOpenNI.SKEL_LEFT_ELBOW);
    
          leftElbow = getBodyPoint(userId, SimpleOpenNI.SKEL_LEFT_ELBOW);
    
          rtHand = getBodyPoint(userId, SimpleOpenNI.SKEL_RIGHT_HAND);
    
          leftHand = getBodyPoint(userId, SimpleOpenNI.SKEL_LEFT_HAND);
    
          rtFoot = getBodyPoint(userId, SimpleOpenNI.SKEL_RIGHT_FOOT);
    
          leftFoot = getBodyPoint(userId, SimpleOpenNI.SKEL_LEFT_FOOT);
    
          rtHip = getBodyPoint(userId, SimpleOpenNI.SKEL_RIGHT_HIP);
          leftHip = getBodyPoint(userId, SimpleOpenNI.SKEL_LEFT_HIP);
        }
        ///////////////////
    
    
        // draw the skeleton with the selected joints
        //Simple OpenNI has a method called drawLimb, which simply draws a line
        // between two body points
        void drawSkeleton(int userId)
        {
    
    
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_HEAD, SimpleOpenNI.SKEL_NECK);
    
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_LEFT_SHOULDER);
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_LEFT_ELBOW);
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_ELBOW, SimpleOpenNI.SKEL_LEFT_HAND);
    
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_RIGHT_SHOULDER);
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_RIGHT_ELBOW);
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW, SimpleOpenNI.SKEL_RIGHT_HAND);
    
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
      myKinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
    
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_LEFT_HIP);
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_HIP, SimpleOpenNI.SKEL_LEFT_KNEE);
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_KNEE, SimpleOpenNI.SKEL_LEFT_FOOT);
    
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_RIGHT_HIP);
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_HIP, SimpleOpenNI.SKEL_RIGHT_KNEE);
          myKinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_KNEE, SimpleOpenNI.SKEL_RIGHT_FOOT); 
        }
    
        // -----------------------------------------------------------------
        // SimpleOpenNI has a number of event handlers, that are triggered when
        // "User events" occur.
    
        void onNewUser(SimpleOpenNI curContext, int userId)
        {
          println("onNewUser - userId: " + userId);
          println("  start pose detection");
    
          myKinect.startTrackingSkeleton(userId);
        }
    
        void onLostUser(int userId)
        {
          println("onLostUser - userId: " + userId);
        }
    
    
        float angleOf(PVector one, PVector two, PVector axis) {
          PVector limb = PVector.sub(two, one);
          return degrees(PVector.angleBetween(limb, axis));
        }
    ` :)>- 
    
  • Answer ✓

    To newcomers in this forum: read attentively these instructions

    Moved topic to a more specific one, formatted your code (but I left the pseudo-formating you did...).

  • Oh, i'm so sorry for causing you troubles PhiLho, I didn't mean it to post code, just wanted to know how to keep the skeleton from disappearing. And then i was excited because i found a way to track the joints.

    Sorry

Sign In or Register to comment.