Defining a HotSpot with ofxOpenNI

Hi,

Is there a way to define a hot-spot with ofxOpenNI so that it tracks only the user who is standing on the hot-spot?
Can we use this near-threshold, far-threshold with user tracking as well?

I dont want openNI to track all the users within the Kinect’s view area, but the only user standing on the hot-spot.

Highly appreciate any help!
Thanks!
-Lahiru.

I really appreciate any help on this. :slight_smile:

Thank you!

I’ve used this to grab the front-most user - might help

Each user has a set of pixels with depth values. You can take those values (or sample one , e.g. the center) and get the distance of the user with ofxDepthGenerator’s getPixelDepth(x, y). (some of the code is here: http://forum.openframeworks.cc/t/ofxopenni-±skeleton-tracking/8266/8)

So if the user’s distance is within your specified range you can pick them as your active user.

As I was hacking away at the new API today I was thinking about this problem…

There are several ways to hatch this egg -> I came at it kind of differently to you Jason…maybe because I was thinking about the auto-calibrating version of openNI…

What I thought was: let’s limit max users to just 1.

Whenever we get a calibrated, skeleton tracking user…let’s check there centre of mass (ofxOpenNIUser::getCentre())…and if their x,y,z is not within the bounds we want…let’s stop tracking that user (ofxOpenNI::resetUserTracking(XnUserID nID, bool forceImmediateRestart)

I added the forceImmediateRestart because (I guess it’s a feature, but felt like a bug in this case) if just cancel Skeleton tracking NITE still thinks the user is there -> cos they are, duh :wink: so by forcing a re-calibration request NITE goes searching for another user skeleton…

I added some user events to see if I could get this to work purely externally, and only during recognition (so you could move anywhere once it’s got you calibrated) and it seemed fine (probably better to alter the internals if you want really quick decisions), but using the ofxOpenNIUserEvents and the above command I got my kinect to only recognize my skeleton if I was more than 2m away…and then keep tracking me wherever I went after getting calibrated (if you wanted to force skeleton recognition in only one limited area, you could do all of this in an update rather than an event, so it continuously checked CoM for any user with a skeleton and force reset the user tracking if they’re outside)…

So definitely yes with the new API, and definitely yes with the old API, but you’d have to make some of the same changes I’ve been making…

…hope that makes sense…it’s late here :wink:

Thank you for the reply!

I tried to do as you suggested by refereeing the development branch of ofxOpenNI. Now I can stop tracking the user whenever it is not in the allowed region. However, if I limit the max users to 1 ofxOpenNI keep tracking the same user even though the skeleton tracking is not there. Also, if the kinect can see the first user it ignores the calibration pose for the second (or other) users. :frowning:

In other words…,
After starting the application if I go infront of the kinect it starts to track me (without skeleton tracking!) -> I need to remove this user if he/she is not in the allowed region.

Then I do the calibration pose, and kinect starts skeleton tracking. If the user go out from the allowed region I can stop tracking the user as you suggested. But it stops only the skeleton tracking and keeps tracking the user without the skeleton. :slight_smile:

I am sorry if my question is not clear enough.

Is there any way to forget all the users and restart the process?

Thanks a lot!
-Lahiru.

Yep I had the same thing, hence:

I added the forceImmediateRestart because (I guess it’s a feature, but felt like a bug in this case) if just cancel Skeleton tracking NITE still thinks the user is there -> cos they are, duh :wink: so by forcing a re-calibration request NITE goes searching for another user skeleton…

I found that if I called resetUserTracking(nID, true) this forced Nite to start the calibration cycle again…did you try that, and it didn’t work?

Yes, I tried that.

But startTrackingUser(nID) gives me an error at the following line.

CHECK_ERR_RC(nRetVal, “Get skeleton capability - start tracking”);

The return value of user_generator.GetSkeletonCap().StartTracking(nID) is not XN_STATUS_OK and it prints “Get skeleton capability - start tracking - Error” on the console.

Any reason for this? I am using ofxOpenNI master branch.

Thanks a lot!

Try using the experimental branch, that way you can call:

  
resetUserTracking(nID, true)  

Hey! Thanks a lot! I am trying this out with the experimental branch now. First of all, I must say that “No Pose” rocks! :slight_smile:

However, in the example app it crashes at the end… after pressing esc. This is not a huge issue at the moment but I was wondering whether it could be fixed too.

It breaks at,

  
  
void ofxOpenNI::updateGenerators() {  
....  
...  
g_Context.WaitAnyUpdateAll();  
....  
...  
}  
  

Thanks!

I am sorry I just noticed this. :slight_smile:

  
  
    // this often does not work -> it's a known bug -> but calling it on a key press or anywhere that isnt std::aexit() works  
    // press 'x' to shutdown cleanly...  
  

Okey, this is what happens.

Let’s say we have limited the max users to 1, and when I call,

  
  
openNIDevices[0].resetUserTracking(user.getID(), true);  
  

it stops tracking user “one”, but keeps that user in the users list. So even if user “two” comes to the scene the app will not track him. Is there anyway to remove all users from the users list and force to start with new users?

About the unclean exit: it’s really quite annoying -> I’ve literally spent hours and hours on this (if you look at the commit list you will see my frustration!)…at the end of the day I’m not entirely sure why it happens but it’s either:

* mutex deadlock or destruction order being unspecified - maybe caused by smart-pointer application instance destructing before ofxOpenNI thread gets joined/stopped
* NITE singleton instance getting destroyed during application exit in unspecified order (apparently NITE uses a singleton internally and maybe it kills itself before we get to shutdown the thread) - my reason for thinking this is that the unclean crash only happens when using NITE libs (ie., user/hand tracking, gestures)

About user list:
* Which user list are you talking about? In ofxOpenNI I am using a map to store references to user ID’s -> I started out using arturo’s version of this (from ofxOpenNI2) but wanted to allow persistent user references so that it was possible to set properties on a per user basis…
* NITE itself should decrement the user ID number when a user is lost…but sometimes this doesn’t happen, so
* Actually I need to look more closely at how I’m doing this so that a) regardless of the NITE user ID number we allocate our own user ID and therefore track the correct maxNumUsers, and b) maintain persistence of user settings…

