Go to the documentation of this file.00001
00061 #ifdef __LINUX__
00062 #include "cob_people_detection/head_detector_node.h"
00063 #include "cob_vision_utils/GlobalDefines.h"
00064 #else
00065 #endif
00066
00067
00068 #include <opencv2/opencv.hpp>
00069 #include <cv_bridge/cv_bridge.h>
00070 #include <sensor_msgs/image_encodings.h>
00071
00072
00073 #include <pcl/point_types.h>
00074 #include <pcl_ros/point_cloud.h>
00075
00076
00077 #include <cob_people_detection/timer.h>
00078
00079 using namespace ipa_PeopleDetector;
00080
00081 HeadDetectorNode::HeadDetectorNode(ros::NodeHandle nh) :
00082 node_handle_(nh)
00083 {
00084 data_directory_ = ros::package::getPath("cob_people_detection") + "/common/files/";
00085
00086
00087 double depth_increase_search_scale;
00088 int depth_drop_groups;
00089 int depth_min_search_scale_x;
00090 int depth_min_search_scale_y;
00091 std::cout << "\n--------------------------\nHead Detector Parameters:\n--------------------------\n";
00092 node_handle_.param("data_directory", data_directory_, data_directory_);
00093 std::cout << "data_directory = " << data_directory_ << "\n";
00094 node_handle_.param("fill_unassigned_depth_values", fill_unassigned_depth_values_, true);
00095 std::cout << "fill_unassigned_depth_values = " << fill_unassigned_depth_values_ << "\n";
00096 node_handle_.param("depth_increase_search_scale", depth_increase_search_scale, 1.1);
00097 std::cout << "depth_increase_search_scale = " << depth_increase_search_scale << "\n";
00098 node_handle_.param("depth_drop_groups", depth_drop_groups, 68);
00099 std::cout << "depth_drop_groups = " << depth_drop_groups << "\n";
00100 node_handle_.param("depth_min_search_scale_x", depth_min_search_scale_x, 20);
00101 std::cout << "depth_min_search_scale_x = " << depth_min_search_scale_x << "\n";
00102 node_handle_.param("depth_min_search_scale_y", depth_min_search_scale_y, 20);
00103 std::cout << "depth_min_search_scale_y = " << depth_min_search_scale_y << "\n";
00104 node_handle_.param("display_timing", display_timing_, false);
00105 std::cout << "display_timing = " << display_timing_ << "\n";
00106
00107
00108 head_detector_.init(data_directory_, depth_increase_search_scale, depth_drop_groups, depth_min_search_scale_x, depth_min_search_scale_y);
00109
00110
00111 head_position_publisher_ = node_handle_.advertise<cob_perception_msgs::ColorDepthImageArray>("head_positions", 1);
00112
00113
00114 pointcloud_sub_ = nh.subscribe("pointcloud_rgb", 1, &HeadDetectorNode::pointcloud_callback, this);
00115
00116 std::cout << "HeadDetectorNode initialized." << std::endl;
00117 }
00118
00119 HeadDetectorNode::~HeadDetectorNode(void)
00120 {
00121 }
00122
00123 void HeadDetectorNode::pointcloud_callback(const sensor_msgs::PointCloud2::ConstPtr& pointcloud)
00124 {
00125
00126
00127
00128
00129
00130 cv::Mat depth_image;
00131 cv::Mat color_image;
00132 convertPclMessageToMat(pointcloud, depth_image, color_image);
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 std::vector<cv::Rect> head_bounding_boxes;
00149 head_detector_.detectRangeFace(depth_image, head_bounding_boxes, fill_unassigned_depth_values_);
00150
00151
00152 cob_perception_msgs::ColorDepthImageArray image_array;
00153 image_array.header = pointcloud->header;
00154 image_array.head_detections.resize(head_bounding_boxes.size());
00155 for (unsigned int i = 0; i < head_bounding_boxes.size(); i++)
00156 {
00157 cv_bridge::CvImage cv_ptr;
00158 image_array.head_detections[i].head_detection.x = head_bounding_boxes[i].x;
00159 image_array.head_detections[i].head_detection.y = head_bounding_boxes[i].y;
00160 image_array.head_detections[i].head_detection.width = head_bounding_boxes[i].width;
00161 image_array.head_detections[i].head_detection.height = head_bounding_boxes[i].height;
00162 cv::Mat depth_patch = depth_image(head_bounding_boxes[i]);
00163 cv_ptr.image = depth_patch;
00164 cv_ptr.encoding = sensor_msgs::image_encodings::TYPE_32FC3;
00165 image_array.head_detections[i].depth_image = *(cv_ptr.toImageMsg());
00166 image_array.head_detections[i].depth_image.header = pointcloud->header;
00167 cv::Mat color_patch = color_image(head_bounding_boxes[i]);
00168 cv_ptr.image = color_patch;
00169 cv_ptr.encoding = sensor_msgs::image_encodings::BGR8;
00170 image_array.head_detections[i].color_image = *(cv_ptr.toImageMsg());
00171 image_array.head_detections[i].color_image.header = pointcloud->header;
00172 }
00173 head_position_publisher_.publish(image_array);
00174
00175 if (display_timing_ == true)
00176 ROS_INFO("%d HeadDetection: Time stamp of pointcloud message: %f. Delay: %f.", pointcloud->header.seq, pointcloud->header.stamp.toSec(),
00177 ros::Time::now().toSec() - pointcloud->header.stamp.toSec());
00178
00179 }
00180
00181 unsigned long HeadDetectorNode::convertPclMessageToMat(const sensor_msgs::PointCloud2::ConstPtr& pointcloud, cv::Mat& depth_image, cv::Mat& color_image)
00182 {
00183 pcl::PointCloud < pcl::PointXYZRGB > depth_cloud;
00184 pcl::fromROSMsg(*pointcloud, depth_cloud);
00185 depth_image.create(depth_cloud.height, depth_cloud.width, CV_32FC3);
00186 color_image.create(depth_cloud.height, depth_cloud.width, CV_8UC3);
00187 uchar* depth_image_ptr = (uchar*)depth_image.data;
00188 uchar* color_image_ptr = (uchar*)color_image.data;
00189 for (int v = 0; v < (int)depth_cloud.height; v++)
00190 {
00191 int depth_base_index = depth_image.step * v;
00192 int color_base_index = color_image.step * v;
00193 for (int u = 0; u < (int)depth_cloud.width; u++)
00194 {
00195 int depth_index = depth_base_index + 3 * u * sizeof(float);
00196 float* depth_data_ptr = (float*)(depth_image_ptr + depth_index);
00197 int color_index = color_base_index + 3 * u * sizeof(uchar);
00198 uchar* color_data_ptr = (uchar*)(color_image_ptr + color_index);
00199 pcl::PointXYZRGB point_xyz = depth_cloud(u, v);
00200 depth_data_ptr[0] = point_xyz.x;
00201 depth_data_ptr[1] = point_xyz.y;
00202 depth_data_ptr[2] = (isnan(point_xyz.z)) ? 0.f : point_xyz.z;
00203 color_data_ptr[0] = point_xyz.r;
00204 color_data_ptr[1] = point_xyz.g;
00205 color_data_ptr[2] = point_xyz.b;
00206
00207 }
00208 }
00209 return ipa_Utils::RET_OK;
00210 }
00211
00212
00213
00214 int main(int argc, char** argv)
00215 {
00216
00217 ros::init(argc, argv, "head_detector");
00218
00219
00220 ros::NodeHandle nh("~");
00221
00222
00223 HeadDetectorNode head_detector_node(nh);
00224
00225
00226
00227
00228
00229
00230 ros::spin();
00231
00232 return 0;
00233 }