Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental #47

Open
wants to merge 4 commits into
base: experimental
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
OFXOPENNI
=========
This is ofxOpenNI using OpenNI2 and NITE2 libraries.

It's highly experimental. Currently only tested with PrimeSense Carmine 1.08x sensor on MacOSX 10.8.4 with of007x.
This is ofxOpenNI using OpenNI2 and NITE2 libraries.

It's highly experimental. Currently only tested with PrimeSense Carmine 1.08x sensor on MacOSX 10.8.4 with of007x.

This fork incoorporates motion measurements per joint and was used for an installation at Bauhaus Dessau.
158 changes: 152 additions & 6 deletions src/ofxOpenNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,54 @@
ofxOpenNI::ofxOpenNI(){
stop();
CreateRainbowPallet();
_motion_detection_rate = 1000/MOTION_DETECTION_FPS;
_motion_detection_count = ceil(MOTION_DETECTION_CACHE_LENGTH_MS / (1000/MOTION_DETECTION_FPS));
_md_threshold_motion = 0.5f;
_md_threshold_nomotion = 2.0f;
}

//--------------------------------------------------------------
ofxOpenNI::~ofxOpenNI(){
stop();
}

void ofxOpenNI::setMotionThresholds(float _threshold_motion, float _threshold_nomotion, float _cache_length = 0) {
ofScopedLock lock(mutex);
_md_threshold_motion = _threshold_motion;
_md_threshold_nomotion = _threshold_nomotion;
if (_cache_length == 0) _cache_length = MOTION_DETECTION_CACHE_LENGTH_MS;
_motion_detection_count = ceil(MOTION_DETECTION_CACHE_LENGTH_MS / (1000/MOTION_DETECTION_FPS));
}


