Example #1
0
	/*! @brief the main processing callback of the ECTO pipeline
	 *
	 * this method is called once all input dependencies are satisfied.
	 * The PartsBasedDetector has two input dependencies: a color image and depth image,
	 * both retrieved from the Kinect. If any detection candidates are found,
	 * the bounding boxes, detection confidences and object ids are returned
	 *
	 * @param inputs the input tendrils
	 * @param outputs the output tendrils
	 * @return
	 */
	int process(const tendrils& inputs, const tendrils& outputs)
	{
		std::cout << "detector: process" << std::endl;

		pose_results_->clear();

		image_pipeline::PinholeCameraModel camera_model;
		camera_model.setParams(color_->size(), *camera_intrinsics_, cv::Mat(),
				cv::Mat(), cv::Mat());

		std::vector<Candidate> candidates;
		detector_->detect(*color_, *depth_, candidates);

		if (candidates.size() == 0)
		{
			if (*visualize_)
			{
				cv::cvtColor(*color_, *output_, CV_RGB2BGR);
				//cv::waitKey(30);
			}

			return ecto::OK;
		}

		Candidate::sort(candidates);
		Candidate::nonMaximaSuppression(*color_, candidates, *max_overlap_);

		if (*visualize_)
		{
			visualizer_->candidates(*color_, candidates, candidates.size(), *output_, true);
			cv::cvtColor(*output_, *output_, CV_RGB2BGR);
			//cv::waitKey(30);
		}

		std::vector<Rect3d> bounding_boxes;
		std::vector<PointCloud> parts_centers;

		typename PointCloudClusterer<PointType>::PointProjectFunc projecter =
				boost::bind(&PartsBasedDetectorCell::projectPixelToRay, this,
						camera_model, _1);
		PointCloudClusterer<PointType>::computeBoundingBoxes(candidates,
				*color_, *depth_, projecter, *input_cloud_, bounding_boxes,
				parts_centers);


		// output clusters
		std::vector<PointType> object_centers;
		std::vector<PointCloud> clusters;

		// remove planes from input cloud if needed
		if(*remove_planes_)
		{
			PointCloud::Ptr clusterer_cloud (new PointCloud());
			PointCloudClusterer<PointType>::organizedMultiplaneSegmentation(*input_cloud_, *clusterer_cloud);
			PointCloudClusterer<PointType>::clusterObjects(clusterer_cloud,
					bounding_boxes, clusters, object_centers);
		}
		else
		{
			PointCloudClusterer<PointType>::clusterObjects(*input_cloud_,
					bounding_boxes, clusters, object_centers);
		}




		// compute poses (centroid of part centers)

		// for each object
		for (int object_it = 0; object_it < candidates.size(); ++object_it)
		{
			if(std::isnan(object_centers[object_it].x) || std::isnan(object_centers[object_it].y) || std::isnan(object_centers[object_it].z))
				continue;

			PoseResult result;

			// no db for now, only one model
			result.set_object_id(*object_db_, model_name_);
			result.set_confidence(candidates[object_it].score());

			// set the clustered cloud's center as a center...
			result.set_T(Eigen::Vector3f(object_centers[object_it].getVector3fMap()));

//			// For the rotation a minimum of two parts is needed
//			if (part_centers_cloud.size() >= 2 &&
//					!pcl_isnan(part_centers_cloud[0].x) &&
//					!pcl_isnan(part_centers_cloud[0].y) &&
//					!pcl_isnan(part_centers_cloud[0].z) &&
//					!pcl_isnan(part_centers_cloud[1].x) &&
//					!pcl_isnan(part_centers_cloud[1].y) &&
//					!pcl_isnan(part_centers_cloud[1].z))
//			{
//				Eigen::Vector3f center(centroid.block<3, 1>(0, 0));
//
//				Eigen::Vector3f x_axis(
//						part_centers_cloud[0].getVector3fMap() - center);
//				x_axis.normalize();
//				Eigen::Vector3f z_axis =
//						(x_axis.cross(
//								part_centers_cloud[1].getVector3fMap() - center)).normalized();
//
//				Eigen::Vector3f y_axis = x_axis.cross(z_axis); // should be normalized
//
//				Eigen::Matrix3f rot_matr;
//				rot_matr << z_axis, y_axis, -x_axis;
//				//rot_matr.transposeInPlace();
//
//				result.set_R(rot_matr);
//			}
//			else
			{
				result.set_R(Eigen::Quaternionf(1, 0, 0, 0));
			}

			// Only one point of view for this object...
			sensor_msgs::PointCloud2Ptr cluster_cloud (new sensor_msgs::PointCloud2());
	        std::vector<sensor_msgs::PointCloud2ConstPtr> ros_clouds (1);
	        pcl::toROSMsg(clusters[object_it], *(cluster_cloud));
	        ros_clouds[0] = cluster_cloud;
	        result.set_clouds(ros_clouds);

			std::vector<PointCloud, Eigen::aligned_allocator<PointCloud> > object_cluster (1);
			object_cluster[0] = clusters[object_it];

			pose_results_->push_back(result);
		}

		return ecto::OK;
	}
