Go to the documentation of this file.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 #include <ros/ros.h>
00059 #include <cv_bridge/cv_bridge.h>
00060 #include <sensor_msgs/image_encodings.h>
00061 #include <image_transport/image_transport.h>
00062 #include <image_transport/subscriber_filter.h>
00063 #include <message_filters/sync_policies/approximate_time.h>
00064 #include <message_filters/synchronizer.h>
00065 #include <message_filters/subscriber.h>
00066
00067 #include <pluginlib/class_list_macros.h>
00068 #include <nodelet/nodelet.h>
00069
00070
00071 #include <sensor_msgs/Image.h>
00072 #include <sensor_msgs/PointCloud2.h>
00073 #include <std_msgs/Float64.h>
00074
00075 using namespace message_filters;
00076
00077 typedef sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::PointCloud2> SyncPolicy;
00078
00079
00080
00081
00082 class CreateColoredPointCloud : public nodelet::Nodelet
00083 {
00084 private:
00085 ros::NodeHandle n_;
00086
00087
00088 image_transport::ImageTransport image_transport_;
00089 image_transport::SubscriberFilter color_image_sub_;
00090 message_filters::Subscriber<sensor_msgs::PointCloud2> pc_sub_;
00091
00092 boost::shared_ptr<message_filters::Synchronizer<SyncPolicy> > pc_sync_;
00093
00094
00095 cv::Mat c_color_image_8U3_;
00096
00097
00098 ros::Publisher pc_pub_;
00099
00100 int num_subs;
00101
00102 public:
00103
00104 CreateColoredPointCloud()
00105 : image_transport_(n_),
00106 num_subs(0)
00107 {}
00108
00109
00110 ~CreateColoredPointCloud()
00111 {
00112 }
00113
00114 void initNode()
00115 {
00116 pc_sync_ = boost::shared_ptr<message_filters::Synchronizer<SyncPolicy> >(new message_filters::Synchronizer<SyncPolicy>(SyncPolicy(3)));
00117 pc_pub_ = n_.advertise<sensor_msgs::PointCloud2>("colored_point_cloud2", 1, boost::bind(&CreateColoredPointCloud::connectCb, this), boost::bind(&CreateColoredPointCloud::disconnectCb, this));
00118
00119
00120
00121 pc_sync_->connectInput(color_image_sub_, pc_sub_);
00122 pc_sync_->registerCallback(boost::bind(&CreateColoredPointCloud::syncCallback, this, _1, _2));
00123 }
00124
00125 virtual void onInit()
00126 {
00127 n_ = getNodeHandle();
00128 image_transport_ = image_transport::ImageTransport(n_);
00129 initNode();
00130 }
00131
00132
00133 void connectCb()
00134 {
00135 num_subs++;
00136 if(num_subs > 0)
00137 {
00138 color_image_sub_.subscribe(image_transport_,"image_color", 1);
00139 pc_sub_.subscribe(n_, "point_cloud2", 1);
00140 }
00141 }
00142
00143 void disconnectCb()
00144 {
00145 num_subs--;
00146 if(num_subs <= 0)
00147 {
00148 color_image_sub_.unsubscribe();
00149 pc_sub_.unsubscribe();
00150 }
00151 }
00152
00153
00154
00155
00156 void syncCallback(const sensor_msgs::Image::ConstPtr& img_rgb, const sensor_msgs::PointCloud2::ConstPtr& pc)
00157 {
00158 sensor_msgs::PointCloud2 cpc_msg;
00159
00160 cpc_msg.header = pc->header;
00161
00162 cv_bridge::CvImagePtr cv_ptr;
00163 try
00164 {
00165 cv_ptr = cv_bridge::toCvCopy(img_rgb,sensor_msgs::image_encodings::BGR8);
00166 }
00167 catch (cv_bridge::Exception& e)
00168 {
00169 ROS_ERROR("cv_bridge exception: %s", e.what());
00170 return;
00171 }
00172
00173
00174
00175 cpc_msg.width = pc->width;
00176 cpc_msg.height = pc->height;
00177 cpc_msg.fields.resize(4);
00178 cpc_msg.fields[0].name = "x";
00179 cpc_msg.fields[0].datatype = sensor_msgs::PointField::FLOAT32;
00180 cpc_msg.fields[1].name = "y";
00181 cpc_msg.fields[1].datatype = sensor_msgs::PointField::FLOAT32;
00182 cpc_msg.fields[2].name = "z";
00183 cpc_msg.fields[2].datatype = sensor_msgs::PointField::FLOAT32;
00184 cpc_msg.fields[3].name = "rgb";
00185 cpc_msg.fields[3].datatype = sensor_msgs::PointField::FLOAT32;
00186 int offset = 0;
00187 for (size_t d = 0; d < cpc_msg.fields.size(); d++, offset += 4)
00188 {
00189 cpc_msg.fields[d].offset = offset;
00190 }
00191 cpc_msg.point_step = offset;
00192 cpc_msg.row_step = cpc_msg.point_step * cpc_msg.width;
00193 cpc_msg.data.resize (cpc_msg.width*cpc_msg.height*cpc_msg.point_step);
00194 cpc_msg.is_dense = true;
00195 cpc_msg.is_bigendian = false;
00196
00197 unsigned char* c_ptr = 0;
00198 int cpc_msg_idx=0;
00199 for (int row = 0; row < cv_ptr->image.rows; row++)
00200 {
00201 c_ptr = cv_ptr->image.ptr<unsigned char>(row);
00202
00203 for (int col = 0; col < cv_ptr->image.cols; col++, cpc_msg_idx++)
00204 {
00205 memcpy(&cpc_msg.data[cpc_msg_idx * cpc_msg.point_step], &pc->data[cpc_msg_idx * pc->point_step], 3*sizeof(float));
00206 memcpy(&cpc_msg.data[cpc_msg_idx * cpc_msg.point_step + cpc_msg.fields[3].offset], &c_ptr[3*col], 3*sizeof(unsigned char));
00207 }
00208 }
00209 pc_pub_.publish(cpc_msg);
00210 }
00211
00212 };
00213
00214
00215
00216 int main(int argc, char** argv)
00217 {
00218
00219 ros::init(argc, argv, "cpc_publisher");
00220
00221 CreateColoredPointCloud cpcPublisher;
00222 cpcPublisher.initNode();
00223
00224 ros::spin();
00225
00226 return 0;
00227 }
00228
00229
00230 PLUGINLIB_DECLARE_CLASS(cob_gazebo, CreateColoredPointCloud, CreateColoredPointCloud, nodelet::Nodelet);
00231
00232
00233