Select a specific skeleton - Unity / Orbbec Astra Pro

Hi Guybrush

I’ve had to do something kind similar recently. This is how i’ve approached it:

First disabled the autoskeleton tracking :

  void Start()
  {
    NuitrackManager.skeletonTracker.SetAutoTracking(false);
    NuitrackManager.skeletonTracker.SetNumActiveUsers(1);  
}

then listen to the data UsertrackerUpdates:

private void OnEnable()
{
    NuitrackManager.onUserTrackerUpdate += OnUserTrackerUpdate;
}

private void OnDisable()
{
    NuitrackManager.onUserTrackerUpdate -= OnUserTrackerUpdate;
}

In the usertracker update, you can then check for the closed user and assign/remove the user skeleton to track. This way you only calculate one skeleton.

       private void OnUserTrackerUpdate( UserFrame frame )
       {

        int nSkeletonTracked = NuitrackManager.skeletonTracker.GetSkeletonData().NumUsers;

        foreach (User user in frame.Users)
        {
            bool foundInSpot = CheckInSpot(user);

            if (NuitrackManager.skeletonTracker != null)
			{
				if (foundInSpot)
				{
                    InSpot = true;

                    if (nSkeletonTracked == 0)
					{
						Debug.Log("In spot user.ID:" + user.ID);
						NuitrackManager.skeletonTracker.StartTracking(user.ID);
					}
				}
				else
				{
					bool isTrackingUser = NuitrackManager.skeletonTracker.IsTracking(user.ID);
					NuitrackManager.skeletonTracker.IsTracking ?" + isTrackingUser + " nSkeletonTracked:"+ nSkeletonTracked);
					if (isTrackingUser && nSkeletonTracked >= 1)
						NuitrackManager.skeletonTracker.StopTracking(user.ID);
					
				}
			}
		}
}


	 private bool CheckInSpot(User user)
     {
            BoundingBox bb = user.Box;
     
            userPosition = user.Real.ToVector3();

           //SpotPosition is the Vector3 position where you want your detrection to happen
            var diff = userPosition - SpotPosition;
            diff = new UnityEngine.Vector3(Mathf.Abs(diff.x), Mathf.Abs(diff.y), Mathf.Abs(diff.z));

           // SpotRadius the area/zone where you want the detection to happen
            if (diff.x > SpotRadius.x)
                return false;
            if (diff.z > SpotRadius.z)
                return false;

            return true;
}

lastlysomewhere else you can check for the skeleton on Update

void Update()
{
    if (CurrentUserTracker.CurrentSkeleton != null)
    {
        ProcessSkeleton(CurrentUserTracker.CurrentSkeleton); // do something with  nuitrack.Skeleton
    } 
}

This code is copy paste from different part of a project so it will need adaptation, but you’ll get the idea.

There is another route using the config file that the support team gave me, yet i needed the full camera frame so didn’t go for it. might be of use for you/others tho. This is what they suggested:

1) open %NUITRACK_HOME%/data/nuitrack.config file in a text editor;
2) set "Skeletonization.ActiveUsers" to 1;
3) add this line

"BoxCutter":{"x":"0","y":"0","z":"0","width":"1000","height":"4000","depth":"3000","alpha":"0","beta":"-1.5"},

as the first line to "Segmentation" section.

Notes about 3rd step:

- depth map will be thresholded by height/2 mm (depth values [0...height/2] will be processed only);
- "beta" parameter is the BoxCutter's rotation angle in radians along X-axis of a sensor.

Please note this configuration of nuitrack.config file isn't default and could lead to accuracy issues.

Good luck!

1 Like