I’m currently investigating this because hand tracking is even more annoying with NITE, where the XnUserID for each hand always increments no matter if a hand has been lost (even internally by NITE)

So when it’s done I’ll let you know…

Thanks a lot for all your hard work! :slight_smile:

What I meant was that, even if I call openNIDevices[0].resetUserTracking(1, true); user 1 is there. It only stops skeleton tracking for user 1, but user1.isTracking would always be true!

You can notice this clearly when you have two users in the scene and the maxUsers is set to 1. So even after you call resetUserTracking(1, true) it keeps tracking (not skeleton) the first user who came into the scene.

Only after openni lose user 1, it starts looking for a new-user-1 so that the new-user-1 get a chance for a skeleton tracking. User 2 will be ignored… like forever :frowning:

Edit:

Is there anyway to force openni to lose all users (events like “Lost User 1”, “Lost User 2” will be fired), and re-generate the users list?

Thanks a bunch!

Once OpenNI grabs a user it seems to hold onto them pretty tight until they leave the camera’s view for 10 seconds

I guess a brute force way would be to kill the OpenNI context/callbacks (basically rebooting the camera/app). Fortunately the new versions are much quicker about this

@jvcleave: Yes, forcing openni to kill all users would be a good solution. Thanks!

@gameover:

To reset the skeleton tracking, resetUserTracking() works well so far! However, sometimes, very rarely, app crashes on the following line…

  
  
void ofxOpenNI::updateGenerators(){  
    //if (bIsThreaded) lock(); // with this here I get ~30 fps with 2 Kinects  
	  
    if (!bIsContextReady) return;  
      
    g_Context.WaitAnyUpdateAll(); //<--- Crash Here!!  
....  
..  
}  
  

