00001 #include "iros12_planar_removal.h"
00002
00003 using namespace Eigen;
00004
00005
00006 PlanarRemovalIROS2012::PlanarRemovalIROS2012() : it_(nh_) {
00007
00008
00009
00010
00011
00012
00013 this->pcl2_sub_ = this->nh_.subscribe<sensor_msgs::PointCloud2>("/planar_removal_iros2012/pcl2/input", 1, &PlanarRemovalIROS2012::pcl2_sub_callback, this);
00014
00015
00016 this->image_pub_ = this->it_.advertise("/planar_removal_iros2012/image/dense", 1);
00017
00018
00019
00020 this->pcl2_pub_ = this->nh_.advertise<sensor_msgs::PointCloud2>("/planar_removal_iros2012/pcl2/output", 15);
00021 this->pcl2_planes_pub_ = this->nh_.advertise<sensor_msgs::PointCloud2>("/planar_removal_iros2012/pcl2/planes_output", 15);
00022
00023 this->coefficients_pub_ = this->nh_.advertise<pcl::ModelCoefficients> ("/planar_removal_iros2012/ModelCoefficients/output", 1);
00024
00025
00026 dynamic_reconfigure::Server<iri_pcl_filters::IriPclFiltersParametersConfig>::CallbackType reconfig_callback_type = boost::bind(&PlanarRemovalIROS2012::reconfigureCallback, this, _1, _2);
00027
00028 dyn_reconfig_srv.setCallback(reconfig_callback_type);
00029
00030
00031
00032
00033
00034
00035
00036 ROS_INFO("starting planar_removal_iros2012");
00037
00038 }
00039
00040
00041 void PlanarRemovalIROS2012::reconfigureCallback(iri_pcl_filters::IriPclFiltersParametersConfig &config, uint32_t level)
00042 {
00043 ROS_INFO("Reconfigure request : distance th: %f lasting_cloud: %f #planes: %d ",
00044 config.distance_threshold, config.cloud_remaining_proportion_threshold, config.max_num_of_planes_removed);
00045
00046 mutex.enter();
00047 distance_threshold_ = config.distance_threshold;
00048 cloud_remaining_proportion_threshold_ = config.cloud_remaining_proportion_threshold;
00049 max_num_of_planes_removed_ = config.max_num_of_planes_removed;
00050 mutex.exit();
00051
00052 }
00053
00054 PlanarRemovalIROS2012::~PlanarRemovalIROS2012(){
00055
00056 }
00057
00058 void PlanarRemovalIROS2012::removePlanesXYZ(pcl::PointCloud<pcl::PointXYZ> cloud,pcl::PointCloud<pcl::PointXYZRGB>& cloud_filtered,pcl::PointCloud<pcl::PointXYZRGB>& cloud_planes){
00059
00060 pcl::PointCloud<pcl::PointXYZ> one_plane;
00061 pcl::copyPointCloud(cloud, cloud_filtered);
00062
00063 pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients ());
00064 pcl::PointIndices::Ptr inliers(new pcl::PointIndices ());
00065
00066 pcl::SACSegmentation<pcl::PointXYZ> seg;
00067
00068 double distance_threshold_aux;
00069 double cloud_remaining_proportion_threshold_aux;
00070
00071 mutex.enter();
00072 distance_threshold_aux = distance_threshold_;
00073 cloud_remaining_proportion_threshold_aux = cloud_remaining_proportion_threshold_;
00074 mutex.exit();
00075
00076
00077 cloud_planes.width = cloud.width;
00078 cloud_planes.height = cloud.height;
00079 cloud_planes.points.resize (one_plane.width * one_plane.height);
00080 cloud_planes.is_dense = cloud.is_dense;
00081 cloud_planes.header = cloud.header;
00082
00083
00084 seg.setOptimizeCoefficients (true);
00085
00086
00087 seg.setModelType (pcl::SACMODEL_PLANE);
00088 seg.setMethodType (pcl::SAC_RANSAC);
00089 seg.setDistanceThreshold (distance_threshold_aux);
00090
00091 seg.setInputCloud (cloud.makeShared ());
00092 seg.segment (*inliers, *coefficients);
00093
00094 coefficients_pub_.publish (*coefficients);
00095
00096 if (inliers->indices.size () == 0) {
00097 ROS_INFO("Could not estimate a planar model for the given dataset.");
00098 return;
00099 }
00100
00101
00102 pcl::ExtractIndices<pcl::PointXYZ> extract;
00103
00104
00105 extract.setInputCloud (cloud.makeShared());
00106 extract.setIndices (inliers);
00107 extract.setNegative (false);
00108 extract.filter (one_plane);
00109
00110 pcl::copyPointCloud(one_plane, cloud_planes);
00111
00112 ROS_INFO("points ok %d",inliers->indices.size());
00113 for(int j = 0; j < inliers->indices.size(); j++){
00114 uint8_t r = 255, g = 0, b = 0;
00115 uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
00116 cloud_filtered[inliers->indices[j]].rgb = *reinterpret_cast<float*>(&rgb);
00117 }
00118
00119 cv::Mat mask(480,640,CV_8UC1);
00120 mask.setTo(255);
00121
00122 int z=0;
00123 uint8_t r = 255, g = 0, b = 0;
00124 uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
00125
00126 for(int j=0;j<mask.rows;j++)
00127 {
00128 for(int i=0;i<mask.cols;i++)
00129 {
00130 if(cloud_filtered[z].rgb == *reinterpret_cast<float*>(&rgb) || isnan(cloud_filtered[z].z))
00131 mask.ptr(j)[i]=(uint)0;
00132 z++;
00133 }
00134 }
00135 cv::imwrite("/tmp/tamp.png",mask);
00136 }
00137
00138
00139 void PlanarRemovalIROS2012::removePlanesXYZRGB(pcl::PointCloud<pcl::PointXYZRGB> cloud,pcl::PointCloud<pcl::PointXYZRGB>& cloud_filtered,pcl::PointCloud<pcl::PointXYZRGB>& cloud_planes){
00140
00141 pcl::PointCloud<pcl::PointXYZRGB> color_valid_points;
00142 pcl::PointCloud<pcl::PointXYZRGB> one_plane;
00143 pcl::PointCloud<pcl::PointXYZRGB> unstructured_cloud;
00144
00145 pcl::copyPointCloud(cloud, cloud_filtered);
00146
00147 pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients ());
00148 pcl::PointIndices::Ptr inliers(new pcl::PointIndices ());
00149
00150 pcl::SACSegmentation<pcl::PointXYZRGB> seg;
00151
00152 double distance_threshold_aux;
00153 double cloud_remaining_proportion_threshold_aux;
00154
00155 mutex.enter();
00156 distance_threshold_aux = distance_threshold_;
00157 cloud_remaining_proportion_threshold_aux = cloud_remaining_proportion_threshold_;
00158 mutex.exit();
00159
00160
00161 cloud_planes.width = cloud.width;
00162 cloud_planes.height = cloud.height;
00163 cloud_planes.points.resize (one_plane.width * one_plane.height);
00164 cloud_planes.is_dense = cloud.is_dense;
00165 cloud_planes.header = cloud.header;
00166
00167 if(0)
00168 {
00169 RGBValue color_accept;
00170 color_accept.Red=143.4074;
00171 color_accept.Green=134.5007;
00172 color_accept.Blue=134.8869;
00173
00174 pcl::ComparisonBase<pcl::PointXYZRGB>::Ptr color_filter(new ConditionColor(color_accept, 28.3));
00175 pcl::ConditionAnd<pcl::PointXYZRGB>::Ptr andfilter(new pcl::ConditionAnd<pcl::PointXYZRGB>);
00176 andfilter->addComparison(color_filter);
00177 pcl::ConditionalRemoval<pcl::PointXYZRGB> condrem (andfilter);
00178
00179 condrem.setInputCloud(cloud.makeShared());
00180 condrem.setKeepOrganized(true);
00181 pcl::PointIndicesPtr inliers3(new pcl::PointIndices);
00182 for (int i=0;i<cloud.width*cloud.height;i++)
00183 inliers3->indices.push_back(i);
00184 std::cout<<" s0120941093 "<< inliers3->indices.size();
00185 condrem.setIndices(inliers3);
00186 pcl::IndicesConstPtr inliers2;
00187 inliers2=condrem.getRemovedIndices();
00188 condrem.filter(color_valid_points);
00189
00190 for(int i=0;i<inliers2->size();i++)
00191 {
00192 std::cout<<(*inliers2)[i]<<" ";
00193 inliers->indices.push_back((*inliers2)[i]);
00194 }
00195 }else{
00196
00197 seg.setOptimizeCoefficients (true);
00198
00199
00200 seg.setModelType (pcl::SACMODEL_PLANE);
00201 seg.setMethodType (pcl::SAC_RANSAC);
00202 seg.setDistanceThreshold (distance_threshold_aux);
00203
00204 seg.setInputCloud (cloud.makeShared ());
00205 seg.segment (*inliers, *coefficients);
00206
00207 coefficients_pub_.publish (*coefficients);
00208 }
00209
00210 pcl::ExtractIndices<pcl::PointXYZRGB> extract;
00211
00212
00213
00214
00215
00216
00217 if (inliers->indices.size () == 0) {
00218 ROS_INFO("Could not estimate a planar model for the given dataset.");
00219 return;
00220 }
00221
00222
00223 extract.setInputCloud (cloud.makeShared());
00224 extract.setIndices (inliers);
00225 extract.setNegative (false);
00226 extract.filter (one_plane);
00227
00228 cloud_planes += one_plane;
00229
00230 ROS_INFO("points ok %d",inliers->indices.size());
00231 for(int j = 0; j < inliers->indices.size(); j++){
00232 uint8_t r = 255, g = 0, b = 0;
00233 uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
00234 cloud_filtered[inliers->indices[j]].rgb = *reinterpret_cast<float*>(&rgb);
00235 }
00236
00237 cv::Mat mask(480,640,CV_8UC1);
00238 mask.setTo(255);
00239
00240 int z=0;
00241 uint8_t r = 255, g = 0, b = 0;
00242 uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
00243
00244 for(int j=0;j<mask.rows;j++)
00245 {
00246 for(int i=0;i<mask.cols;i++)
00247 {
00248 if(cloud_filtered[z].rgb == *reinterpret_cast<float*>(&rgb) )
00249 mask.ptr(j)[i]=(uint)0;
00250 z++;
00251 }
00252 }
00253 cv::imwrite("/tmp/tamp.png",mask);
00254 }
00255
00256
00257 void PlanarRemovalIROS2012::pcl2_sub_callback(const sensor_msgs::PointCloud2::ConstPtr& pcl2_msg_) {
00258
00259
00260
00261
00262
00263
00264
00265 cv::Mat rgb_image;
00266 pcl::PointCloud<pcl::PointXYZRGB> pcl_xyzrgb_aux;
00267 pcl::PointCloud<pcl::PointXYZ> pcl_xyz_aux;
00268
00269
00270 if(sensor_msgs::getPointCloud2FieldIndex(*pcl2_msg_,"rgb")!=-1)
00271 {
00272 pcl::fromROSMsg(*pcl2_msg_, pcl_xyzrgb_);
00273 removePlanesXYZRGB(pcl_xyzrgb_, pcl_xyzrgb_aux, pcl_planes_xyzrgb_);
00274 }
00275 else
00276 {
00277 pcl::fromROSMsg(*pcl2_msg_, pcl_xyz_);
00278 removePlanesXYZ(pcl_xyz_, pcl_xyzrgb_aux, pcl_planes_xyzrgb_);
00279 }
00280
00281
00282
00283 rgb_image.create(pcl_xyzrgb_aux.height, pcl_xyzrgb_aux.width, CV_8UC3);
00284
00285 cv_image.header.stamp = ros::Time::now();
00286 cv_image.header.frame_id = "camera";
00287 cv_image.encoding = "bgr8";
00288
00289 rgb_image = cv::Mat::zeros(rgb_image.size(), CV_8UC3);
00290 image_from_sparse_pcl2(pcl_xyzrgb_aux,rgb_image);
00291 cv_image.image = rgb_image;
00292
00293 image_pub_.publish(cv_image.toImageMsg());
00294
00295 pcl::toROSMsg(pcl_xyzrgb_, pcl2_filtered_msg_);
00296
00297 pcl2_pub_.publish(pcl2_filtered_msg_);
00298
00299 pcl::toROSMsg(pcl_planes_xyzrgb_, pcl2_planes_msg_);
00300 pcl2_planes_pub_.publish(pcl2_planes_msg_);
00301
00302 }
00303
00304 void PlanarRemovalIROS2012::image_from_pcl2(cv::Mat& rgb_image){
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 }
00320
00321 void PlanarRemovalIROS2012::image_from_sparse_pcl2(pcl::PointCloud<pcl::PointXYZRGB> cloud, cv::Mat& rgb_image){
00322
00323 pcl::PointCloud<pcl::PointXYZRGB>::iterator pt_iter_xyzrgb = cloud.begin();
00324
00325 if(cloud.height != rgb_image.rows || cloud.width != rgb_image.cols){
00326 ROS_ERROR("Size mismatch between point cloud and rgb_image");
00327 ROS_INFO("xyzrgb size %d %d data size %d xyz %d %d data size %d rgb_image %d %d",pcl_xyzrgb_.height, pcl_xyzrgb_.width, pcl_xyzrgb_.size(),cloud.height, cloud.width, cloud.size(), rgb_image.rows, rgb_image.cols);
00328 } else {
00329 for (int rr = 0; rr < cloud.height; ++rr) {
00330 for (int cc = 0; cc < cloud.width; ++cc, ++pt_iter_xyzrgb) {
00331 pcl::PointXYZRGB &pt_xyzrgb = *pt_iter_xyzrgb;
00332 RGBValue color;
00333 color.float_value = pt_xyzrgb.rgb;
00334 if(isnan(pt_iter_xyzrgb->x) && isnan(pt_iter_xyzrgb->y) && isnan(pt_iter_xyzrgb->z)){
00335 rgb_image.at<cv::Vec3b>(rr,cc)[0] = 0;
00336 rgb_image.at<cv::Vec3b>(rr,cc)[1] = 0;
00337 rgb_image.at<cv::Vec3b>(rr,cc)[2] = 0;
00338 }else{
00339 rgb_image.at<cv::Vec3b>(rr,cc)[0] = color.Blue;
00340 rgb_image.at<cv::Vec3b>(rr,cc)[1] = color.Green;
00341 rgb_image.at<cv::Vec3b>(rr,cc)[2] = color.Red;
00342 }
00343 }
00344 }
00345 }
00346 }
00347
00348 int main(int argc, char** argv)
00349 {
00350 ros::init(argc, argv, "planar_removal_iros2012");
00351 PlanarRemovalIROS2012 planar_removal;
00352 ros::spin();
00353 return 0;
00354 }
00355