Example #2
0
    /** Compute the pose of the table plane
     * @param inputs
     * @param outputs
     * @return
     */
    int
    process(const tendrils& inputs, const tendrils& outputs)
    {
      std::vector<tabletop_object_detector::TabletopObjectRecognizer<pcl::PointXYZ>::TabletopResult > results;

      // Process each table
      pose_results_->clear();

      std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clusters_merged;
      // Map to store the transformation for each cluster (table_index)
      std::map<pcl::PointCloud<pcl::PointXYZ>::Ptr, size_t> cluster_table;

      std::vector<cv::Vec3f> translations(clusters_->size());
      std::vector<cv::Matx33f> rotations(clusters_->size());
      for (size_t table_index = 0; table_index < clusters_->size(); ++table_index)
      {
        getPlaneTransform((*table_coefficients_)[table_index], rotations[table_index], translations[table_index]);

        // Make the clusters be in the table frame
        size_t n_clusters = (*clusters_)[table_index].size();
        std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clusters(n_clusters);

        cv::Matx33f Rinv = rotations[table_index].t();
        cv::Vec3f Tinv = -Rinv*translations[table_index];

        for (size_t cluster_index = 0; cluster_index < n_clusters; ++cluster_index)
        {
          clusters[cluster_index] = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>());
          for(size_t i = 0; i < (*clusters_)[table_index][cluster_index].size(); ++i)
          {
            cv::Vec3f res = Rinv*(*clusters_)[table_index][cluster_index][i] + Tinv;
            clusters[cluster_index]->push_back(pcl::PointXYZ(res[0], res[1], res[2]));
          }
          cluster_table.insert(std::pair<pcl::PointCloud<pcl::PointXYZ>::Ptr, size_t>(clusters[cluster_index], table_index));
        }

        clusters_merged.insert(clusters_merged.end(), clusters.begin(), clusters.end());
      }

      object_recognizer_.objectDetection(clusters_merged, confidence_cutoff_, perform_fit_merge_, results);

      for (size_t i = 0; i < results.size(); ++i)
      {
        const tabletop_object_detector::TabletopObjectRecognizer<pcl::PointXYZ>::TabletopResult & result = results[i];
        const size_t table_index = cluster_table[result.cloud_];

        PoseResult pose_result;

        // Add the object id
        std::stringstream ss;
        ss << result.object_id_;
        pose_result.set_object_id(db_, ss.str());

        // Add the pose
        const geometry_msgs::Pose &pose = result.pose_;
        cv::Vec3f T(pose.position.x, pose.position.y, pose.position.z);
        Eigen::Quaternionf quat(pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z);

        cv::Vec3f new_T = rotations[table_index] * T + translations[table_index];
        pose_result.set_T(cv::Mat(new_T));

        pose_result.set_R(quat);
        cv::Mat R = cv::Mat(rotations[table_index] * pose_result.R<cv::Matx33f>());
        pose_result.set_R(R);
        pose_result.set_confidence(result.confidence_);

        // Add the cluster of points
        std::vector<sensor_msgs::PointCloud2ConstPtr> ros_clouds (1);
        sensor_msgs::PointCloud2Ptr cluster_cloud (new sensor_msgs::PointCloud2());

#if PCL_VERSION_COMPARE(>=,1,7,0)
        ::pcl::PCLPointCloud2 pcd_tmp;
        ::pcl::toPCLPointCloud2(*result.cloud_, pcd_tmp);
        pcl_conversions::fromPCL(pcd_tmp, *cluster_cloud);
#else
        pcl::toROSMsg(*result.cloud_, *cluster_cloud);
#endif
        ros_clouds[0] = cluster_cloud;
        pose_result.set_clouds(ros_clouds);

        pose_results_->push_back(pose_result);
      }
      return ecto::OK;
    }