//--------------------------------------------------------------
bool ofxOpenNI::setup(){
bool ofxOpenNI::setup(int _deviceid){

openni::Status rc = OpenNI::initialize();
if (rc != openni::STATUS_OK) {
ofLogError() << "Failed to initialize OpenNI:" << OpenNI::getExtendedError();
bUseDevice = false;
}

const char* deviceUri = ANY_DEVICE;
/* Print Device List */

openni::Array<DeviceInfo> deviceInfoList;
OpenNI::enumerateDevices(&deviceInfoList);
ofLogNotice() << "***************************************************";
ofLogNotice() << "* Available Devices *";
ofLogNotice() << "***************************************************";

for(int i = 0; i < deviceInfoList.getSize(); ++i){
ofLogNotice() << "Device " << ofToString(i) << " (" << deviceInfoList[i].getName() << "): " << deviceInfoList[i].getUri();
ofLogNotice() << " Vendor: " << deviceInfoList[i].getVendor() << deviceInfoList[i].getUsbVendorId() << " / " << ofToString(deviceInfoList[i].getUsbProductId());

}
ofLogNotice() << "***************************************************";

const char* deviceUri = ANY_DEVICE;
if (_deviceid >= 0) {
deviceUri = deviceInfoList[_deviceid].getUri();
}
rc = device.open(deviceUri);
if (rc != openni::STATUS_OK) {
ofLogError() << "Failed to open device:" << OpenNI::getExtendedError();
Expand All @@ -59,7 +89,6 @@ bool ofxOpenNI::setup(){
device.setDepthColorSyncEnabled(true);
bUseDevice = true;
}

return bUseDevice;

}
Expand Down Expand Up @@ -140,7 +169,7 @@ bool ofxOpenNI::addImageStream(){
}

//--------------------------------------------------------------
bool ofxOpenNI::addUserTracker(){
bool ofxOpenNI::addUserTracker(float _smoothing){

ofScopedLock lock(mutex);

Expand All @@ -165,7 +194,7 @@ bool ofxOpenNI::addUserTracker(){
}else{

ofLogNotice() << "Succeded to add user tracker";
userTracker.setSkeletonSmoothingFactor(0.3);
userTracker.setSkeletonSmoothingFactor(_smoothing);
bUseUsers = true;
}

Expand Down Expand Up @@ -343,7 +372,10 @@ void ofxOpenNI::updateImageFrame(){
void ofxOpenNI::updateUserFrame(){
if(userFrame.isValid()){
const nite::Array<nite::UserData>& users = userFrame.getUsers();

for(int i = 0; i < users.getSize(); ++i){


const UserData& user = users[i];

if(user.isNew()){
Expand All @@ -353,17 +385,22 @@ void ofxOpenNI::updateUserFrame(){
trackedUsers[user.getId()] = u;
trackedUsers[user.getId()].setUserID(user.getId());
}


switch (user.getSkeleton().getState()) {
case nite::SKELETON_TRACKED:
{
//ofLogNotice() << "Skeleton Tracking: " << user.getId();
ofxOpenNIUser& u = trackedUsers[user.getId()];
u.bIsTracked = true;
float timestamp = ofGetElapsedTimeMillis();
vector<ofxOpenNIJoint>& joints = u.getJoints();
float totalConfidence = 0.0f;
for(int i = 0; i < joints.size(); i++){
ofxOpenNIJoint& joint = joints[i];

u.centerOfMass = toOf(user.getCenterOfMass());

nite::Point3f position = user.getSkeleton().getJoint((nite::JointType)i).getPosition();
joint.positionReal = toOf(position);
ofPoint p;
Expand All @@ -373,7 +410,94 @@ void ofxOpenNI::updateUserFrame(){
totalConfidence += joint.positionConfidence;
joint.orientation = toOf(user.getSkeleton().getJoint((nite::JointType)i).getOrientation());
joint.orientationConfidence = user.getSkeleton().getJoint((nite::JointType)i).getOrientationConfidence();

/* Caching Position, every 100ms */

if (joint.activateMotionDetection) {


if (timestamp - joint.lastMeasureTimeStamp >= _motion_detection_rate) {


joint.lastMeasureTimeStamp = timestamp;

float _delta = (joint.pointCache.size()>0?p.distance(joint.pointCache.front().positionProjective):0) / 10;
joint.totalDistance += _delta;
joint.pointCache.push_front((ofxOpenNIJoint::_queue) {
.distanceMoved = _delta,
.positionProjective = p
});


/* Limit Length to max 50 Points */
if (joint.pointCache.size()>_motion_detection_count) {

/* if (i==6) {
cout << "Tracking Active Point " << ofToString(i) << ": Distance: " << ofToString(joint.motionCache) << " / Speed: " << ofToString(joint.averageSpeed) << " / Current Distance: " << ofToString(joint.motionShortCache) << " / Current Speed: " << ofToString(joint.currentSpeed) << " / Count: " << ofToString(_motion_detection_count) << " / " << ofToString(ceil(_motion_detection_count/5)) << "\n";
}
*/

joint.pointCache.resize(_motion_detection_count);

/* Calculate total and average */


joint.motionCache =
// joint.averageSpeed =
// joint.motionShortCache =
joint.currentSpeed = 0.0f;

int _index = 0;
//int _motion_detection_short_count = ceil(_motion_detection_count/10);
for (std::list<ofxOpenNIJoint::_queue>::iterator _cache = joint.pointCache.begin(); _cache != joint.pointCache.end(); _cache++, _index++) {
// if (_index < _motion_detection_short_count) {
// joint.motionShortCache += _cache->distanceMoved;
// }
// else {
joint.motionCache += _cache->distanceMoved;
// }
}
//joint.currentSpeed = joint.motionShortCache / _motion_detection_short_count * _motion_detection_rate;
//joint.averageSpeed = joint.motionCache / (_motion_detection_count-_motion_detection_short_count) * _motion_detection_rate;
joint.currentSpeed = joint.motionCache / _motion_detection_count * _motion_detection_rate;


/* Motion Detection: Still */
if (joint.currentSpeed < _md_threshold_nomotion)
{
joint.hasMotion = false;
if (joint.detectTime==0.0f) {
joint.detectTime = timestamp;
}
}
/* Motion Detection: Move */

else if (joint.motionCache > _md_threshold_motion ) {
joint.hasMotion = true;
joint.detectTime = 0.0f;
}

/* Motion Detection: Move /

if (joint.motionShortCache > _md_threshold_motion ) {
joint.hasMotion = true;
joint.detectTime = 0.0f;
}
/ Motion Detection: Still /
else if (joint.averageSpeed > _md_threshold_nomotion_long && joint.currentSpeed < _md_threshold_nomotion_current)
{
joint.hasMotion = false;
if (joint.detectTime==0.0f) {
joint.detectTime = timestamp;
}
}*/
}
}
}
}

u.box = user.getBoundingBox();

//cout << totalConfidence/joints.size() << endl;
if(totalConfidence == 0){
u.resetSkeleton();
Expand Down Expand Up @@ -415,6 +539,7 @@ void ofxOpenNI::updateUserFrame(){
trackedUsers.erase(trackedUsers.find(user.getId()));
}
}

}
}

Expand Down Expand Up @@ -478,6 +603,27 @@ void ofxOpenNI::threadedFunction(){
}
}

//--------------------------------------------------------------

map<int, ofxOpenNIUser> ofxOpenNI::skeletonData() {
ofScopedLock lock(mutex);
return trackedUsers;
}

//--------------------------------------------------------------

ofTexture & ofxOpenNI::depthData() {
return depthTexture;
}

//--------------------------------------------------------------

ofTexture & ofxOpenNI::imageData() {
return imageTexture;
}



//--------------------------------------------------------------
void ofxOpenNI::draw(){
if(!bUseDevice) return;
Expand Down Expand Up @@ -510,4 +656,4 @@ void ofxOpenNI::draw(){
}

ofSetColor(255, 255, 255);
}
}
35 changes: 28 additions & 7 deletions src/ofxOpenNI.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
#include "ofxOpenNIUtils.h"
#include "ofxOpenNITypes.h"

#define MOTION_DETECTION_FPS 10 // FPS of motion detecion capturing
#define MOTION_DETECTION_CACHE_LENGTH_MS 500 // Cache length in ms to calculate average speed

using namespace openni;
using namespace nite;

Expand All @@ -45,15 +48,16 @@ class ofxOpenNI : public ofThread {
ofxOpenNI();
~ofxOpenNI();

bool setup();

bool setup(int _deviceid = -1);

void start();
void stop();

bool addDepthStream();
bool addImageStream();
// bool addInfraGenerator();
bool addUserTracker();
bool addUserTracker(float _smoothing = 0.6);
// bool addGestureGenerator();
bool addHandsTracker();
// bool addAudioGenerator();
Expand All @@ -72,6 +76,16 @@ class ofxOpenNI : public ofThread {
bool isDepthFrameNew();
bool isImageFrameNew();

map<int, ofxOpenNIUser> skeletonData();
ofTexture& depthData();
ofTexture& imageData();

bool bUseDepth;
bool bUseImage;

void setMotionThresholds(float _threshold_motion, float _threshold_nomotion, float _cache_length);


protected:

void updateGenerators();
Expand Down Expand Up @@ -117,11 +131,10 @@ class ofxOpenNI : public ofThread {
bool bIsDepthFrameNew;
bool bIsImageFrameNew;

bool bUseDevice;
bool bUseNite;

bool bUseDepth;
bool bUseImage;
bool bUseDevice;


bool bUseInfra;
bool bUseUsers;
bool bUseGesture;
Expand All @@ -131,6 +144,14 @@ class ofxOpenNI : public ofThread {
bool bUseRecord;
bool bUsePlayer;


/* Motion Detection */
float _motion_detection_rate;
int _motion_detection_count;
float _md_threshold_motion;
float _md_threshold_nomotion;
// float _md_threshold_nomotion_current;

};

#endif
#endif
Loading