In this recipe, we are going to show you how to request a search for a specific pose on a user and show the status of all the users' poses.
In the current version of NiTE, there are only two predefined poses that can be tracked and recognized: the PSI pose that was formally used as a calibration pose and the crossed hands pose that is a newly introduced pose. What follows is an image of a PSI pose:
In the new version of NiTE, there is no practical need to find out if a user is in one of these two predefined poses, because there is no need to be in a PSI pose for calibration and no requirement for the crossed hands pose that we are aware of. But you can still use these poses alone or if you want to support other third-party middleware. Also, even when it seems there is no need for PSI poses for calibration, it is still an error to indicate that calibration failed because of a lack of poses. So it may be used in some rare cases.
Create a project in Visual Studio and prepare it for working with OpenNI and NiTE using the Create a project in Visual Studio 2010 recipe in Chapter 2, OpenNI and C++.
#include
lines):char ReadLastCharOfLine() { int newChar = 0; int lastChar; fflush(stdout); do { lastChar = newChar; newChar = getchar(); } while ((newChar != ' ') && (newChar != EOF)); return (char)lastChar; } bool HandleStatus(nite::Status status) { if (status == nite::STATUS_OK) return true; printf("ERROR: #%d, %s", status, openni::OpenNI::getExtendedError()); ReadLastCharOfLine(); return false; }
int _tmain(int argc, _TCHAR* argv[]) {
nite::Status status = nite::STATUS_OK; status = nite::NiTE::initialize(); if (!HandleStatus(status)) return 1; printf("Creating user tracker ... "); nite::UserTracker uTracker; status = uTracker.create(); if (!HandleStatus(status)) return 1; printf("Reading data from user tracker ... "); while(!_kbhit()) { nite::UserTrackerFrameRef newFrame; status = uTracker.readFrame(&newFrame); if (!HandleStatus(status) || !newFrame.isValid()) return 1; system("cls"); const nite::Array<nite::UserData>& users = newFrame.getUsers(); for (int i = 0; i < users.getSize(); ++i) { if (users[i].isNew()){ uTracker.startPoseDetection( users[i].getId(), nite::POSE_PSI); } printf("User #%d %s - %s ", users[i].getId(), (users[i].isVisible()) ? "is Visible" : "is not Visible", (users[i].getPose(nite::POSE_PSI).isHeld()) ? "In PSI Pose" : "In No Pose"); } } uTracker.destroy(); nite::NiTE::shutdown(); return 0;
This is a fairly simple recipe. As you can see in step one, we have nothing except two of our famous functions: ReadLastCharOfLine()
for reading input from the console and HandleStatus()
for checking if a nite::Status
object is indicating an error.
Also, in the initial lines of step two, we have the same lines of code as given in the previous recipes. We initialized NiTE and created a nite::UserTracker
object. But just after that we entered a while
loop to read data from nite::UserTracker
until a user pressed a key in the console. In our while
loop, we have the code for reading a frame of data; this can be seen in the second line of the following code:
nite::UserTrackerFrameRef newFrame; status = uTracker.readFrame(&newFrame);
And then we cleared the console by calling a system command:
system("cls");
Then, to get the status of each user's pose information, we read the list of all the recognized users and their properties, including their poses, by defining an array of the nite::UserData
variable and calling the nite::UserTrackerFrameRef::getUsers()
method:
const nite::Array<nite::UserData>& users = newFrame.getUsers();
The next step is to loop through the users using another loop:
for (int i = 0; i < users.getSize(); ++i)
Then we can show the status of each user's pose to the user via the console; however, how can we expect to recognize a pose when we didn't request a search for it? That's why we need to call the
nite::UserTracker::startPoseDetection()
method when a new user is recognized:
if (users[i].isNew()){ uTracker.startPoseDetection( users[i].getId(), nite::POSE_PSI); }
As you can see in the preceding code, we checked if this user is a newly recognized user and if so, asked for a search for the PSI pose on this user.
Then we are going to show the current user's active pose to the user:
printf("User #%d %s - %s ", users[i].getId(), (users[i].isVisible()) ? "is Visible" : "is not Visible", (users[i].getPose(nite::POSE_PSI).isHeld()) ? "In PSI Pose" : "In No Pose");
This is a little complicated because we tried to do all the things in one line. But as you can clearly see, we used the nite::UserData::getPose()
method to retrieve the status of one of the poses of the user, and then using nite::PoseData::isHeld()
, we found out if the user is currently in this pose.
Based on these two methods, we wrote an inline if
to show the name of the active pose (the PSI pose in our case) and In No Pose
if the user wasn't in the PSI pose.
The output of our application is as follows:
18.118.31.67