예제 #1
0
template <typename PointT> void
pcl::UnaryClassifier<PointT>::segment (pcl::PointCloud<pcl::PointXYZRGBL>::Ptr &out)
{
  if (trained_features_.size () > 0)
  {
    // convert cloud into cloud with XYZ
    pcl::PointCloud<pcl::PointXYZ>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZ>);
    convertCloud (input_cloud_, tmp_cloud);

    // compute FPFH feature histograms for all point of the input point cloud
    pcl::PointCloud<pcl::FPFHSignature33>::Ptr input_cloud_features (new pcl::PointCloud<pcl::FPFHSignature33>);
    computeFPFH (tmp_cloud, input_cloud_features, normal_radius_search_, fpfh_radius_search_);

    // query the distances from the input data features to all trained features
    std::vector<int> indices;
    std::vector<float> distance;
    queryFeatureDistances (trained_features_, input_cloud_features, indices, distance);

    // assign a label to each point of the input point cloud
    int n_feature_means = static_cast<int> (trained_features_[0]->points.size ());
    convertCloud (input_cloud_, out);
    assignLabels (indices, distance, n_feature_means, feature_threshold_, out);
    //std::cout << "Assign labels - DONE" << std::endl;
  }
  else
    PCL_ERROR ("no training features set \n");
}
예제 #2
0
//グリッド化
void make_elevation(object_map& m)
{
    std::cout << "make_elevation" << std::endl;
    double max_x = -10.0;  double max_y = -10.0;  double max_z = -10.0;
    double min_x = 10.0;  double min_y = 10.0;  double min_z = 10.0;
    int int_max_x = -100; int int_min_x = 100; int int_max_y = -100; int int_min_y = 100;

    pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
    *tmp_cloud = m.cloud_rgb;

    for(int i=0;i<tmp_cloud->size();i++){
        if(tmp_cloud->points[i].x > max_x) max_x = tmp_cloud->points[i].x;
        if(tmp_cloud->points[i].x < min_x) min_x = tmp_cloud->points[i].x;
        tmp_cloud->points[i].x = (int)(tmp_cloud->points[i].x*100);

        if(tmp_cloud->points[i].y > max_y) max_y = tmp_cloud->points[i].y;
        if(tmp_cloud->points[i].y < min_y) min_y = tmp_cloud->points[i].y;
        tmp_cloud->points[i].y = (int)(tmp_cloud->points[i].y*100);

        if(tmp_cloud->points[i].z > max_z) max_z = tmp_cloud->points[i].z;
        if(tmp_cloud->points[i].z < min_z) min_z = tmp_cloud->points[i].z;
        tmp_cloud->points[i].z = (int)(tmp_cloud->points[i].z*100);
    }

    m.max_x = max_x;  m.min_x = min_x;  m.max_y = max_y;  m.min_y = min_y;  m.max_z = max_z; m.min_z = min_z;
    int_min_x = 100*min_x; int_min_y = 100*min_y;
    int_max_x = 100*max_x; int_max_y = 100*max_y;

    downsampling(*tmp_cloud, 1.0f);

    m.size_x = int_max_x - int_min_x + 1;
    m.size_y = int_max_y - int_min_y + 1;

    // std::cout << m.min_x << " " << m.max_x << std::endl;
    // std::cout << m.min_y << " " << m.max_y << std::endl;
    // std::cout << m.size_x << " " << m.size_y << std::endl;

    for(int i=0;i<MAP_X;i++){
        for(int j=0;j<MAP_Y;j++){
            m.map[i][j] = 0.0;
        }
    }
    for(int i=0;i<tmp_cloud->size();i++){
        if(tmp_cloud->points[i].z > m.map[(int)tmp_cloud->points[i].x-int_min_x][(int)tmp_cloud->points[i].y-int_min_y])
            m.map[(int)tmp_cloud->points[i].x-int_min_x][(int)tmp_cloud->points[i].y-int_min_y] = tmp_cloud->points[i].z;
    }

    return;
}
예제 #3
0
template <typename PointT> void
pcl::UnaryClassifier<PointT>::train (pcl::PointCloud<pcl::FPFHSignature33>::Ptr &output)
{  
  // convert cloud into cloud with XYZ
  pcl::PointCloud<pcl::PointXYZ>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZ>);
  convertCloud (input_cloud_, tmp_cloud);

  // compute FPFH feature histograms for all point of the input point cloud
  pcl::PointCloud<pcl::FPFHSignature33>::Ptr feature (new pcl::PointCloud<pcl::FPFHSignature33>);
  computeFPFH (tmp_cloud, feature, normal_radius_search_, fpfh_radius_search_);

  //PCL_INFO ("Number of input cloud features: %d\n", static_cast<int> (feature->points.size ()));

  // use k-means to cluster the features
  kmeansClustering (feature, output, cluster_size_);
}
예제 #4
0
파일: Transformation.cpp 프로젝트: Xala/MAV
void addToPCD(float r, float g, float b, pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud1, pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud2, Matrix4f trans){
	pcl::PointCloud<pcl::PointXYZRGB> cloud_trans;
	pcl::transformPointCloud (*cloud2, cloud_trans, trans);

	pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
	*tmp_cloud = cloud_trans;

	pcl::VoxelGrid<pcl::PointXYZRGB> sor;
	sor.setLeafSize (0.001f, 0.001f, 0.001f);
	sor.setInputCloud (tmp_cloud);


	pcl::PointCloud<pcl::PointXYZRGB> voxelcloud_trans;
	sor.filter(voxelcloud_trans);

	for(unsigned int i = 0; i < voxelcloud_trans.points.size(); i++){
		voxelcloud_trans.points.at(i).r = r;
		voxelcloud_trans.points.at(i).g = g;
		voxelcloud_trans.points.at(i).b = b;
	}
	*cloud1 += voxelcloud_trans;
}
 void ConvexConnectedVoxels::segmentCloud(
     const pcl::PointCloud<PointT>::Ptr cloud,
     const std::vector<pcl::PointIndices> &indices,
     std::vector<pcl::PointCloud<PointT>::Ptr> &cloud_clusters,
     std::vector<pcl::PointCloud<pcl::Normal>::Ptr> &normal_clusters,
     pcl::PointCloud<pcl::PointXYZ>::Ptr centroids)
 {
     boost::mutex::scoped_lock lock(this->mutex_);
     pcl::ExtractIndices<PointT>::Ptr eifilter(
        new pcl::ExtractIndices<PointT>);
     eifilter->setInputCloud(cloud);
     for (int i = 0; i < indices.size(); i++) {
        pcl::PointIndices::Ptr index(new pcl::PointIndices());
        index->indices = indices[i].indices;
        eifilter->setIndices(index);
        pcl::PointCloud<PointT>::Ptr tmp_cloud(
           new pcl::PointCloud<PointT>);
        eifilter->filter(*tmp_cloud);
        if (tmp_cloud->width > 0) {
          Eigen::Vector4f centroid;
          pcl::compute3DCentroid<PointT, float>(*cloud, *index, centroid);
          float ct_x = static_cast<float>(centroid[0]);
          float ct_y = static_cast<float>(centroid[1]);
          float ct_z = static_cast<float>(centroid[2]);
          if (!isnan(ct_x) && !isnan(ct_y) && !isnan(ct_z)) {
             pcl::PointCloud<pcl::Normal>::Ptr s_normal(
                new pcl::PointCloud<pcl::Normal>);
             this->estimatePointCloudNormals(
                tmp_cloud, s_normal, 40, 0.05, false);
             normal_clusters.push_back(s_normal);
             centroids->push_back(pcl::PointXYZ(ct_x, ct_y, ct_z));
             cloud_clusters.push_back(tmp_cloud);
          }
       }
     }
 }
