00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #if (defined _WIN32)
00071 #define PRIu64 "llu"
00072 #else
00073 #define __STDC_FORMAT_MACROS
00074 #include <inttypes.h>
00075 #endif
00076
00077 #include "cob_openni2_tracker/body_tracker.h"
00078
00079 #include <cob_openni2_tracker/NiteSampleUtilities.h>
00080 #include <math.h>
00081 #include <stdio.h>
00082
00083
00084 #define GL_WIN_SIZE_X 640
00085 #define GL_WIN_SIZE_Y 512
00086 #define TEXTURE_SIZE 256
00087 #define MAX_USERS 10
00088 #define MIN_NUM_CHUNKS(data_size, chunk_size) ((((data_size)-1) / (chunk_size) + 1))
00089 #define MIN_CHUNKS_SIZE(data_size, chunk_size) (MIN_NUM_CHUNKS(data_size, chunk_size) * (chunk_size))
00090
00091 #define USER_MESSAGE(msg) {\
00092 sprintf(userStatusLabels[user.getId()], "%s", msg);\
00093 printf("[%08" PRIu64 "] User #%d:\t%s\n", ts, user.getId(), msg);}
00094
00095 float Colors[][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 1, 1}};
00096 bool visibleUsers[MAX_USERS] = {false};
00097 int colorCount = 3;
00098 nite::SkeletonState skeletonStates[MAX_USERS] = {nite::SKELETON_NONE};
00099 char userStatusLabels[MAX_USERS][100] = {{0}};
00100 char generalMessage[100] = {0};
00101 static std::string detector_ = "camera";
00102
00103 using namespace std;
00104 using namespace message_filters;
00105
00106
00107
00108
00109
00110 BodyTracker::BodyTracker(ros::NodeHandle nh_priv)
00111 :pcl_cloud_(new pcl::PointCloud<pcl::PointXYZRGB>), m_poseUser(0), br_(), nh_(nh_priv)
00112 {
00113 marker_id_ = 0;
00114
00115
00116
00117 if(!nh_.getParam("camera_frame_id", cam_frame_)){
00118 ROS_WARN("tf_prefix was not found on Param Server! See your launch file!");
00119 nh_.shutdown();
00120 Finalize();
00121 }
00122
00123 if(!nh_.getParam("tf_prefix", tf_prefix_)){
00124 ROS_WARN("tf_prefix was not found on Param Server! See your launch file!");
00125 nh_.shutdown();
00126 Finalize();
00127 }
00128
00129 if(!nh_.getParam("relative_frame", rel_frame_)){
00130 ROS_WARN("relative_frame was not found on Param Server! See your launch file!");
00131 nh_.shutdown();
00132 Finalize();
00133 }
00134
00135 std::cout << "\n---------------------------\nPeople Tracker Detection Parameters (CAMERA):\n---------------------------\n";
00136
00137 nh_.param("drawSkeleton", drawSkeleton_, false);
00138 std::cout << "drawSkeleton = " << drawSkeleton_ << "\n";
00139 nh_.param("drawCenterOfMass", drawCenterOfMass_, false);
00140 std::cout << "drawCenterOfMass = " << drawCenterOfMass_ << "\n";
00141 nh_.param("drawUserName", drawUserName_, true);
00142 std::cout << "drawUserName = " << drawUserName_ << "\n";
00143 nh_.param("drawBoundingBox", drawBoundingBox_, true);
00144 std::cout << "drawBoundingBox = " << drawBoundingBox_ << "\n";
00145 nh_.param("drawBackground", drawBackground_, false);
00146 std::cout << "drawBackground = " << drawBackground_ << "\n";
00147 nh_.param("drawDepth", drawDepth_, false);
00148 std::cout << "drawDepth = " << drawDepth_ << "\n";
00149 nh_.param("drawFrames", drawFrames_, false);
00150 std::cout << "drawFrames = " << drawFrames_ << "\n";
00151 nh_.param("poseTimeoutToExit", poseTimeoutToExit_, 2000);
00152 std::cout << "poseTimeoutToExit = " << poseTimeoutToExit_ << "\n";
00153
00154 vis_pub_ = nh_.advertise<visualization_msgs::Marker>( "visualization_marker", 10);
00155 pcl_pub_ = nh_.advertise<pcl::PointCloud<pcl::PointXYZ> >("body_tracker_filter", 0);
00156 people_pub_ = nh_.advertise<cob_perception_msgs::People>("people", 0);
00157
00158 ROS_INFO("Create BodyTracker.\n");
00159 m_pUserTracker = new nite::UserTracker;
00160 pcl_cloud_->points.clear();
00161
00162 init();
00163
00164 it_ = new image_transport::ImageTransport(nh_);
00165 image_sub_.registerCallback(boost::bind(&BodyTracker::imageCallback, this, _1));
00166 image_sub_.subscribe(*it_, "/camera/rgb/image_raw", 1);
00167 image_pub_ = it_->advertise("colorimage_out", 1);
00168
00169 tracked_users_ = new list<nite::UserData>();
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179 void BodyTracker::imageCallback(const sensor_msgs::ImageConstPtr& color_image_msg)
00180 {
00181 cv_bridge::CvImageConstPtr cv_ptr;
00182
00183 try
00184 {
00185 cv_ptr = cv_bridge::toCvShare(color_image_msg, sensor_msgs::image_encodings::BGR8);
00186 }catch (cv_bridge::Exception& e)
00187 {
00188 ROS_ERROR("PeopleDetection: cv_bridge exception: %s", e.what());
00189 return;
00190 }
00191 cv::Mat color_image_ = cv_ptr->image;
00192 int height = color_image_msg->height;
00193 int width = color_image_msg->width;
00194
00195
00196 if(!tracked_users_->empty())
00197 {
00198 for(std::list<nite::UserData>::iterator iter_ = tracked_users_->begin();
00199 iter_ != tracked_users_->end(); ++iter_)
00200 {
00201 if((*iter_).getCenterOfMass().x != 0 && (*iter_).getCenterOfMass().y != 0 && (*iter_).getCenterOfMass().z != 0)
00202 {
00203 int max_x = width - (*iter_).getBoundingBox().max.x;
00204 int max_y = (*iter_).getBoundingBox().max.y;
00205 int min_x = width - (*iter_).getBoundingBox().min.x;
00206 int min_y = (*iter_).getBoundingBox().min.y;
00207
00208 double center_x = (*iter_).getCenterOfMass().x;
00209 double center_y = (*iter_).getCenterOfMass().y;
00210
00211
00212 int r = 255*Colors[(*iter_).getId() % colorCount][0];
00213 int g = 255*Colors[(*iter_).getId() % colorCount][1];
00214 int b = 255*Colors[(*iter_).getId() % colorCount][2];
00215
00216 if(drawBoundingBox_)
00217 {
00218 cv::rectangle(color_image_, cv::Point(min_x, min_y), cv::Point(max_x, max_y) ,
00219 CV_RGB(r, g, b), 2);
00220 }
00221
00222 if(drawCenterOfMass_)
00223 {
00224 cv::circle(color_image_, cv::Point(100, 100), 10, CV_RGB(r, g, b));
00225 }
00226 if(drawUserName_)
00227 {
00228
00229 }
00230 }
00231 }
00232 }
00233 cv::waitKey(10);
00234
00235 image_pub_.publish(cv_ptr->toImageMsg());
00236 }
00237
00238 BodyTracker::~BodyTracker()
00239 {
00240
00241 Finalize();
00242 }
00243
00244 void BodyTracker::Finalize()
00245 {
00246 ros::spinOnce();
00247 delete[] m_pTexMap_;
00248 delete m_pUserTracker;
00249 device_.close();
00250 nite::NiTE::shutdown();
00251 openni::OpenNI::shutdown();
00252 }
00253
00254
00255
00256
00257 void BodyTracker::init()
00258 {
00259 m_pTexMap_ = NULL;
00260
00261 openni::Status rc = openni::OpenNI::initialize();
00262 if (rc != openni::STATUS_OK)
00263 {
00264 printf("Failed to initialize OpenNI\n%s\n", openni::OpenNI::getExtendedError());
00265 nh_.shutdown();
00266 return;
00267 }
00268 const char* device_Uri = openni::ANY_DEVICE;
00269
00270 rc = device_.open(device_Uri);
00271 if (rc != openni::STATUS_OK)
00272 {
00273 printf("Failed to open device_\n%s\n", openni::OpenNI::getExtendedError());
00274 nh_.shutdown();
00275 return;
00276 }
00277
00278 rc = depthSensor_.create(device_, openni::SENSOR_DEPTH);
00279 if (rc != openni::STATUS_OK)
00280 {
00281 printf("Failed to create a video stream \n%s\n", openni::OpenNI::getExtendedError());
00282 nh_.shutdown();
00283 return;
00284 }
00285
00286 nite::NiTE::initialize();
00287 if (m_pUserTracker->create(&device_) != nite::STATUS_OK)
00288 {
00289 printf(" Get data for NiTE failed\n");
00290 nh_.shutdown();
00291 return;
00292 }
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 void BodyTracker::runTracker()
00314 {
00315 while(nh_.ok())
00316 {
00317 if(tracked_users_ == NULL)
00318 {
00319 tracked_users_ = new list<nite::UserData>();
00320 }
00321 nite::UserTrackerFrameRef userTrackerFrame;
00322 openni::VideoFrameRef depthFrame;
00323
00324 nite::Status rc = m_pUserTracker->readFrame(&userTrackerFrame);
00325 if (rc != nite::STATUS_OK)
00326 {
00327 printf("GetNextData failed\n");
00328 return;
00329 }
00330
00331 depthFrame = userTrackerFrame.getDepthFrame();
00332
00333 if (m_pTexMap_ == NULL)
00334 {
00335
00336 m_nTexMapX = MIN_CHUNKS_SIZE(depthFrame.getVideoMode().getResolutionX(), TEXTURE_SIZE);
00337 m_nTexMapY = MIN_CHUNKS_SIZE(depthFrame.getVideoMode().getResolutionY(), TEXTURE_SIZE);
00338 m_pTexMap_ = new openni::RGB888Pixel[m_nTexMapX * m_nTexMapY];
00339 }
00340 const nite::UserMap& userLabels = userTrackerFrame.getUserMap();
00341
00342 if (depthFrame.isValid() && drawDepth_)
00343 {
00344 calculateHistogram(m_pDepthHist, MAX_DEPTH, depthFrame);
00345 }
00346 memset(m_pTexMap_, 0, m_nTexMapX*m_nTexMapY*sizeof(openni::RGB888Pixel));
00347 float factor[3] = {1, 1, 1};
00348
00349
00350 if (depthFrame.isValid() && drawDepth_)
00351 {
00352 const nite::UserId* pLabels = userLabels.getPixels();
00353
00354 const openni::DepthPixel* pDepthRow = (const openni::DepthPixel*)depthFrame.getData();
00355 openni::RGB888Pixel* pTexRow = m_pTexMap_ + depthFrame.getCropOriginY() * m_nTexMapX;
00356 int rowSize = depthFrame.getStrideInBytes() / sizeof(openni::DepthPixel);
00357 float dX, dY, dZ;
00358
00359 pcl_cloud_->resize(depthFrame.getHeight()*depthFrame.getWidth());
00360 pcl_cloud_->width = depthFrame.getWidth();
00361 pcl_cloud_->height = depthFrame.getHeight();
00362
00363 for (int y = 0; y < depthFrame.getHeight(); ++y)
00364 {
00365 const openni::DepthPixel* pDepth = pDepthRow;
00366 openni::RGB888Pixel* pTex = pTexRow + depthFrame.getCropOriginX();
00367
00368 for (int x = 0; x < depthFrame.getWidth(); ++x, ++pDepth, ++pTex, ++pLabels)
00369 {
00370 if (*pLabels == 0)
00371 {
00372 if (!drawBackground_)
00373 {
00374 factor[0] = factor[1] = factor[2] = 0;
00375 }
00376 else
00377 {
00378 factor[0] = Colors[colorCount][0];
00379 factor[1] = Colors[colorCount][1];
00380 factor[2] = Colors[colorCount][2];
00381 }
00382 }
00383 else
00384 {
00385
00386 factor[0] = Colors[*pLabels % colorCount][0];
00387 factor[1] = Colors[*pLabels % colorCount][1];
00388 factor[2] = Colors[*pLabels % colorCount][2];
00389 }
00390
00391 if(*pDepth != 0)
00392 openni::CoordinateConverter::convertDepthToWorld(depthSensor_, (float)x, (float)y, (float)(*pDepth), &dX, &dY, &dZ);
00393 else
00394 dX = dY = dZ = 0.f;
00395 pcl::PointXYZRGB& point = pcl_cloud_->at(x,y);
00396 point.r = 255*factor[0];
00397 point.g = 255*factor[1];
00398 point.b = 255*factor[2];
00399 point.x = dZ/1000;
00400 point.y = -dX/1000;
00401 point.z = dY/1000;
00402
00403 if (*pDepth != 0)
00404 {
00405 int nHistValue = m_pDepthHist[*pDepth];
00406 pTex->r = nHistValue*factor[0];
00407 pTex->g = nHistValue*factor[1];
00408 pTex->b = nHistValue*factor[2];
00409
00410 factor[0] = factor[1] = factor[2] = 1;
00411 }
00412 }
00413 pDepthRow += rowSize;
00414 pTexRow += m_nTexMapX;
00415 }
00416 }
00417
00418 drawPointCloud();
00419
00420
00421 const nite::Array<nite::UserData>& users = userTrackerFrame.getUsers();
00422 for (int i = 0; i < users.getSize(); ++i)
00423 {
00424 const nite::UserData& user = users[i];
00425 updateUserState(user, userTrackerFrame.getTimestamp());
00426
00427 if(user.isNew())
00428 {
00429 m_pUserTracker->startSkeletonTracking(user.getId());
00430 m_pUserTracker->startPoseDetection(user.getId(), nite::POSE_CROSSED_HANDS);
00431 }
00432 else if(!user.isLost() && users[i].getSkeleton().getState() == nite::SKELETON_TRACKED)
00433 {
00434
00435
00436 if(drawFrames_)
00437 {
00438 drawFrames(user);
00439 }
00440
00441 double length = sqrt(users[i].getCenterOfMass().x) + sqrt(users[i].getCenterOfMass().y) +
00442 sqrt(users[i].getCenterOfMass().z);
00443
00444 if(length != 0)
00445 {
00446
00447
00448 bool found = false;
00449 for(std::list<nite::UserData>::iterator iter_ = tracked_users_->begin();
00450 iter_ != tracked_users_->end(); ++iter_)
00451 {
00452 if((*iter_).getId() == user.getId())
00453 {
00454 found = true;
00455 tracked_users_->erase(iter_++);
00456
00457
00458
00459
00460 }
00461 }
00462
00463 if(found)
00464 {
00465
00466 tracked_users_->insert(tracked_users_->begin(), users[i]);
00467 }
00468
00469
00470 if(!found || tracked_users_->empty())
00471 {
00472 tracked_users_->insert(tracked_users_->end(), users[i]);
00473 }
00474 }
00475 }
00476 else if(user.isLost())
00477 {
00478
00479 for(std::list<nite::UserData>::iterator iter_ = tracked_users_->begin();
00480 iter_ != tracked_users_->end(); ++iter_)
00481 {
00482 if((*iter_).getId() == user.getId())
00483 tracked_users_->erase(iter_++);
00484 }
00485 }
00486
00487 if (m_poseUser == 0 || m_poseUser == user.getId())
00488 {
00489 const nite::PoseData& pose = user.getPose(nite::POSE_CROSSED_HANDS);
00490 if (pose.isEntered())
00491 {
00492
00493 sprintf(generalMessage, "In exit pose. Keep it for %d second%s to exit\n", poseTimeoutToExit_/1000, poseTimeoutToExit_/1000 == 1 ? "" : "s");
00494 printf("Waiting to start timeout %i \n", poseTimeoutToExit_/1000);
00495 m_poseUser = user.getId();
00496 m_poseTime_ = userTrackerFrame.getTimestamp();
00497 }
00498 else if (pose.isExited())
00499 {
00500 memset(generalMessage, 0, sizeof(generalMessage));
00501 m_poseTime_ = 0;
00502 m_poseUser = 0;
00503 }
00504 else if (pose.isHeld())
00505 {
00506 if (userTrackerFrame.getTimestamp() - m_poseTime_ > poseTimeoutToExit_ * 1000)
00507 {
00508 printf("Timeout.");
00509 }
00510 }
00511 }
00512 }
00513 publishTrackedUserMsg();
00514 }
00515 }
00516
00517
00518
00519 void BodyTracker::publishTrackedUserMsg()
00520 {
00521
00522 std::vector<cob_perception_msgs::Person> detected_people;
00523 for(std::list<nite::UserData>::iterator iter_ = tracked_users_->begin(); iter_ != tracked_users_->end(); ++iter_)
00524 {
00525 cob_perception_msgs::Person person;
00526 cob_perception_msgs::Skeleton skeleton;
00527
00528 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_HEAD)));
00529 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_NECK)));
00530 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_LEFT_SHOULDER)));
00531 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_RIGHT_SHOULDER)));
00532 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_LEFT_ELBOW)));
00533 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_RIGHT_ELBOW)));
00534 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_LEFT_HAND)));
00535 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_RIGHT_HAND)));
00536 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_TORSO)));
00537 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_LEFT_HIP)));
00538 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_RIGHT_HIP)));
00539 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_LEFT_KNEE)));
00540 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_RIGHT_KNEE)));
00541 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_LEFT_FOOT)));
00542 skeleton.joints.push_back(convertNiteJointToMsgs((*iter_).getSkeleton().getJoint(nite::JOINT_RIGHT_FOOT)));
00543
00544 char id[100];
00545 snprintf(id,100,"person %d", (*iter_).getId());
00546 string id_ = std::string(id);
00547
00548 person.name = id_;
00549 person.detector = detector_;
00550 person.position.position.x = (*iter_).getCenterOfMass().x/1000.0;
00551 person.position.position.y = -(*iter_).getCenterOfMass().y/1000.0;
00552 person.position.position.z = (*iter_).getCenterOfMass().z/1000.0;
00553
00554 person.skeleton = skeleton;
00555
00556 unsigned int length = sqrt(person.position.position.x) + sqrt(person.position.position.y) +
00557 sqrt(person.position.position.z);
00558
00559
00560 if(length != 0)
00561 detected_people.push_back(person);
00562 }
00563 cob_perception_msgs::People array;
00564 array.header.stamp = ros::Time::now();
00565 array.header.frame_id = rel_frame_;
00566 array.people = detected_people;
00567 people_pub_.publish(array);
00568
00569 }
00570
00571
00572
00573 void BodyTracker::updateUserState(const nite::UserData& user, uint64_t ts)
00574 {
00575 if(user.isNew()){
00576 USER_MESSAGE("New User detected.");
00577 }
00578 else if(user.isVisible() && !visibleUsers[user.getId()]){
00579 printf("[%08" PRIu64 "] User #%d:\tVisible\n", ts, user.getId());
00580 }
00581 else if(!user.isVisible() && visibleUsers[user.getId()]){
00582 printf("[%08" PRIu64 "] User #%d:\tOut of Scene\n", ts, user.getId());
00583 }
00584 else if(user.isLost()){
00585 USER_MESSAGE("Lost");
00586 }
00587 visibleUsers[user.getId()] = user.isVisible();
00588
00589 if(skeletonStates[user.getId()] != user.getSkeleton().getState())
00590 {
00591 switch(skeletonStates[user.getId()] = user.getSkeleton().getState())
00592 {
00593 case nite::SKELETON_NONE:
00594 USER_MESSAGE("Stopped tracking !")
00595 break;
00596 case nite::SKELETON_CALIBRATING:
00597 USER_MESSAGE("Calibrating...")
00598 break;
00599 case nite::SKELETON_TRACKED:
00600 USER_MESSAGE("Tracking ...");
00601 break;
00602 case nite::SKELETON_CALIBRATION_ERROR_NOT_IN_POSE:
00603 case nite::SKELETON_CALIBRATION_ERROR_HANDS:
00604 case nite::SKELETON_CALIBRATION_ERROR_LEGS:
00605 case nite::SKELETON_CALIBRATION_ERROR_HEAD:
00606 case nite::SKELETON_CALIBRATION_ERROR_TORSO:
00607 USER_MESSAGE("Calibration Failed... :-|")
00608 break;
00609 }
00610 }
00611 }
00612
00613
00614
00615
00616 void BodyTracker::publishJoints(ros::NodeHandle& nh, tf::TransformBroadcaster& br, std::string joint_name,
00617 nite::SkeletonJoint joint, std::string tf_prefix, std::string rel_frame, int id){
00618
00619 if (joint.getPositionConfidence() > 0.0)
00620 {
00621 tf::Transform transform;
00622 transform.setOrigin(tf::Vector3(joint.getPosition().x/1000.0, -joint.getPosition().y/1000.0,
00623 joint.getPosition().z/1000.0));
00624 tf::Quaternion frame_rotation;
00625 frame_rotation.setEuler(0, 0, 0);
00626 transform.setRotation(frame_rotation);
00627 std::stringstream frame_id_stream;
00628 std::string frame_id;
00629 frame_id_stream << "/" << tf_prefix << "/user_" << id << "/" << joint_name;
00630 frame_id = frame_id_stream.str();
00631
00632 br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), rel_frame, frame_id));
00633 }
00634 }
00635
00636
00637
00638
00639 geometry_msgs::Pose BodyTracker::convertNiteJointToMsgs(nite::SkeletonJoint joint)
00640 {
00641 geometry_msgs::Pose transform_msgs;
00642
00643 if (joint.getPositionConfidence() > 0.0)
00644 {
00645 tf::Transform transform;
00646 transform.setOrigin(tf::Vector3(joint.getPosition().x/1000.0, -joint.getPosition().y/1000.0,
00647 joint.getPosition().z/1000.0));
00648 tf::Quaternion frame_rotation;
00649 frame_rotation.setEuler(0, 0, 0);
00650 transform.setRotation(frame_rotation);
00651 tf::poseTFToMsg(transform, transform_msgs);
00652 }
00653 return transform_msgs;
00654 }
00655
00656
00657
00658
00659 void BodyTracker::drawPointCloud()
00660 {
00661 ros::Time time = ros::Time::now();
00662 uint64_t st = time.toNSec();
00663 pcl_cloud_->header.stamp = st;
00664 pcl_cloud_->header.frame_id = cam_frame_;
00665
00666 pcl_pub_.publish(pcl_cloud_);
00667 pcl_cloud_->points.clear();
00668 }
00669
00670
00671
00672 void BodyTracker::drawLimb(nite::UserTracker* pUserTracker, const nite::SkeletonJoint& joint1, const nite::SkeletonJoint& joint2, int color)
00673 {
00674
00675 }
00676
00677
00678
00679 void BodyTracker::drawSkeleton(nite::UserTracker* pUserTracker, const nite::UserData& userData)
00680 {
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 }
00699
00700
00701
00702
00703 void BodyTracker::drawUserName(const nite::UserData& user, cv::Mat& color_image, cv::Point& tag_coords)
00704 {
00705
00706
00707
00708
00709
00710
00711
00712 }
00713
00714
00715
00716 void BodyTracker::drawFrames(const nite::UserData& user)
00717 {
00718 int r = 255*Colors[user.getId() % colorCount][0];
00719 int g = 255*Colors[user.getId() % colorCount][1];
00720 int b = 255*Colors[user.getId() % colorCount][2];
00721
00722 JointMap joints;
00723 joints["head"] = (user.getSkeleton().getJoint(nite::JOINT_HEAD));
00724 joints["neck"] = (user.getSkeleton().getJoint(nite::JOINT_NECK));
00725 joints["left_shoulder"] = (user.getSkeleton().getJoint(nite::JOINT_LEFT_SHOULDER));
00726 joints["right_shoulder"] = (user.getSkeleton().getJoint(nite::JOINT_RIGHT_SHOULDER));
00727 joints["left_elbow"] = (user.getSkeleton().getJoint(nite::JOINT_LEFT_ELBOW));
00728 joints["right_elbow"] = (user.getSkeleton().getJoint(nite::JOINT_RIGHT_ELBOW));
00729 joints["left_hand"] = (user.getSkeleton().getJoint(nite::JOINT_LEFT_HAND));
00730 joints["right_hand"] = (user.getSkeleton().getJoint(nite::JOINT_RIGHT_HAND));
00731 joints["torso"] = (user.getSkeleton().getJoint(nite::JOINT_TORSO));
00732 joints["left_hip"] = (user.getSkeleton().getJoint(nite::JOINT_LEFT_HIP));
00733 joints["right_hip"] = (user.getSkeleton().getJoint(nite::JOINT_RIGHT_HIP));
00734 joints["left_knee"] = (user.getSkeleton().getJoint(nite::JOINT_LEFT_KNEE));
00735 joints["right_knee"] = (user.getSkeleton().getJoint(nite::JOINT_RIGHT_KNEE));
00736 joints["left_foot"] = (user.getSkeleton().getJoint(nite::JOINT_LEFT_FOOT));
00737 joints["right_foot"] = (user.getSkeleton().getJoint(nite::JOINT_RIGHT_FOOT));
00738
00739 for (JointMap::iterator it=joints.begin(); it!=joints.end(); ++it){
00740 publishJoints(nh_, br_, it->first, it->second, tf_prefix_, rel_frame_, user.getId());
00741 }
00742
00743 drawCircle(r, g, b, joints["head"].getPosition());
00744 drawCircle(r, g, b, joints["right_hand"].getPosition());
00745 drawCircle(r, g, b, joints["left_hand"].getPosition());
00746 drawCircle(r, g, b, joints["right_foot"].getPosition());
00747 drawCircle(r, g, b, joints["left_foot"].getPosition());
00748
00749 drawLine(r, g, b, joints["head"].getPosition(), joints["neck"].getPosition());
00750 drawLine(r, g, b, joints["neck"].getPosition(), joints["left_shoulder"].getPosition());
00751 drawLine(r, g, b, joints["neck"].getPosition(), joints["right_shoulder"].getPosition());
00752 drawLine(r, g, b, joints["right_shoulder"].getPosition(), joints["right_elbow"].getPosition());
00753 drawLine(r, g, b, joints["left_shoulder"].getPosition(), joints["left_elbow"].getPosition());
00754 drawLine(r, g, b, joints["right_elbow"].getPosition(), joints["right_hand"].getPosition());
00755 drawLine(r, g, b, joints["left_elbow"].getPosition(), joints["left_hand"].getPosition());
00756 drawLine(r, g, b, joints["neck"].getPosition(), joints["torso"].getPosition());
00757 drawLine(r, g, b, joints["torso"].getPosition(), joints["left_hip"].getPosition());
00758 drawLine(r, g, b, joints["torso"].getPosition(), joints["right_hip"].getPosition());
00759 drawLine(r, g, b, joints["right_hip"].getPosition(), joints["right_knee"].getPosition());
00760 drawLine(r, g, b, joints["left_hip"].getPosition(), joints["left_knee"].getPosition());
00761 drawLine(r, g, b, joints["right_knee"].getPosition(), joints["right_foot"].getPosition());
00762 drawLine(r, g, b, joints["left_knee"].getPosition(), joints["left_foot"].getPosition());
00763
00764 }
00765
00769 void BodyTracker::drawLine (const double r, const double g, const double b,
00770 const nite::Point3f& pose_start, const nite::Point3f& pose_end )
00771 {
00772 visualization_msgs::Marker marker;
00773 marker.header.frame_id = rel_frame_;
00774 marker.header.stamp = ros::Time::now();
00775 marker.action = visualization_msgs::Marker::ADD;
00776 marker.type = visualization_msgs::Marker::LINE_STRIP;
00777 geometry_msgs::Point p;
00778 marker.id = marker_id_;
00779 p.x = pose_start.x/1000.0;
00780 p.y = -pose_start.y/1000.0;
00781 p.z = pose_start.z/1000.0;
00782 marker.points.push_back(p);
00783 p.x =pose_end.x/1000.0;
00784 p.y = pose_end.y/1000.0;
00785 p.z = pose_end.z/1000.0;
00786 marker.points.push_back(p);
00787 marker.scale.x = 0.019;
00788 marker.scale.y = 0.0;
00789 marker.scale.z = 0.0;
00790 marker.color.r = r;
00791 marker.color.g = g;
00792 marker.color.b = b;
00793 marker.lifetime = ros::Duration(0.01);
00794 vis_pub_.publish(marker);
00795 marker_id_++;
00796 }
00797
00798
00799
00800
00801
00802 void BodyTracker::drawCircle(const double r, const double g, const double b,
00803 const nite::Point3f& pose){
00804 visualization_msgs::Marker m;
00805 m.header.stamp = ros::Time::now();
00806 m.action = visualization_msgs::Marker::ADD;
00807 m.header.frame_id = "/camra_link";
00808 m.type = m.SPHERE;
00809 m.id = marker_id_;
00810 m.pose.position.x = pose.x/1000.0;
00811 m.pose.position.y = -pose.y/1000.0;
00812 m.pose.position.z = pose.z/1000.0;
00813 m.scale.x = .1;
00814 m.scale.y = .1;
00815 m.scale.z = .1;
00816 m.color.r = 1;
00817 m.lifetime = ros::Duration(0.01);
00818 vis_pub_.publish(m);
00819 marker_id_++;
00820 }
00821
00822 void BodyTracker::calculateHistogram(float* pHistogram, int histogramSize, const openni::VideoFrameRef& depthFrame)
00823 {
00824 const openni::DepthPixel* pDepth = (const openni::DepthPixel*)depthFrame.getData();
00825 int width = depthFrame.getWidth();
00826 int height = depthFrame.getHeight();
00827
00828 memset(pHistogram, 0, histogramSize*sizeof(float));
00829 int restOfRow = depthFrame.getStrideInBytes() / sizeof(openni::DepthPixel) - width;
00830
00831 unsigned int nNumberOfPoints = 0;
00832 for (int y = 0; y < height; ++y)
00833 {
00834 for (int x = 0; x < width; ++x, ++pDepth)
00835 {
00836 if (*pDepth != 0)
00837 {
00838 pHistogram[*pDepth]++;
00839 nNumberOfPoints++;
00840 }
00841 }
00842 pDepth += restOfRow;
00843 }
00844 for (int nIndex=1; nIndex<histogramSize; nIndex++)
00845 {
00846 pHistogram[nIndex] += pHistogram[nIndex-1];
00847 }
00848 if (nNumberOfPoints)
00849 {
00850 for (int nIndex=1; nIndex<histogramSize; nIndex++)
00851 {
00852 pHistogram[nIndex] = (256 * (1.0f - (pHistogram[nIndex] / nNumberOfPoints)));
00853 }
00854 }
00855 }
00856
00857 int main(int argc, char** argv)
00858 {
00859 ros::init(argc, argv, "cob_body_tracker");
00860 ros::NodeHandle nh_priv("~");
00861 BodyTracker BodyTracker(nh_priv);
00862
00863 ros::spin();
00864 return 0;
00865
00866 }