segment_cluster_creator.cpp
Go to the documentation of this file.
00001 #include <segment_cluster_creator.hpp>
00002 #include <boost/date_time/posix_time/posix_time.hpp>
00003 #include <boost/date_time/posix_time/posix_time_io.hpp>
00004 
00005 using namespace pcl;
00006 
00007 EuclideanCluster::EuclideanCluster(ros::NodeHandle nh, ros::NodeHandle n)
00008     : nh_(nh),
00009       rate_(n.param("loop_rate", 10)),
00010       accumulation_counter_(0),
00011       frame_id_(n.param<std::string>("clustering_frame_id", "base_link"))
00012 {
00013   source_pc_sub_ = nh_.subscribe(n.param<std::string>("source_pc_topic_name", "/hokuyo3d/hokuyo_cloud2"), 1, &EuclideanCluster::EuclideanCallback, this);
00014   fileterd_cloud_pub_ = nh_.advertise<sensor_msgs::PointCloud2>(n.param<std::string>("filtered_pc_topic_name", "/filtered_pointcloud"), 1);
00015   euclidean_cluster_pub_ = nh_.advertise<jsk_recognition_msgs::BoundingBoxArray>(n.param<std::string>("box_name", "/clustering_result"), 1);
00016 
00017   // クラスタリングのパラメータを初期化
00018   n.param<double>("clusterTolerance", clusterTolerance_, 0.3);
00019   n.param<int>("minSize", minSize_, 100);
00020   n.param<int>("maxSize", maxSize_, 25000);
00021   // clopboxを当てはめるエリアを定義
00022   n.param<float>("crop_x_min", crop_min_.x, -35.5);
00023   n.param<float>("crop_x_max", crop_max_.x, 35.5);
00024   n.param<float>("crop_y_min", crop_min_.y, -35.5);
00025   n.param<float>("crop_y_max", crop_max_.y, 35.5);
00026   n.param<float>("crop_z_min", crop_min_.z, 0.05);
00027   n.param<float>("crop_z_max", crop_max_.z, 15.5);
00028 
00029   boost::posix_time::ptime thistime = boost::posix_time::from_time_t(ros::Time::now().toSec());
00030   output_file_prefix_ = to_simple_string(thistime) + "Cluster_";
00031 }
00032 
00033 void EuclideanCluster::EuclideanCallback(
00034     const sensor_msgs::PointCloud2::ConstPtr &source_pc) {
00035 
00036   //点群をKinect座標系からWorld座標系に変換
00037   //変換されたデータはtrans_pcに格納される.
00038   sensor_msgs::PointCloud2 trans_pc;
00039   try {
00040     pcl_ros::transformPointCloud(frame_id_, *source_pc, trans_pc, tf_);
00041   } catch (tf::ExtrapolationException e) {
00042     ROS_ERROR("pcl_ros::transformPointCloud %s", e.what());
00043   }
00044 
00045   // sensor_msgs::PointCloud2 → pcl::PointCloud
00046   pcl::PointCloud<PointXYZI> pcl_source;
00047   pcl::fromROSMsg(trans_pc, pcl_source);
00048   pcl::PointCloud<PointXYZI>::Ptr pcl_source_ptr(new pcl::PointCloud<PointXYZI>(pcl_source));
00049 
00050   // 点群の中からnanを消す
00051   // std::vector<int> dummy;
00052   // pcl::removeNaNFromPointCloud(*pcl_source_ptr, *pcl_source_ptr, dummy);
00053 
00054   // Create the filtering object
00055   pcl::StatisticalOutlierRemoval<pcl::PointXYZI> sor;
00056   sor.setInputCloud (pcl_source_ptr);
00057   sor.setMeanK (100);
00058   sor.setStddevMulThresh (0.1);
00059   sor.filter (*pcl_source_ptr);
00060 
00061   // 平面をしきい値で除去する→Cropboxで
00062   CropBox(pcl_source_ptr, crop_min_, crop_max_);
00063 
00064   // 処理後の点群をpublish
00065   sensor_msgs::PointCloud2 filtered_pc2;
00066   pcl::toROSMsg(*pcl_source_ptr, filtered_pc2);
00067   filtered_pc2.header.stamp = ros::Time::now();
00068   filtered_pc2.header.frame_id = "base_link";
00069   fileterd_cloud_pub_.publish(filtered_pc2);
00070 
00071   // Creating the KdTree object for the search method of the extraction
00072   Clustering(pcl_source_ptr);
00073 }
00074 
00075 void EuclideanCluster::CropBox(pcl::PointCloud<pcl::PointXYZI>::Ptr cloud,
00076                                pcl::PointXYZ min, pcl::PointXYZ max) {
00077   Eigen::Vector4f minPoint;
00078 
00079   minPoint[0] = min.x; // define minimum point x
00080   minPoint[1] = min.y; // define minimum point y
00081   minPoint[2] = min.z; // define minimum point z
00082 
00083   Eigen::Vector4f maxPoint;
00084   maxPoint[0] = max.x; // define max point x
00085   maxPoint[1] = max.y; // define max point y
00086   maxPoint[2] = max.z; // define max point z
00087 
00088   Eigen::Vector3f boxTranslatation;
00089   boxTranslatation[0] = 0;
00090   boxTranslatation[1] = 0;
00091   boxTranslatation[2] = 0;
00092 
00093   Eigen::Vector3f boxRotation;
00094   boxRotation[0] = 0; // rotation around x-axis
00095   boxRotation[1] = 0; // rotation around y-axis
00096   boxRotation[2] = 0; // in radians rotation around z-axis. this rotates your
00097 
00098   Eigen::Affine3f boxTransform;
00099 
00100   pcl::CropBox<pcl::PointXYZI> cropFilter;
00101   cropFilter.setInputCloud(cloud);
00102   cropFilter.setMin(minPoint);
00103   cropFilter.setMax(maxPoint);
00104   cropFilter.setTranslation(boxTranslatation);
00105   cropFilter.setRotation(boxRotation);
00106 
00107   pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>());
00108   cropFilter.filter(*cloud_filtered);
00109   pcl::copyPointCloud<pcl::PointXYZI, pcl::PointXYZI>(*cloud_filtered, *cloud);
00110 }
00111 
00112 void EuclideanCluster::Clustering(pcl::PointCloud<pcl::PointXYZI>::Ptr cloud) {
00113   pcl::search::KdTree<pcl::PointXYZI>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZI>);
00114   tree->setInputCloud(cloud);
00115 
00116   std::vector<pcl::PointIndices> cluster_indices;
00117   pcl::EuclideanClusterExtraction<pcl::PointXYZI> ec;
00118   ec.setClusterTolerance(clusterTolerance_);
00119   ec.setMinClusterSize(minSize_);
00120   ec.setMaxClusterSize(maxSize_);
00121   ec.setSearchMethod(tree);
00122   ec.setInputCloud(cloud);
00123   ec.extract(cluster_indices);
00124 
00125   int j = 0;
00126   jsk_recognition_msgs::BoundingBoxArray box_array; // clustering結果をぶち込む配列
00127 
00128   for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin(); it != cluster_indices.end(); ++it) {
00129     pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZI>);
00130     for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); ++pit)
00131       cloud_cluster->points.push_back(cloud->points[*pit]);
00132 
00133     cloud_cluster->width = cloud_cluster->points.size();
00134     cloud_cluster->height = 1;
00135     cloud_cluster->is_dense = true;
00136 
00137     std::stringstream filename;
00138     filename << output_file_prefix_ << std::setw(4) << std::setfill('0') <<  accumulation_counter_;
00139     pcl::io::savePCDFileASCII ("./"+filename.str()+".pcd" , *cloud_cluster);
00140     // 一つのclusterをpushback
00141     j++;
00142     accumulation_counter_++;
00143   }
00144 
00145   // int clusterLength = clusterIndices.size();
00146   ROS_INFO("Found %lu clusters:", cluster_indices.size());
00147 
00148   // Empty Buffer
00149   cluster_indices.clear();
00150 }
00151 
00152 
00153 
00154 void EuclideanCluster::run()
00155 {
00156   while(nh_.ok()){
00157     ros::spinOnce();
00158     rate_.sleep();
00159   }
00160 }


target_obejct_detector
Author(s): CIR-KIT
autogenerated on Thu Jun 6 2019 20:19:57