c++openniopenframeworksnite

OpenNI through OpenFrameworks shows skeleton but not user mask


This is my first time using OpenFrameworks. I'm using it to get OpenCV's optical flow working with a user mask from OpenNI. So I don't need a skeleton. What I need is the user mask from OpenNI.

I'm using OpenNI version 1.5.4.0 and NITE version 1.5.2.21 and I'm on Ubuntu Trusty.

Most of the parts work, except for one: I can't see the user masks. The native OpenNI examples work: I can see user outlines in them. But from OpenFrameworks, I can't seem to get a user mask.

For each user in my OpenFrameworks code, I can do this:

// "user" is an object returned from ofxOpenNI::getTrackedUser

// This actually displays a skeleton:
user.drawSkeleton();
// These two do nothing:
user.drawMask();
user.drawPointCloud();

I think this is also true for the OpenNI device's debug view:

// openNiDevice is an instance of ofxOpenNI
openNiDevice.drawDebug();

This shows the RGB camera and the depth camera with the skeleton, but I don't think it shows the user mask. It's not perfectly clear because the user outline could be mistaken for a homogeneous depth reading, but I don't think it's the case. I think that even in the debug screen, the user mask would be in a different color than the depth color.

I print the number of users on the screen on draw and I can tell that ofxOpenNI does detect users. Also, it does show skeletons, so it must be seeing something.

Again, the OpenNI sample app Sample-NiUserTracker does give me a perfect outline, so OpenNI must be working.

What am I doing wrong?


Solution

  • I figured it out. Somewhere in the user mask code, a number is saved as an int but read as a char. So saving the pixels of the user mask into a new array but only keeping one out of four entries did the trick.

    Basically this:

    const unsigned char * userPix = user.getMaskPixels().getPixels();
    int dataSize = user.getMaskPixels().getWidth() * user.getMaskPixels().getHeight() * 4;
    unsigned char goodGray[dataSize / 4];
    for (int i = 0; i < dataSize; i += 4) {
      goodGray[i / 4] = userPix[i];
    }
    

    goodGray now contains the proper pixels and can be used to make an ofImage object.