As a random guess (since I cant really find why it crashes) I uncommented the first “if (bIsThreaded) lock();” and commented out the currently used one. After doing that app did not crash or it seems really hard to reproduce the issue.

Is this a known issue? Could “if (bIsThreaded) lock();” have any effect on the crash?

Thanks a lot! :slight_smile:

Hi, I was using the master, but also I needed to “reset” or delete the user1 once it’s lost by the camera, in fact I don’t want to detect multiple users, but just one. If that user leaves the hotspot, then the new user should be user1.
So I decided to use the experimental to try the resetUserTracking(nID, true) after a user is lost, but when I run the UserAndCloud-Simple example I get this after the program is loaded.

  
  
: OF_LOG_WARNING: Using a NASTY hack to silence SIGNAL errors on exit - read the comments at line ~1712 of ofxOpenNI.cpp   
ofxOpenNIDevice[2]: OF_LOG_NOTICE: Init context...   
ofxOpenNIDevice[2]: OF_LOG_NOTICE: Adding licence...   
ofxOpenNIDevice[2]: OF_LOG_NOTICE: Init device...   
ofxOpenNIDevice[2]: OF_LOG_NOTICE: Found 1 devices connected   
ofxOpenNIDevice[2]: OF_LOG_ERROR: No Devices available for this instance [ 2 ] of ofxOpenNI - have you got a device connected?!?!   
ofxOpenNIDevice[2]: OF_LOG_WARNING: Using a NASTY hack to silence SIGNAL errors on exit - read the comments at line ~1712 of ofxOpenNI.cpp   
ofxOpenNIDevice[2]: OF_LOG_NOTICE: Init context...   
ofxOpenNIDevice[2]: OF_LOG_NOTICE: Adding licence...   
ofxOpenNIDevice[2]: OF_LOG_ERROR: No Devices available for this instance [ 2 ] of ofxOpenNI - have you got a device connected?!?!   
ofxOpenNIDevice[2]: OF_LOG_NOTICE: Adding generator type XN_NODE_TYPE_DEPTH   
ofxOpenNIDevice[2]: OF_LOG_ERROR: Context is not setup - please call ofxOpenNI::setup() first   
ofxOpenNIDevice[2]: OF_LOG_NOTICE: Adding generator type XN_NODE_TYPE_IMAGE   
ofxOpenNIDevice[2]: OF_LOG_ERROR: Context is not setup - please call ofxOpenNI::setup() first   
ofxOpenNIDevice[2]: OF_LOG_WARNING: Currently it is only possible to have a user generator on one device in a single process!!   
OF: OF_LOG_ERROR: trying to delete a non indexed texture, something weird is happening. Deleting anyway  
Program received signal:  “EXC_BAD_ACCESS”.  
sharedlibrary apply-load-rules all  
kill  
quit  
  
The Debugger has exited with status 0.  
  

I know that message comes from static ofTexture.cpp -> void release(GLuint id){} but I just don’t know how to solve the problem.

I hope some of you could help me with this.
Thank you.

Um are you just using the ‘vanilla’ UserAndCloud-Simple example? Or have you made modifications?

The trace you posted suggests you have several instances of ofxOpenNI somewhere in your testApp, since it’s trying to tell you that:

a) you only have one device

  
ofxOpenNIDevice[2]: OF_LOG_NOTICE: Found 1 devices connected   

b) you’re using an instance with a higher instance number than the number of devices

  
ofxOpenNIDevice[2]: OF_LOG_ERROR: No Devices available for this instance [ 2 ] of ofxOpenNI  

c) it’s asking if you called setup()

  
Context is not setup - please call ofxOpenNI::setup() first   

d) that you can only have a user generator on 1 instance of ofxOpenNI

  
Currently it is only possible to have a user generator on one device  

Could be my code is all mucked up, but looks like you’ve modified the example…could you let me know how many kinects you have connected and whether you’re just using the example as downloaded?