void cloud_cb (const sensor_msgs::PointCloud2ConstPtr& cloud_msg){
 // Updating parameters from the parameter server
 ros::param::getCached("/PCL_object_clustering/cluster_tolerans",cluster_tolerans);
 ros::param::getCached("/PCL_object_clustering/cluster_size/min",cluster_size_min);
 ros::param::getCached("/PCL_object_clustering/cluster_size/max",cluster_size_max);
 ros::param::getCached("/PCL_object_clustering/clusters_highest_point",clusters_highest_point);

 // Converting from PointCloud2 msg to pcl::PointCloud
 pcl::PCLPointCloud2 pcl_pc2;
 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_without_planes (new pcl::PointCloud<pcl::PointXYZ>);
 pcl_conversions::toPCL(*cloud_msg,pcl_pc2);
 pcl::fromPCLPointCloud2(pcl_pc2,*cloud_without_planes);

 if(!(*cloud_without_planes).empty()){
  pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
  tree->setInputCloud (cloud_without_planes);
  // Getting indeces for each found cluster with parameters cluster_tolerans,
  // cluster_size_min and cluster_size_max
  std::vector<pcl::PointIndices> cluster_indices;
  pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
  ec.setClusterTolerance (cluster_tolerans);
  ec.setMinClusterSize (cluster_size_min);
  ec.setMaxClusterSize (cluster_size_max);
  ec.setSearchMethod (tree);
  ec.setInputCloud (cloud_without_planes);
  ec.extract (cluster_indices);

  /* For each cluster we store cluster in tmp_cloud, calculate its centroids.
     If cluster highest point is less than clusters_highest_point we publish
     centroid and append tmp_cloud to cloud_cluster. When we checked through all
     possible centroids we publish cloud_cluster to visualize in rviz.*/
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZ>);
  for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it){
   pcl::PointCloud<pcl::PointXYZ>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZ>);
   for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); ++pit){
    tmp_cloud->points.push_back (cloud_without_planes->points[*pit]);
   }
   pcl::PointXYZ min_point, max_point;
   pcl::getMinMax3D(*tmp_cloud,min_point,max_point);
   if(max_point.z < clusters_highest_point){
    Eigen::Vector4f c;
    pcl::compute3DCentroid(*tmp_cloud, c);
    //std::cout << "Centroid is " << c << std::endl;
    object_detecter_2d::object_loc object_loc_msg;
    object_loc_msg.ID = 10;
    object_loc_msg.point.x = c(0);
    object_loc_msg.point.y = c(1);
    object_loc_msg.point.z = c(2);
    pub_centroid.publish(object_loc_msg);
    (*cloud_cluster) = (*cloud_cluster)+(*tmp_cloud);

   }
  }
  cloud_cluster->width = cloud_cluster->points.size ();
  cloud_cluster->height = 1;
  cloud_cluster->is_dense = true;
  (*cloud_cluster).header.frame_id = (*cloud_without_planes).header.frame_id;
  sensor_msgs::PointCloud2 output;
  pcl::toROSMsg(*cloud_cluster, output);
  pub_debug_pcl.publish(output);
 }
}
예제 #7
0
//***********************************************************
// segmentation
//  セグメンテーションを行う.
//***********************************************************
void segmentation(pcl::PointCloud<pcl::PointXYZRGB>& cloud, double th, int c)
{
    std::cout << "segmentation" << std::endl;

    pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp_rgb (new pcl::PointCloud<pcl::PointXYZRGB>);
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZRGB>);

    for(int i=0;i<cloud.points.size();i++){
        if((m_size.max_z <= cloud.points[i].z) && (cloud.points[i].z <= m_size.max_z+0.3)){
            tmp_cloud->points.push_back(cloud.points[i]);
        }
    }
    pcl::copyPointCloud(*tmp_cloud, cloud);

    // Creating the KdTree object for the search method of the extraction
    pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB>);
    tree->setInputCloud (cloud.makeShared ());

    std::vector<pcl::PointIndices> cluster_indices;
    pcl::EuclideanClusterExtraction<pcl::PointXYZRGB> ec;
    ec.setClusterTolerance (th);
    ec.setMinClusterSize (200);
    ec.setMaxClusterSize (300000);
    ec.setSearchMethod (tree);
    ec.setInputCloud (cloud.makeShared ());
    ec.extract (cluster_indices);

    std::cout << "クラスタリング開始" << std::endl;
    int m = 0;

    for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it){
        pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_cluster_rgb (new pcl::PointCloud<pcl::PointXYZRGB>);
        pcl::PointCloud<pcl::PointXYZHSV>::Ptr cloud_cluster_hsv (new pcl::PointCloud<pcl::PointXYZHSV>);
        pcl::PointXYZ g;

        for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); pit++){
            cloud_cluster_rgb->points.push_back (cloud.points[*pit]);
        }
        cloud_cluster_rgb->width = cloud_cluster_rgb->points.size ();
        cloud_cluster_rgb->height = 1;
        cloud_cluster_rgb->is_dense = true;

        //クラスタ重心を求める  
        g = g_pos(*cloud_cluster_rgb);

        if(((g.x < m_size.min_x) || (m_size.max_x < g.x)) ||
           ((g.y < m_size.min_y) || (m_size.max_y < g.y))){
            continue;
        }

        m++;

        if((m_size.max_z + 0.02 < g.z) && (g.z < m_size.max_z + 0.12)){
            object_map map;
            map.cloud_rgb = *cloud_cluster_rgb;
            map.g = g;
            map.tf = c;
            make_elevation(map);

            // RGB -> HSV
            pcl::PointCloudXYZRGBtoXYZHSV(*cloud_cluster_rgb, *cloud_cluster_hsv);

            for(int i=0;i<MAP_H;i++){
              for(int j=0;j<MAP_S;j++){
                map.histogram[i][j] = 0.000;
              }
            }

            map.cloud_hsv = *cloud_cluster_hsv;
            // H-Sヒストグラムの作成
            for(int i=0;i<cloud_cluster_hsv->points.size();i++){
                if(((int)(255*cloud_cluster_hsv->points[i].h)/((256/MAP_H)*360) >= 32) || ((int)(255*cloud_cluster_hsv->points[i].h)/((256/MAP_H)*360) < 0)) continue;
                if(((int)(255*cloud_cluster_hsv->points[i].s)/(256/MAP_H) >= 32) || ((int)(255*cloud_cluster_hsv->points[i].s)/(256/MAP_H) < 0)) continue;

                // 正規化のため,セグメントの点数で割る.
                map.histogram[(int)(255*cloud_cluster_hsv->points[i].h)/((256/MAP_H)*360)][(int)(255*cloud_cluster_hsv->points[i].s)/(256/MAP_H)] += 1.000/(float)cloud_cluster_hsv->points.size();
            }

            Object_Map.push_back(map);

            *tmp_rgb += *cloud_cluster_rgb;
        }
    }

    pcl::copyPointCloud(*tmp_rgb, cloud);

    return;
}
// Separate into separate clouds and publish polygons
std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr > // use jsk_recognition_msgs::PointsArray
separate(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz_rot, std_msgs::Header header) {
  double x_pitch = 0.25, x_min = 1.0, x_max = 3.0; // 1.5~1.75 1.75~2.00 1.5~1.675
  double y_min = -0.75, y_max = 0.75;
  double z_min = -0.250, z_1 = 0.000, z_2 = 1.000, z_max = 1.750; // -0.3125, 2.0
  pcl::PointXYZ pt_1, pt_2, pt_3, pt_4, pt_5, pt_6; // deprecate with polygon

  // Divide large cloud
  std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr > cloud_vector;
  // pcl::PointCloud<pcl::PointXYZ>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZ>);
  // pcl::PointXYZ tmp_p;

  jsk_recognition_msgs::PolygonArray polygon_array;
  polygon_array.header = header;
  for (int i = 0; i < (int)( (x_max - x_min) / x_pitch ); i++) {
    pcl::PointCloud<pcl::PointXYZ>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZ>);
    geometry_msgs::PolygonStamped polygon;
    visualization_msgs::Marker texts, line_strip; // TEXT_VIEW_FACING

    texts.header = header;
    texts.ns = "text"; // namespace + ID
    texts.action = visualization_msgs::Marker::ADD;
    texts.type = visualization_msgs::Marker::TEXT_VIEW_FACING;

    texts.pose.orientation.x = 0.0;
    texts.pose.orientation.y = 0.0;
    texts.pose.orientation.z = 0.0;
    texts.pose.orientation.w = 1.0;
    texts.scale.x = 0.125;
    texts.scale.y = 0.125;
    texts.scale.z = 0.125;
    texts.color.r = 1.0f;
    texts.color.g = 0.0f;
    texts.color.b = 0.0f;
    texts.color.a = 1.0;

    geometry_msgs::Point32 tmp_p_up_0, tmp_p_up_1, tmp_p_up_2, tmp_p_down_0, tmp_p_down_1, tmp_p_down_2;
    pcl::PointXYZ tmp_p;
    double width_tmp, width_min_up = 2.000, width_min_down = 4.000;
    double width_min_bottom = 0.500, width_min_top = 0.200;
    for (pcl::PointCloud<pcl::PointXYZ>::const_iterator itr = cloud_xyz_rot->begin();
         itr != cloud_xyz_rot->end(); itr++) {
      if ( (x_min + i*x_pitch) < itr->x && itr->x < (x_min + (i+1)*x_pitch) ) {
        if (y_min < itr->y && itr->y < y_max) {
          if (z_min < itr->z && itr->z < z_max) {
            // compare tmp_p and itr, and calculate width and points
            if (itr != cloud_xyz_rot->begin()) { // skip at 1st time
              if ( (tmp_p.y < 0 && 0 <= itr->y) || (itr->y < 0 && 0 <= tmp_p.y) ) {
                if (itr->z < z_1) {
                  width_tmp = sqrt(pow(fabs(tmp_p.x - itr->x), 2)
                                   + pow(fabs(tmp_p.y - itr->y), 2)
                                   + pow(fabs(tmp_p.z - itr->z), 2));
                  if (width_min_bottom < width_tmp && width_tmp <= width_min_down) {
                    width_min_down = width_tmp; // create width_min array
                    tmp_p_down_0.x = tmp_p.x; tmp_p_down_0.y = tmp_p.y;
                    tmp_p_down_0.z = (tmp_p.z + itr->z) / 2;
                    tmp_p_down_1.x = itr->x; tmp_p_down_1.y = itr->y;
                    tmp_p_down_1.z = (tmp_p.z + itr->z) / 2;
                    tmp_p_down_2.x = tmp_p.x; // ignore adding sqrt
                    tmp_p_down_2.y = tmp_p.y + sqrt(pow(fabs(tmp_p.y - itr->y), 2)) / 2;
                    tmp_p_down_2.z = (tmp_p.z + itr->z) / 2;
                  }
                }
                if (z_2 < itr->z) {
                  width_tmp = sqrt(pow(fabs(tmp_p.x - itr->x), 2)
                                   + pow(fabs(tmp_p.y - itr->y), 2)
                                   + pow(fabs(tmp_p.z - itr->z), 2));
                  if (width_tmp <= width_min_down) {
                    width_min_up = width_tmp;
                    tmp_p_up_0.x = tmp_p.x; tmp_p_up_0.y = tmp_p.y;
                    tmp_p_up_0.z = (tmp_p.z + itr->z) / 2;
                    tmp_p_up_1.x = itr->x; tmp_p_up_1.y = itr->y;
                    tmp_p_up_1.z = (tmp_p.z + itr->z) / 2;
                    tmp_p_up_2.x = tmp_p.x; // ignore adding sqrt
                    tmp_p_up_2.y = tmp_p.y + sqrt(pow(fabs(tmp_p.y - itr->y), 2)) / 2;
                    tmp_p_up_2.z = (tmp_p.z + itr->z) / 2;
                  }
                }
              }
              tmp_p.x = itr->x; tmp_p.y = itr->y; tmp_p.z = itr->z;
              tmp_cloud->points.push_back(tmp_p);
            }
          }
        }
      }
      // From tmp_cloud, get 4 points to publish marker
      // Create polygon
    }

    cloud_vector.push_back(tmp_cloud);

    tmp_p_up_0.x = x_min + i*x_pitch - x_pitch/2;
    tmp_p_up_1.x = x_min + i*x_pitch - x_pitch/2;
    tmp_p_down_0.x = x_min + i*x_pitch - x_pitch/2;
    tmp_p_down_1.x = x_min + i*x_pitch - x_pitch/2;
    if (tmp_p_up_0.y < tmp_p_up_1.y) {
      polygon.polygon.points.push_back(tmp_p_up_0);
      polygon.polygon.points.push_back(tmp_p_up_1);
    }
    if (tmp_p_up_0.y >= tmp_p_up_1.y) {
      polygon.polygon.points.push_back(tmp_p_up_1);
      polygon.polygon.points.push_back(tmp_p_up_0);
    }
    if (tmp_p_down_0.y < tmp_p_down_1.y) {
      polygon.polygon.points.push_back(tmp_p_down_1);
      polygon.polygon.points.push_back(tmp_p_down_0);
    }
    if (tmp_p_down_0.y >= tmp_p_down_1.y) {
      polygon.polygon.points.push_back(tmp_p_down_0);
      polygon.polygon.points.push_back(tmp_p_down_1);
    }
    polygon.header = header;
    polygon_array.polygons.push_back(polygon);

    std::cerr << "count:" << i << ", " << "size:" << cloud_vector.at(i)->size() << std::endl;
    std::cerr << "width_min_up:" << width_min_up << std::endl;
    std::cerr << "width_min_down:" << width_min_down << std::endl;

    texts.id = 2*i;
    texts.pose.position.x = tmp_p_up_0.x;
    texts.pose.position.y = tmp_p_up_2.y;
    texts.pose.position.z = tmp_p_up_2.z;

    std::ostringstream strs;
    strs << width_min_up;
    std::string str = strs.str();
    texts.text = str;
    pub_marker.publish(texts);

    texts.id = 2*i + 1;
    texts.pose.position.x = tmp_p_down_0.x;
    texts.pose.position.y = tmp_p_down_2.y;
    texts.pose.position.z = tmp_p_down_2.z;

    strs.str("");
    strs.clear(std::stringstream::goodbit);
    strs << width_min_down;
    str = strs.str();
    texts.text = str;
    pub_marker.publish(texts);

  }
  pub_polygon_array.publish(polygon_array); // error
  return cloud_vector;
}