Example #3
0
void Cup_Segmentation::cloudCallback (const sensor_msgs::PointCloud2::ConstPtr& cloud_in)
{
  ROS_INFO("Processing!");
  /************************ CENTER AND LEFT BOXES ***************************************/
  //Creating point cloud and convert ROS Message
  pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
  pcl::PointCloud<pcl::PointXYZ>::Ptr seg_cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::fromROSMsg(*cloud_in, *pcl_cloud);
  //Create and define filter parameters

  pcl::PassThrough<pcl::PointXYZ> pass3;
  pass3.setFilterFieldName("x");
  pass3.setFilterLimits(0, 1.2); //-0.5 0.5
  pass3.setInputCloud(pcl_cloud);
  pass3.filter(*pcl_cloud);

  pcl::PassThrough<pcl::PointXYZ> pass;
  pass.setFilterFieldName("y");
  pass.setFilterLimits(-0.7, 0.1); //-0.5 0.5
  pass.setInputCloud(pcl_cloud);
  pass.filter(*pcl_cloud);

  pcl::PassThrough<pcl::PointXYZ> pass2;
  pass2.setFilterFieldName("z");
  pass2.setFilterLimits(0.0, 1.0); //-0.5 0.5
  pass2.setInputCloud(pcl_cloud);
  pass2.filter(*pcl_cloud);

  //Model fitting process ->RANSAC
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
  pcl::SACSegmentation<pcl::PointXYZ> seg;
  seg.setOptimizeCoefficients (true);
  seg.setModelType (pcl::SACMODEL_PARALLEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setDistanceThreshold (0.03); //0.03
  seg.setAxis (Eigen::Vector3f(1, 0, 0));
  seg.setEpsAngle (0.1); //0.02
  seg.setInputCloud (pcl_cloud);
  seg.segment (*inliers, *coefficients);
  //Verify if inliers is not empty
  if (inliers->indices.size () == 0)
    return;
  pcl::PointCloud<pcl::PointXYZ>::Ptr treated_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
  for (std::vector<int>::const_iterator it = inliers->indices.begin(); it != inliers->indices.end (); ++it)
    treated_cloud->push_back(pcl_cloud->points[*it]);

  pcl::ExtractIndices<pcl::PointXYZ> extract;
	extract.setInputCloud(pcl_cloud);
	extract.setIndices(inliers);
	extract.setNegative(true);
	extract.filter(*seg_cloud);

  //Create and define radial filter parameters
  //pcl::RadiusOutlierRemoval<pcl::PointXYZ> radialFilter;
  //radialFilter.setInputCloud(treated_cloud);
  //radialFilter.setRadiusSearch(0.03);
  //radialFilter.setMinNeighborsInRadius (20);
  //radialFilter.filter (*treated_cloud);

  //Apply clustering algorithm
  pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree (new pcl::search::KdTree<pcl::PointXYZ>);
  kdtree->setInputCloud (seg_cloud);
  std::vector<pcl::PointIndices> cluster_indices;
  pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
  ec.setClusterTolerance (0.06);
  ec.setMinClusterSize (6);
  ec.setMaxClusterSize (150);
  ec.setSearchMethod (kdtree);
  ec.setInputCloud (seg_cloud);
  ec.extract (cluster_indices);
  pcl::PointCloud<pcl::PointXYZI>::Ptr cluster_cloud (new pcl::PointCloud<pcl::PointXYZI> ());
  pcl::PointXYZI cluster_point;
  double cluster_final_average;
  int cluster_id=0;
  float x1 = 0.0, y1 = 0.0, z1 = 0.0;
  float x2 = 0.0, y2 = 0.0, z2 = 0.0;
  float x3 = 0.0, y3 = 0.0, z3 = 0.0;
  int total1 = 0, total2 = 0, total3 = 0;
  bool hasCup1, hasCup2, hasCup3;

  for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end ();
  ++it, cluster_id+=1)
  {
    for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); pit++)
    {
      cluster_point.x = seg_cloud->points[*pit].x;
      cluster_point.y = seg_cloud->points[*pit].y;
      cluster_point.z = seg_cloud->points[*pit].z;
      cluster_point.intensity = cluster_id;
      cluster_cloud->push_back(cluster_point);

      if(cluster_id == 0){
        x1 += seg_cloud->points[*pit].x;
        y1 += seg_cloud->points[*pit].y;
        z1 += seg_cloud->points[*pit].z;
        total1++;
      } else if (cluster_id == 1){
        x2 += seg_cloud->points[*pit].x;
        y2 += seg_cloud->points[*pit].y;
        z2 += seg_cloud->points[*pit].z;
        total2++;
      } else if (cluster_id == 2){
        x3 += seg_cloud->points[*pit].x;
        y3 += seg_cloud->points[*pit].y;
        z3 += seg_cloud->points[*pit].z;
        total3++;
      }
    }
  }
  if(total1 != 0 ){
    x1 = x1/total1;
    y1 = y1/total1;
    z1 = z1/total1;
    hasCup1=true;
  }else{
    hasCup1 = false;
  }
  if(total2 != 0 ){
    x2 = x2/total2;
    y2 = y2/total2;
    z2 = z2/total2;

    hasCup2 = true;
  } else {
    hasCup2 = false;
  }

  if(total3 != 0){
    x3 = x3/total2;
    y3 = y3/total2;
    z3 = z3/total2;
    hasCup3 = true;
  } else{
    hasCup3 = false;
  }


  //Publish message
  sensor_msgs::PointCloud2 cloud;
  pcl::toROSMsg(*cluster_cloud, cloud);
  cloud.header.stamp = ros::Time::now();
  cloud.header.frame_id = cloud_in->header.frame_id;
  treated_cloud_pub_.publish(cloud);


  //Geometry
  geometry_msgs::PointStamped cupPoint1;
  geometry_msgs::PointStamped cupPoint2;
  geometry_msgs::PointStamped cupPoint3;

  tf::Quaternion q;

  geometry_msgs::PointStamped cupSensorPoint1;
  geometry_msgs::PointStamped cupSensorPoint2;
  geometry_msgs::PointStamped cupSensorPoint3;

  static tf::TransformBroadcaster tfBc1;
  static tf::TransformBroadcaster tfBc2;
  static tf::TransformBroadcaster tfBc3;

  tf::Transform tfCup1;
  tf::Transform tfCup2;
  tf::Transform tfCup3;

  cupPoint1.header.frame_id = "base_footprint";
  cupPoint2.header.frame_id = "base_footprint";
  cupPoint3.header.frame_id = "base_footprint";

  cupPoint1.header.stamp = cloud_in->header.stamp;
  cupPoint2.header.stamp = cloud_in->header.stamp;
  cupPoint3.header.stamp = cloud_in->header.stamp;

  cupPoint1.point.x = x1;
  cupPoint2.point.x = x2;
  cupPoint3.point.x = x3;

  cupPoint1.point.y = y1;
  cupPoint2.point.y = y2;
  cupPoint3.point.y = y3;

  cupPoint1.point.z = z1;
  cupPoint2.point.z = z2;
  cupPoint3.point.z = z3;

  ROS_INFO("Cup 1: X=%f Y=%f Z=%f", cupPoint1.point.x, cupPoint1.point.y, cupPoint1.point.z);
  ROS_INFO("Cup 2: X=%f Y=%f Z=%f", cupPoint2.point.x, cupPoint2.point.y, cupPoint2.point.z);
  ROS_INFO("Cup 3: X=%f Y=%f Z=%f", cupPoint3.point.x, cupPoint3.point.y, cupPoint3.point.z);


  tf_listener.transformPoint("sensors_frame", cupPoint1, cupSensorPoint1);
  tf_listener.transformPoint("sensors_frame", cupPoint2, cupSensorPoint2);
  tf_listener.transformPoint("sensors_frame", cupPoint3, cupSensorPoint3);


  tfCup1.setOrigin( tf::Vector3(cupSensorPoint1.point.x, cupSensorPoint1.point.y, cupSensorPoint1.point.z) );
  tfCup2.setOrigin( tf::Vector3(cupSensorPoint2.point.x, cupSensorPoint2.point.y, cupSensorPoint2.point.z) );
  tfCup3.setOrigin( tf::Vector3(cupSensorPoint3.point.x, cupSensorPoint3.point.y, cupSensorPoint3.point.z) );

  ROS_INFO("Sensor Frame Cup 1: X=%f Y=%f Z=%f", cupSensorPoint1.point.x, cupSensorPoint1.point.y, cupSensorPoint1.point.z);
  ROS_INFO("Sensor Frame Cup 2: X=%f Y=%f Z=%f", cupSensorPoint2.point.x, cupSensorPoint2.point.y, cupSensorPoint2.point.z);
  ROS_INFO("Sensor Frame Cup 3: X=%f Y=%f Z=%f", cupSensorPoint3.point.x, cupSensorPoint3.point.y, cupSensorPoint3.point.z);

  q.setRPY(0, 0, 0);

  tfCup1.setRotation(q);
  tfCup2.setRotation(q);
  tfCup3.setRotation(q);

  tfBc1.sendTransform(tf::StampedTransform(tfCup1, cloud_in->header.stamp, "sensors_frame", "cup1"));
  tfBc2.sendTransform(tf::StampedTransform(tfCup2, cloud_in->header.stamp, "sensors_frame", "cup2"));
  tfBc3.sendTransform(tf::StampedTransform(tfCup3, cloud_in->header.stamp, "sensors_frame", "cup3"));
  ROS_INFO("All Sent!");

}
  void
  PrimitiveShapeClassifier::process(const sensor_msgs::PointCloud2::ConstPtr& ros_cloud,
                                    const sensor_msgs::PointCloud2::ConstPtr& ros_normal,
                                    const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& ros_indices,
                                    const jsk_recognition_msgs::PolygonArray::ConstPtr& ros_polygons)
  {
    boost::mutex::scoped_lock lock(mutex_);

    if (!checkFrameId(ros_cloud, ros_normal, ros_indices, ros_polygons)) return;

    pcl::PointCloud<PointT>::Ptr input(new pcl::PointCloud<PointT>);
    pcl::fromROSMsg(*ros_cloud, *input);

    pcl::PointCloud<pcl::Normal>::Ptr normal(new pcl::PointCloud<pcl::Normal>);
    pcl::fromROSMsg(*ros_normal, *normal);

    pcl::ExtractIndices<PointT> ext_input;
    ext_input.setInputCloud(input);
    pcl::ExtractIndices<pcl::Normal> ext_normal;
    ext_normal.setInputCloud(normal);

    std::vector<jsk_recognition_utils::Polygon::Ptr> polygons
      = jsk_recognition_utils::Polygon::fromROSMsg(*ros_polygons);

    jsk_recognition_msgs::ClassificationResult result;
    result.header = ros_cloud->header;
    result.classifier = "primitive_shape_classifier";
    result.target_names.push_back("box");
    result.target_names.push_back("circle");
    result.target_names.push_back("other");

    pcl::PointCloud<PointT>::Ptr projected_cloud(new pcl::PointCloud<PointT>);
    std::vector<pcl::PointIndices::Ptr> boundary_indices;

    NODELET_DEBUG_STREAM("Cluster num: " << ros_indices->cluster_indices.size());
    for (size_t i = 0; i < ros_indices->cluster_indices.size(); ++i)
    {
      pcl::PointIndices::Ptr indices(new pcl::PointIndices);
      indices->indices = ros_indices->cluster_indices[i].indices;
      NODELET_DEBUG_STREAM("Estimating cluster #" << i << " (" << indices->indices.size() << " points)");

      pcl::PointCloud<PointT>::Ptr cluster_cloud(new pcl::PointCloud<PointT>);
      ext_input.setIndices(indices);
      ext_input.filter(*cluster_cloud);

      pcl::PointCloud<pcl::Normal>::Ptr cluster_normal(new pcl::PointCloud<pcl::Normal>);
      ext_normal.setIndices(indices);
      ext_normal.filter(*cluster_normal);

      pcl::ModelCoefficients::Ptr support_plane(new pcl::ModelCoefficients);
      if (!getSupportPlane(cluster_cloud, polygons, support_plane))
      {
        NODELET_ERROR_STREAM("cloud " << i << " has no support plane. skipped");
        continue;
      }

      pcl::PointIndices::Ptr b(new pcl::PointIndices);
      pcl::PointCloud<PointT>::Ptr pc(new pcl::PointCloud<PointT>);
      float circle_likelihood, box_likelihood;
      estimate(cluster_cloud, cluster_normal, support_plane,
               b, pc,
               circle_likelihood, box_likelihood);
      boundary_indices.push_back(std::move(b));
      *projected_cloud += *pc;

      if (circle_likelihood > circle_threshold_) {
        // circle
        result.labels.push_back(1);
        result.label_names.push_back("circle");
        result.label_proba.push_back(circle_likelihood);
      } else if (box_likelihood > box_threshold_) {
        // box
        result.labels.push_back(0);
        result.label_names.push_back("box");
        result.label_proba.push_back(box_likelihood);
      } else {
        // other
        result.labels.push_back(3);
        result.label_names.push_back("other");
        result.label_proba.push_back(0.0);
      }
    }

    // publish results
    sensor_msgs::PointCloud2 ros_projected_cloud;
    pcl::toROSMsg(*projected_cloud, ros_projected_cloud);
    ros_projected_cloud.header = ros_cloud->header;
    pub_projected_cloud_.publish(ros_projected_cloud);

    jsk_recognition_msgs::ClusterPointIndices ros_boundary_indices;
    ros_boundary_indices.header = ros_cloud->header;
    for (size_t i = 0; i < boundary_indices.size(); ++i)
    {
      pcl_msgs::PointIndices ri;
      pcl_conversions::moveFromPCL(*boundary_indices[i], ri);
      ros_boundary_indices.cluster_indices.push_back(ri);
    }
    pub_boundary_indices_.publish(ros_boundary_indices);

    pub_class_.publish(result);
  }