Thanks for your answer gameover.
I’m using only 1 kinect. In fact the master works great, but as I got the experimental with git I renamed the master to ofxOpenNIstable in addons to work with the new branch.
Then in the experimental examples there are four different src’s but in fact I receive the same error with all of them.
After several errors I’ve deleted the example and copied to my apps folder again, but now I receive another error when running:

  
  
run  
[Switching to process 20895]  
Running
  
ofxOpenNIDevice[0]: OF_LOG_WARNING: Using a NASTY hack to silence SIGNAL errors on exit - read the comments at line ~1712 of ofxOpenNI.cpp   
ofxOpenNIDevice[0]: OF_LOG_NOTICE: Init context...   
ofxOpenNIDevice[0]: OF_LOG_NOTICE: Adding licence...   
ofxOpenNIDevice[0]: OF_LOG_NOTICE: Init device...   
ofxOpenNIDevice[0]: OF_LOG_NOTICE: Found 1 devices connected   
ofxOpenNIDevice[0]: OF_LOG_NOTICE: Starting ofxOpenNI with threading   
ofxOpenNIDevice[0]: OF_LOG_NOTICE: Adding generator type XN_NODE_TYPE_DEPTH   
ofxOpenNIDevice[0]: OF_LOG_NOTICE: Adding generator type XN_NODE_TYPE_IMAGE   
ofxOpenNIDevice[0]: OF_LOG_NOTICE: Adding generator type XN_NODE_TYPE_USER   
ofxOpenNIDevice[0]: OF_LOG_NOTICE: User generator DOES NOT require pose for calibration   
Program received signal:  “EXC_BAD_ACCESS”.  
sharedlibrary apply-load-rules all  
warning: .o file "/Developer/usr/lib/gcc/i686-apple-darwin10/4.0.1/libgcc.a(_eprintf.o)" more recent than executable timestamp in "/Users/cui/Proyectos/Xcode/openFrameworks/apps/_Cui/opeNI-SimpleExamples/bin/openNISample007Debug.app/Contents/Frameworks/GLUT.framework/Versions/A/GLUT"  
warning: Could not open OSO file /Developer/usr/lib/gcc/i686-apple-darwin10/4.0.1/libgcc.a(_eprintf.o) to scan for pubtypes for objfile /Users/cui/Proyectos/Xcode/openFrameworks/apps/_Cui/opeNI-SimpleExamples/bin/openNISample007Debug.app/Contents/Frameworks/GLUT.framework/Versions/A/GLUT  
warning: Could not find object file "/Users/theo/Documents/CODE/__OPENFRAMEWORKS/gitOF/openFrameworks/apps/devApps/macDragDropExample/buildGlutFrameworkHackedWindowLevel10.4/libForeground.a(macx_foreground.o)" - no debug information available for "/Users/mcast/Code/GLUT-ToPost/macx_foreground.m".  
  

Maybe an absolute path must be relative?? Because its looking for a file in "/Users/theo/Documents/CODE/
"
The example crash after loaded and Xcode point me to this:

  
  
  template<typename _Key, typename _Val, typename _KeyOfValue,  
           typename _Compare, typename _Alloc>  
    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator  
    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::  
    lower_bound(const _Key& __k)  
    {  
      _Link_type __x = _M_begin(); // Current node.  
      _Link_type __y = _M_end(); // Last node which is not less than __k.  
  
      while (__x != 0)  
->	if (!_M_impl._M_key_compare(_S_key(__x), __k))  
	  __y = __x, __x = _S_left(__x);  
	else  
	  __x = _S_right(__x);  
  
      return iterator(__y);  
    }  
  

I’m lost.

That’s pretty much a generic segmentation fault - somewhere something is writing to a null pointer or something is writing over a pointer that’s in use…maybe :wink:

Could you run again with ofSetLogLevel(OF_LOG_VERBOSE)?

Also what version of Xcode/OS and openFrameworks (and oF branch) are you using?

Hey I think this problem and fix are related…see: topic,7403.msg41119.html#msg41119

Can you pull the latest experimental version and see if it helps?