00001
00031 #include <ros/ros.h>
00032 #include <sensor_msgs/PointCloud2.h>
00033 #include <sensor_msgs/Image.h>
00034 #include <pcl/ros/conversions.h>
00035 #include <pcl/point_cloud.h>
00036 #include <cv_bridge/CvBridge.h>
00037 #include <pcl/io/pcd_io.h>
00038 #include <pcl/point_types.h>
00039 #include <highgui.h>
00040 #include <cv.h>
00041 #include <pcl/io/pcd_io.h>
00042 #include <boost/thread/mutex.hpp>
00043 #include <pcl/features/feature.h>
00044 #include <pcl/registration/registration.h>
00045 #include <pcl/registration/transformation_estimation.h>
00046 #include <pcl/common/transformation_from_correspondences.h>
00047 #include <std_msgs/String.h>
00048 #include <tf/transform_broadcaster.h>
00049
00050 #include <geometry_msgs/Point.h>
00051
00052 #include <cv_bridge/cv_bridge.h>
00053
00054 #include "re_kinect_object_detector/DetectionResult.h"
00055
00056 #include "recognitionmodel.h"
00057
00059 tf::Transform tfFromEigen(Eigen::Matrix4f trans)
00060 {
00061 btMatrix3x3 btm;
00062 btm.setValue(trans(0,0),trans(0,1),trans(0,2),
00063 trans(1,0),trans(1,1),trans(1,2),
00064 trans(2,0),trans(2,1),trans(2,2));
00065 btTransform ret;
00066 ret.setOrigin(btVector3(trans(0,3),trans(1,3),trans(2,3)));
00067 ret.setBasis(btm);
00068 return ret;
00069 }
00070
00074 class ROSCom {
00075 public:
00076 ROSCom() {
00077 ros::NodeHandle nh;
00078 kinect_sub = nh.subscribe<sensor_msgs::PointCloud2>("camera/depth_registered/points",1,
00079 boost::bind(&ROSCom::kinect_cb,this,_1));
00080 features_pub = nh.advertise<sensor_msgs::PointCloud2>("re_kinect/feature_pcl",10);
00081
00082 model_sub = nh.subscribe<std_msgs::String>("re_kinect/model_path", 1000, boost::bind(&ROSCom::model_path_cb, this, _1));
00083
00084 detected_objects_pub = nh.advertise<re_kinect_object_detector::DetectionResult>("re_kinect/detection_results", 10);
00085 }
00086
00088 void model_path_cb(const std_msgs::StringConstPtr& model_path_msg) {
00089 boost::mutex::scoped_lock lock(mutex);
00090 ROS_INFO("model path callback; path = %s", model_path_msg->data.c_str());
00091
00092 std::string model_path = model_path_msg->data;
00093 if (models.find(model_path) != models.end()) {
00094 ROS_WARN("model path '%s' was already known. Ignoring.", model_path.c_str());
00095 return;
00096 }
00097
00098 RecognitionModel model;
00099 if (model.loadFromPath(model_path))
00100 models.insert(std::make_pair(model_path, model));
00101
00102 ROS_INFO("done loading model from %s", model_path.c_str());
00103 }
00104
00106 void kinect_cb(const sensor_msgs::PointCloud2ConstPtr& pcl_msg) {
00107 boost::mutex::scoped_lock lock(mutex);
00108
00109 if (models.empty()) {
00110 static bool first_call = true;
00111 if (first_call) {
00112 ROS_WARN("no model files loaded!");
00113 first_call = false;
00114 }
00115 return;
00116 }
00117
00118
00119 PointCloud cloud_;
00120
00121 pcl::fromROSMsg(*pcl_msg, cloud_);
00122
00123 sensor_msgs::ImagePtr image_(new sensor_msgs::Image);
00124
00125 pcl::toROSMsg (cloud_, *image_);
00126 cv_bridge::CvImageConstPtr capture_ = cv_bridge::toCvShare(image_, "bgr8");
00127
00128 ROS_INFO("received point cloud");
00129
00130
00131 ObjectAspect scene;
00132
00133 scene.calculate(capture_->image,cloud_.makeShared());
00134
00135 Eigen::Matrix4f t;
00136
00137 PointCloud feature_cloud;
00138 sensor_msgs::PointCloud2 feature_msg;
00139 int i = 0;
00140 re_kinect_object_detector::DetectionResult resultMsg;
00141 for(std::map<std::string, RecognitionModel>::iterator it=models.begin(); it!=models.end(); it++, i++) {
00142 RecognitionModel& model = it->second;
00143 re_msgs::DetectedObject detectedObjMsg;
00144
00145
00146 if (model.matchAspects(scene, t)) {
00147
00148
00149 ROS_INFO("displaying %d points in frame: %s",(int)scene.match->points->size(),pcl_msg->header.frame_id.c_str());
00150
00151 PointCloud cloudtransformed;
00152 pcl::transformPointCloud(*scene.match->points, cloudtransformed, t);
00153
00154 if (i == 0)
00155 feature_cloud = cloudtransformed;
00156 else
00157 feature_cloud += cloudtransformed;
00158
00159 for (size_t j=0 ; j< cloudtransformed.points.size(); j++ ){
00160 PointType pt = cloudtransformed.points.at(j);
00161 if (!isnan(pt.x)){
00162 int y = pt.y*525.0 / pt.z + capture_->image.size().height / 2;
00163 int x = pt.x*525.0 / pt.z + capture_->image.size().width / 2;
00164
00165 re_msgs::Pixel px;
00166 px.x = x;
00167 px.y = y;
00168 detectedObjMsg.points2d.push_back(px);
00169
00170 geometry_msgs::Point threeD_pt;
00171 threeD_pt.x = pt.x;
00172 threeD_pt.y = pt.y;
00173 threeD_pt.z = pt.z;
00174
00175 detectedObjMsg.points3d.push_back(threeD_pt);
00176 }
00177 }
00178 tf::Transform object_tf = tfFromEigen(t);
00179 tf_broadcaster.sendTransform(tf::StampedTransform(object_tf, pcl_msg->header.stamp, pcl_msg->header.frame_id, model.model_name));
00180
00181 resultMsg.ObjectNames.push_back(model.model_name);
00182 resultMsg.Detections.push_back(detectedObjMsg);
00183
00184 }
00185 cv_bridge::CvImage out_msg;
00186 out_msg.header = pcl_msg->header;
00187 out_msg.encoding = "bgr8";
00188 out_msg.image = capture_->image;
00189
00190 out_msg.toImageMsg(resultMsg.Image);
00191 detected_objects_pub.publish(resultMsg);
00192 }
00193 pcl::toROSMsg(feature_cloud,feature_msg);
00194
00195 feature_msg.header.frame_id = pcl_msg->header.frame_id;
00196 feature_msg.header.stamp = pcl_msg->header.stamp;
00197
00198 features_pub.publish(feature_msg);
00199 }
00200
00201
00202 ros::Subscriber kinect_sub;
00203 ros::Subscriber model_sub;
00204 ros::Publisher features_pub;
00205 ros::Publisher detected_objects_pub;
00206 tf::TransformBroadcaster tf_broadcaster;
00207 boost::mutex mutex;
00208
00210 std::map<std::string, RecognitionModel> models;
00211 };
00212
00213
00214 int main(int argc, char* argv[]) {
00215
00216 ros::init(argc,argv,"exec");
00217
00218 ROSCom roscom;
00219
00220 #ifdef DEBUG_VIS
00221 cv::startWindowThread();
00222 #endif
00223 ros::spin();
00224
00225
00226 return 0;
00227 }