37 #include <pcl/kdtree/kdtree_flann.h> 38 #include <pcl/common/centroid.h> 40 #include <jsk_recognition_msgs/BoundingBoxArray.h> 41 #include <geometry_msgs/PoseArray.h> 42 #include <pcl/filters/extract_indices.h> 43 #include <visualization_msgs/Marker.h> 45 #include <pcl/sample_consensus/method_types.h> 46 #include <pcl/sample_consensus/model_types.h> 47 #include <pcl/segmentation/sac_segmentation.h> 48 #include <pcl/common/angles.h> 49 #include <jsk_recognition_msgs/PolygonArray.h> 50 #include <jsk_recognition_msgs/ClusterPointIndices.h> 51 #include <pcl/filters/project_inliers.h> 52 #include <pcl/surface/convex_hull.h> 59 const double outlier_threshold):
60 value_(0.0), indices_pair_(pair), coefficients_pair_(coefficients_pair),
61 outlier_threshold_(outlier_threshold_)
71 const pcl::PointCloud<pcl::PointXYZRGB>::Ptr& cloud,
72 const pcl::PointIndices::Ptr& indices,
73 Eigen::Vector3f& output)
75 Eigen::Vector4f centroid;
77 pcl::PointCloud<pcl::PointXYZRGB>::Ptr target_cloud (
new pcl::PointCloud<pcl::PointXYZRGB>);
78 pcl::ExtractIndices<pcl::PointXYZRGB>
ex;
79 ex.setInputCloud(cloud);
80 ex.setIndices(indices);
81 ex.filter(*target_cloud);
82 pcl::compute3DCentroid(*target_cloud, centroid);
83 jsk_recognition_utils::pointFromVectorToVector<Eigen::Vector4f, Eigen::Vector3f>(centroid, output);
88 const pcl::PointCloud<pcl::PointXYZRGB>& cloud,
89 const pcl::PointIndices::Ptr indices,
92 pcl::PointCloud<pcl::PointXYZRGB>::Ptr
points 93 (
new pcl::PointCloud<pcl::PointXYZRGB>);
94 pcl::ExtractIndices<pcl::PointXYZRGB> extract;
95 extract.setInputCloud(cloud.makeShared());
96 extract.setIndices(indices);
97 extract.filter(*points);
98 for (
size_t i = 0; i < points->points.size(); i++) {
99 pcl::PointXYZRGB
p = points->points[i];
100 Eigen::Vector3f p_eigen = p.getVector3fMap();
101 Eigen::Vector3f foot_point;
102 line.
foot(p_eigen, foot_point);
103 output.push_back(foot_point);
111 vertices.push_back(a_edge_pair.get<0>());
112 vertices.push_back(a_edge_pair.get<1>());
113 vertices.push_back(b_edge_pair.get<1>());
114 vertices.push_back(b_edge_pair.get<0>());
120 const pcl::PointCloud<pcl::PointXYZRGB>& cloud,
124 std::vector<int> a_indices, b_indices;
125 for (
size_t i = 0; i < cloud.points.size(); i++) {
126 pcl::PointXYZRGB pcl_point = cloud.points[i];
127 if (pcl_isfinite(pcl_point.x) &&
128 pcl_isfinite(pcl_point.y) &&
129 pcl_isfinite(pcl_point.z)) {
130 Eigen::Vector3f eigen_point = pcl_point.getVector3fMap();
132 a_indices.push_back(i);
135 b_indices.push_back(i);
140 return a_indices.size() + b_indices.size();
149 original_points.push_back(a_candidates.get<0>());
150 original_points.push_back(a_candidates.get<1>());
151 original_points.push_back(b_candidates.get<0>());
152 original_points.push_back(b_candidates.get<1>());
153 for (
size_t i = 0; i < original_points.size(); i++) {
154 Eigen::Vector3f
p = original_points[i];
155 ROS_INFO(
"[foot_point] [%f, %f, %f]", p[0], p[1], p[2]);
159 for (
size_t i = 0; i < original_points.size(); i++) {
160 Eigen::Vector3f foot_point;
161 axis.
foot(original_points[i], foot_point);
162 foot_points.push_back(foot_point);
164 double max_alpha = -DBL_MAX;
165 double min_alpha = DBL_MAX;
166 Eigen::Vector3f max_alpha_point, min_alpha_point;
168 for (
size_t i = 0; i < foot_points.size(); i++) {
170 if (alpha > max_alpha) {
172 max_alpha_point = foot_points[i];
174 if (alpha < min_alpha) {
176 min_alpha_point = foot_points[i];
179 ROS_INFO(
"min_alpha_point: [%f, %f, %f]", min_alpha_point[0], min_alpha_point[1], min_alpha_point[2]);
180 ROS_INFO(
"max_alpha_point: [%f, %f, %f]", max_alpha_point[0], max_alpha_point[1], max_alpha_point[2]);
181 return boost::make_tuple(min_alpha_point, max_alpha_point);
194 const double outlier_threshold):
195 CubeHypothesis(pair, coefficients_pair, outlier_threshold), resolution_(10)
201 const pcl::PointCloud<pcl::PointXYZRGB>& cloud)
208 if (!line_a->isSameDirection(*line_b)) {
209 line_b = line_b->flip();
212 const double r2 = line_a->distance(*line_b);
213 const double r = r2 / 2;
215 Eigen::Vector3f center;
216 axis->getOrigin(center);
229 Eigen::Vector3f centroid_a, centroid_b;
230 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr = cloud.makeShared();
233 ROS_INFO(
"centroid_a: [%f, %f, %f]", centroid_a[0], centroid_a[1], centroid_a[2]);
234 ROS_INFO(
"centroid_b: [%f, %f, %f]", centroid_b[0], centroid_b[1], centroid_b[2]);
238 line_a_aligned->print();
240 line_b_aligned->print();
249 double max_v = - DBL_MAX;
256 Eigen::Vector3f point_on_x;
257 line_a->foot(center, point_on_x);
262 Eigen::Vector3f
ex = (point_on_x - center).
normalized();
264 axis->getDirection(ez);
265 Eigen::Vector3f ey = ez.cross(ex).normalized();
267 if (center.dot(ey) > 0) {
269 ey = ez.cross(ex).normalized();
271 Eigen::Vector3f point_on_y = center + r * ey;
286 Eigen::Vector3f line_c_a_min_point, line_c_a_max_point;
287 Eigen::Vector3f line_c_b_min_point, line_c_b_max_point;
288 line_c->foot(line_a_end_points.get<0>(), line_c_a_min_point);
289 line_c->foot(line_a_end_points.get<1>(), line_c_a_max_point);
290 line_c->foot(line_b_end_points.get<0>(), line_c_b_min_point);
291 line_c->foot(line_b_end_points.get<1>(), line_c_b_max_point);
297 line_c_a_end_points);
299 line_c_b_end_points);
305 max_line_c_a_points = line_c_a_end_points;
306 max_line_c_b_points = line_c_b_end_points;
314 max_line_c_b_points);
315 ROS_INFO(
"end_point: [%f, %f, %f]", axis_end_points.get<0>()[0], axis_end_points.get<0>()[1], axis_end_points.get<0>()[2]);
316 ROS_INFO(
"end_point: [%f, %f, %f]", axis_end_points.get<1>()[0], axis_end_points.get<1>()[1], axis_end_points.get<1>()[2]);
317 Eigen::Vector3f midpoint
318 = (axis_end_points.get<0>() + axis_end_points.get<1>()) / 2.0;
319 double z_dimension = (axis_end_points.get<0>() - midpoint).norm() * 2;
321 ROS_INFO(
"midpoint: [%f, %f, %f]", midpoint[0], midpoint[1], midpoint[2]);
323 std::vector<double> dimensions =
cube_->getDimensions();
324 dimensions[2] = z_dimension;
325 cube_->setDimensions(dimensions);
329 const pcl::PointCloud<PointT>::Ptr cloud,
333 for (
size_t i = 0; i < cloud->points.size(); i++) {
335 if (!std::isnan(p.x) && !std::isnan(p.y) && !std::isnan(p.z)) {
336 Eigen::Vector3f ep = p.getVector3fMap();
346 const pcl::PointCloud<PointT>::Ptr cloud,
347 const std::vector<jsk_recognition_utils::ConvexPolygon::Ptr>& convexes,
348 std::vector<int>& output_indices)
351 for (
size_t i = 0; i < convexes.size(); i++) {
360 output_indices.push_back(i);
370 min_inliers_ = config.min_inliers;
371 convex_area_threshold_ = config.convex_area_threshold;
372 convex_edge_threshold_ = config.convex_edge_threshold;
373 parallel_edge_distance_min_threshold_ = config.parallel_edge_distance_min_threshold;
374 parallel_edge_distance_max_threshold_ = config.parallel_edge_distance_max_threshold;
379 ConnectionBasedNodelet::onInit();
382 srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
383 dynamic_reconfigure::Server<Config>::CallbackType
f =
385 srv_->setCallback (f);
391 pub_ = advertise<jsk_recognition_msgs::BoundingBoxArray>(*pnh_,
"output", 1);
393 = advertise<geometry_msgs::PoseArray>(*pnh_,
"output_pose_array", 1);
395 = advertise<visualization_msgs::Marker>(*pnh_,
"debug_marker", 1);
396 pub_debug_filtered_cloud_ = advertise<sensor_msgs::PointCloud2>(
397 *pnh_,
"debug_filtered_cloud", 1);
399 = advertise<jsk_recognition_msgs::PolygonArray>(*pnh_,
"debug_polygons", 1);
401 = advertise<jsk_recognition_msgs::ClusterPointIndices>(*pnh_,
"debug_clusters", 1);
411 sub_input_.subscribe(*pnh_,
"input", 1);
412 sub_edges_.subscribe(*pnh_,
"input_edges", 1);
413 sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
414 sync_->connectInput(sub_input_, sub_edges_);
415 sync_->registerCallback(boost::bind(
421 sub_input_.unsubscribe();
422 sub_edges_.unsubscribe();
428 pcl::ModelCoefficients::Ptr coefficients_a = pair.get<0>();
429 pcl::ModelCoefficients::Ptr coefficients_b = pair.get<1>();
432 return line_a->midLine(*line_b);
436 const pcl::PointCloud<PointT>::Ptr cloud,
437 const pcl::PointIndices::Ptr indices)
439 pcl::PointCloud<PointT>::Ptr ret (
new pcl::PointCloud<PointT>);
440 pcl::ExtractIndices<PointT>
ex;
441 ex.setInputCloud(cloud);
442 ex.setIndices(indices);
449 const pcl::PointCloud<PointT>::Ptr cloud)
452 for (
size_t i = 0; i < cloud->points.size(); i++) {
454 Eigen::Vector3f eigen_p = p.getVector3fMap();
455 Eigen::Vector3f foot;
456 line.
foot(eigen_p, foot);
457 points.push_back(foot);
463 const pcl::PointCloud<PointT>::Ptr cloud,
467 pcl::ModelCoefficients::Ptr coefficients_a = coefficients_pair.get<0>();
468 pcl::ModelCoefficients::Ptr coefficients_b = coefficients_pair.get<1>();
469 pcl::PointIndices::Ptr indices_a = indices_pair.get<0>();
470 pcl::PointIndices::Ptr indices_b = indices_pair.get<1>();
472 pcl::PointCloud<PointT>::Ptr cloud_a = extractPointCloud(cloud, indices_a);
473 pcl::PointCloud<PointT>::Ptr cloud_b = extractPointCloud(cloud, indices_b);
480 vertices.push_back(a_min_max.get<0>());
481 vertices.push_back(a_min_max.get<1>());
482 vertices.push_back(b_min_max.get<1>());
483 vertices.push_back(b_min_max.get<0>());
489 const std::vector<IndicesPair>& pairs,
490 const std::vector<CoefficientsPair>& coefficients_pair,
491 std::vector<IndicesPair>& filtered_indices_pairs,
492 std::vector<CoefficientsPair>& filtered_coefficients_pairs)
494 for (
size_t i = 0; i < coefficients_pair.size(); i++) {
496 pcl::ModelCoefficients::Ptr coefficients_a = coefficients_pair[i].get<0>();
497 pcl::ModelCoefficients::Ptr coefficients_b = coefficients_pair[i].get<1>();
503 Eigen::Vector3f origin_a, origin_b;
504 line_a->getOrigin(origin_a);
505 line_b->getOrigin(origin_b);
508 Eigen::Vector3f distance_vector;
509 line_a_aligned->parallelLineNormal(*line_b_aligned, distance_vector);
510 double distance = distance_vector.norm();
513 if (distance < parallel_edge_distance_max_threshold_ &&
514 distance > parallel_edge_distance_min_threshold_) {
515 filtered_indices_pairs.push_back(pairs[i]);
516 filtered_coefficients_pairs.push_back(coefficients);
522 pcl::PointIndices::Ptr
526 const pcl::PointCloud<PointT>::Ptr cloud)
529 pcl::PointIndices::Ptr indices(
new pcl::PointIndices);
531 pcl::PointCloud<PointT>::Ptr ret (
new pcl::PointCloud<PointT>);
532 for (
size_t i = 0; i < cloud->points.size(); i++) {
534 if (!std::isnan(p.x) && !std::isnan(p.y) && !std::isnan(p.z)) {
535 Eigen::Vector3f ep = p.getVector3fMap();
536 Eigen::Vector3f foot;
537 magnified_convex->projectOnPlane(ep, foot);
538 if (magnified_convex->isInside(foot) && convex->distanceSmallerThan(ep,
outlier_threshold_)) {
541 indices->indices.push_back(i);
550 const pcl::PointCloud<PointT>::Ptr filtered_cloud,
551 pcl::PointIndices::Ptr output_inliers,
552 pcl::ModelCoefficients::Ptr output_coefficients)
554 Eigen::Vector3f normal = convex->getNormal();
555 pcl::SACSegmentation<PointT> seg;
556 seg.setOptimizeCoefficients (
true);
557 seg.setModelType (pcl::SACMODEL_PERPENDICULAR_PLANE);
558 seg.setMethodType (pcl::SAC_RANSAC);
560 seg.setInputCloud(filtered_cloud);
561 seg.setMaxIterations (10000);
563 seg.setEpsAngle(pcl::deg2rad(10.0));
564 seg.segment (*output_inliers, *output_coefficients);
570 const pcl::PointCloud<PointT>::Ptr filtered_cloud,
571 pcl::PointIndices::Ptr output_inliers,
572 pcl::ModelCoefficients::Ptr output_coefficients)
574 Eigen::Vector3f normal_a = convex->getNormal();
576 Eigen::Vector3f normal_b;
577 mid_line->getDirection(normal_b);
578 Eigen::Vector3f normal = normal_a.cross(normal_b);
579 pcl::SACSegmentation<PointT> seg;
580 seg.setOptimizeCoefficients (
true);
581 seg.setModelType (pcl::SACMODEL_PERPENDICULAR_PLANE);
582 seg.setMethodType (pcl::SAC_RANSAC);
584 seg.setInputCloud(filtered_cloud);
585 seg.setMaxIterations (10000);
587 seg.setEpsAngle(pcl::deg2rad(5.0));
588 seg.segment (*output_inliers, *output_coefficients);
592 const pcl::PointCloud<EdgebasedCubeFinder::PointT>::Ptr cloud,
594 pcl::PointCloud<EdgebasedCubeFinder::PointT>::Ptr points_on_edge)
596 Eigen::Vector3f
ex, ey, ez;
598 = indices_coefficients_triple.get<1>();
600 = indices_coefficients_triple.get<0>();
609 if (!mid_line->isSameDirection(*line_a)) {
610 line_a = line_a->flip();
612 if (!mid_line->isSameDirection(*line_b)) {
613 line_b = line_b->flip();
617 pcl::PointCloud<PointT>::Ptr point_on_a
618 = extractPointCloud(cloud,
619 indices_triple.get<1>());
620 pcl::PointCloud<PointT>::Ptr point_on_b
621 = extractPointCloud(cloud,
622 indices_triple.get<2>());
623 pcl::PointCloud<PointT>::Ptr point_on_c
624 = extractPointCloud(cloud,
625 indices_triple.get<0>());
626 Eigen::Vector4f a_centroid4, b_centroid4, c_centroid4;
627 Eigen::Vector3f a_centroid, b_centroid, c_centroid;
628 pcl::compute3DCentroid(*point_on_a, a_centroid4);
629 pcl::compute3DCentroid(*point_on_b, b_centroid4);
630 pcl::compute3DCentroid(*point_on_c, c_centroid4);
631 jsk_recognition_utils::pointFromVectorToVector<Eigen::Vector4f, Eigen::Vector3f>(
632 a_centroid4, a_centroid);
633 jsk_recognition_utils::pointFromVectorToVector<Eigen::Vector4f, Eigen::Vector3f>(
634 b_centroid4, b_centroid);
635 jsk_recognition_utils::pointFromVectorToVector<Eigen::Vector4f, Eigen::Vector3f>(
636 c_centroid4, c_centroid);
642 pcl::PointCloud<PointT>::Ptr all_points(
new pcl::PointCloud<PointT>);
643 *all_points = *point_on_a + *point_on_b;
644 *all_points = *all_points + *point_on_c;
645 *points_on_edge = *all_points;
662 PointT min_point, max_point;
671 Eigen::Vector3f center_point
672 = (min_max_points.get<0>() + min_max_points.get<1>()) / 2.0;
673 double z_width = (min_max_points.get<0>() - min_max_points.get<1>()).norm();
674 mid_line_aligned->getDirection(ez);
675 mid_line_aligned->parallelLineNormal(*line_a_aligned, ex);
676 mid_line_aligned->parallelLineNormal(*line_b_aligned, ey);
678 double x_width = ex.norm();
679 double y_width = ey.norm();
685 ROS_INFO(
"ex: [%f, %f, %f]", ex[0], ex[1], ex[2]);
686 ROS_INFO(
"ey: [%f, %f, %f]", ey[0], ey[1], ey[2]);
687 ROS_INFO(
"ez: [%f, %f, %f]", ez[0], ez[1], ez[2]);
689 if (ex.cross(ey).dot(ez) < 0) {
694 std::vector<double> dimensions;
695 dimensions.push_back(x_width);
696 dimensions.push_back(y_width);
697 dimensions.push_back(z_width);
703 const sensor_msgs::PointCloud2::ConstPtr& input_cloud,
704 const jsk_recognition_msgs::ParallelEdgeArray::ConstPtr& input_edges)
707 pcl::PointCloud<PointT>::Ptr
cloud (
new pcl::PointCloud<PointT>);
708 pcl::PointCloud<PointT>::Ptr all_filtered_cloud (
new pcl::PointCloud<PointT>);
710 visualization_msgs::Marker
marker;
711 jsk_recognition_msgs::PolygonArray polygon_array;
712 geometry_msgs::PoseArray pose_array;
713 jsk_recognition_msgs::BoundingBoxArray box_array;
714 box_array.header = input_cloud->header;
715 pose_array.header = input_cloud->header;
716 std::vector<jsk_recognition_utils::Cube::Ptr> cubes;
717 std::vector<pcl::PointIndices::Ptr> candidate_cluster_indices;
718 for (
size_t i = 0; i < input_edges->edge_groups.size(); i++) {
719 jsk_recognition_msgs::ParallelEdge parallel_edge = input_edges->edge_groups[i];
720 std::vector<pcl::PointIndices::Ptr> edges
722 parallel_edge.cluster_indices);
725 parallel_edge.coefficients);
726 std::vector<IndicesCoefficientsTriple> triples
727 = tripleIndicesAndCoefficients(edges, coefficients);
728 std::vector<IndicesCoefficientsTriple> perpendicular_triples
729 = filterPerpendicularEdgeTriples(triples);
730 if (perpendicular_triples.size() > 0) {
732 pcl::PointCloud<PointT>::Ptr points_on_edges(
new pcl::PointCloud<PointT>);
734 for (
size_t j = 0; j < perpendicular_triples.size(); j++) {
735 pcl::PointCloud<PointT>::Ptr points_on_edge(
new pcl::PointCloud<PointT>);
738 perpendicular_triples[j],
740 *points_on_edges = *points_on_edges + *points_on_edge;
741 cubes.push_back(cube);
743 pub_debug_filtered_cloud_.publish(points_on_edges);
747 if (cubes.size() > 0) {
748 for (
size_t i = 0; i < cubes.size(); i++) {
750 jsk_recognition_msgs::BoundingBox ros_box = cubes[i]->toROSMsg();
751 ros_box.header = input_cloud->header;
752 box_array.boxes.push_back(ros_box);
753 pose_array.poses.push_back(ros_box.pose);
755 pub_.publish(box_array);
756 pub_pose_array_.publish(pose_array);
761 const Eigen::Vector3f& a,
762 const Eigen::Vector3f& b)
764 double dot = a.normalized().dot(b.normalized());
765 if (fabs(dot) >= 1.0) {
771 if (fabs(theta -
M_PI / 2.0) < pcl::deg2rad(20.0)) {
785 Eigen::Vector3f a_b_normal, a_c_normal;
788 if (isPerpendicularVector(a_b_normal, a_c_normal)) {
789 return A_PERPENDICULAR;
792 Eigen::Vector3f b_a_normal, b_c_normal;
795 if (isPerpendicularVector(b_a_normal, b_c_normal)) {
796 return B_PERPENDICULAR;
799 Eigen::Vector3f c_a_normal, c_b_normal;
802 if (isPerpendicularVector(c_a_normal, c_b_normal)) {
803 return C_PERPENDICULAR;
806 return NOT_PERPENDICULAR;
812 std::vector<IndicesCoefficientsTriple>
814 const std::vector<IndicesCoefficientsTriple>& triples)
816 std::vector<IndicesCoefficientsTriple> ret;
817 for (
size_t i = 0; i < triples.size(); i++) {
818 pcl::ModelCoefficients::Ptr a_coefficients
819 = triples[i].get<1>().get<0>();
820 pcl::ModelCoefficients::Ptr b_coefficients
821 = triples[i].get<1>().get<1>();
822 pcl::ModelCoefficients::Ptr c_coefficients
823 = triples[i].get<1>().get<2>();
831 EdgeRelation relation = perpendicularEdgeTriple(*edge_a,
834 if (relation != NOT_PERPENDICULAR) {
836 if (relation == A_PERPENDICULAR) {
837 ret.push_back(triples[i]);
839 else if (relation == B_PERPENDICULAR) {
842 boost::make_tuple(triples[i].get<0>().get<1>(),
843 triples[i].get<0>().get<0>(),
844 triples[i].get<0>().get<2>()),
846 triples[i].get<1>().get<1>(),
847 triples[i].get<1>().get<0>(),
848 triples[i].get<1>().get<2>()));
849 ret.push_back(new_triple);
851 else if (relation == C_PERPENDICULAR) {
854 boost::make_tuple(triples[i].get<0>().get<2>(),
855 triples[i].get<0>().get<0>(),
856 triples[i].get<0>().get<1>()),
858 triples[i].get<1>().get<2>(),
859 triples[i].get<1>().get<0>(),
860 triples[i].get<1>().get<1>()));
861 ret.push_back(new_triple);
869 const sensor_msgs::PointCloud2::ConstPtr& input_cloud,
870 const jsk_recognition_msgs::ParallelEdgeArray::ConstPtr& input_edges)
873 pcl::PointCloud<PointT>::Ptr
cloud (
new pcl::PointCloud<PointT>);
874 pcl::PointCloud<PointT>::Ptr all_filtered_cloud (
new pcl::PointCloud<PointT>);
876 visualization_msgs::Marker
marker;
877 jsk_recognition_msgs::PolygonArray polygon_array;
878 std::vector<pcl::PointIndices::Ptr> candidate_cluster_indices;
880 polygon_array.header = input_cloud->header;
881 marker.pose.orientation.w = 1.0;
882 marker.color.a = 1.0;
883 marker.color.r = 1.0;
884 marker.header = input_cloud->header;
885 marker.scale.x = 0.01;
886 marker.type = visualization_msgs::Marker::LINE_LIST;
887 NODELET_INFO(
"%lu parallel edge groups", input_edges->edge_groups.size());
888 geometry_msgs::PoseArray pose_array;
889 pose_array.header = input_cloud->header;
890 jsk_recognition_msgs::BoundingBoxArray ros_output;
891 ros_output.header = input_cloud->header;
893 for (
size_t i = 0; i < input_edges->edge_groups.size(); i++) {
894 jsk_recognition_msgs::ParallelEdge parallel_edge = input_edges->edge_groups[i];
896 if (parallel_edge.cluster_indices.size() <= 1) {
898 parallel_edge.cluster_indices.size());
902 i, parallel_edge.cluster_indices.size());
906 std::vector<pcl::PointIndices::Ptr> edges
908 parallel_edge.cluster_indices);
911 parallel_edge.coefficients);
913 std::vector<IndicesPair> pairs = combinateIndices(edges);
914 std::vector<CoefficientsPair> coefficients_pair
915 = combinateCoefficients(coefficients);
916 std::vector<IndicesPair> filtered_indices_pairs;
917 std::vector<CoefficientsPair> filtered_coefficients_pairs;
919 filtered_indices_pairs = pairs;
920 filtered_coefficients_pairs = coefficients_pair;
926 std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> convexes;
927 for (
size_t j = 0; j < filtered_coefficients_pairs.size(); j++) {
929 = convexFromPairs(cloud, filtered_coefficients_pairs[j],
931 convexes.push_back(convex);
933 std::vector<int> filtered_indices;
934 filterBasedOnConvex(cloud, convexes, filtered_indices);
936 pcl::PointIndices::Ptr filtered_cube_candidate_indices(
new pcl::PointIndices);
937 for (
size_t j = 0; j < filtered_indices.size(); j++) {
938 int index = filtered_indices[j];
941 = filtered_indices_pairs[index];
943 = filtered_coefficients_pairs[index];
946 pcl::PointIndices::Ptr filtered_indices
947 = preparePointCloudForRANSAC(
948 target_convex, target_edge_coefficients_pair, cloud);
951 filtered_cube_candidate_indices
1052 candidate_cluster_indices.push_back(filtered_cube_candidate_indices);
1055 pcl::PointIndices::Ptr first_inliers(
new pcl::PointIndices);
1056 pcl::ModelCoefficients::Ptr first_coefficients(
new pcl::ModelCoefficients);
1058 = estimateConvexPolygon(
1060 filtered_cube_candidate_indices,
1063 if (first_polygon) {
1064 geometry_msgs::PolygonStamped first_polygon_ros;
1065 first_polygon_ros.polygon = first_polygon->toROSMsg();
1066 first_polygon_ros.header = input_cloud->header;
1067 polygon_array.polygons.push_back(first_polygon_ros);
1105 pub_.publish(ros_output);
1106 pub_pose_array_.publish(pose_array);
1107 pub_debug_marker_.publish(marker);
1108 sensor_msgs::PointCloud2 ros_cloud;
1110 ros_cloud.header = input_cloud->header;
1111 pub_debug_filtered_cloud_.publish(ros_cloud);
1112 pub_debug_polygons_.publish(polygon_array);
1115 jsk_recognition_msgs::ClusterPointIndices ros_cluster_indices;
1116 ros_cluster_indices.header = input_cloud->header;
1117 for (
size_t i = 0; i < candidate_cluster_indices.size(); i++) {
1119 indices_msg.header = input_cloud->header;
1120 indices_msg.indices = candidate_cluster_indices[i]->indices;
1121 ros_cluster_indices.cluster_indices.push_back(indices_msg);
1123 pub_debug_clusers_.publish(ros_cluster_indices);
1126 std::vector<IndicesCoefficientsTriple>
1128 const std::vector<pcl::PointIndices::Ptr>& indices,
1129 const std::vector<pcl::ModelCoefficients::Ptr>& coefficients)
1131 if (indices.size() != coefficients.size()) {
1132 NODELET_ERROR(
"size of indices and coefficients are not same");
1133 return std::vector<IndicesCoefficientsTriple>();
1136 if (indices.size() <= 2 && coefficients.size() <= 2) {
1137 NODELET_WARN(
"[EdgebasedCubeFinder::tripleIndicesAndCoefficients] no enough canddiates");
1138 return std::vector<IndicesCoefficientsTriple>();
1140 std::vector<IndicesCoefficientsTriple> ret;
1141 for (
size_t i = 0; i < indices.size() - 2; i++) {
1142 for (
size_t j = i + 1; j < indices.size() - 1; j++) {
1143 for (
size_t k = j + 1; k < indices.size(); k++) {
1145 = boost::make_tuple(indices[i],
1149 = boost::make_tuple(coefficients[i],
1153 = boost::make_tuple(indices_triple,
1154 coefficients_triple);
1155 ret.push_back(indices_coefficients_triple);
1163 const pcl::PointCloud<PointT>::Ptr cloud,
1164 const pcl::PointIndices::Ptr indices,
1165 pcl::ModelCoefficients::Ptr coefficients,
1166 pcl::PointIndices::Ptr inliers)
1171 pcl::SACSegmentation<PointT> seg;
1172 seg.setOptimizeCoefficients (
true);
1173 seg.setModelType (pcl::SACMODEL_PLANE);
1174 seg.setMethodType (pcl::SAC_RANSAC);
1175 seg.setInputCloud(cloud);
1176 seg.setIndices(indices);
1177 seg.setDistanceThreshold(0.003);
1178 seg.segment(*inliers, *coefficients);
1182 if (inliers->indices.size() > 0) {
1183 return jsk_recognition_utils::convexFromCoefficientsAndInliers<PointT>(
1184 cloud, inliers, coefficients);
1192 const std::vector<pcl::PointIndices::Ptr>& indices)
1194 std::vector<IndicesPair> ret;
1195 for(
size_t i = 0; i < indices.size() - 1; i++) {
1196 for (
size_t j = i + 1; j < indices.size(); j++) {
1199 ret.push_back(pair);
1206 const std::vector<pcl::ModelCoefficients::Ptr>& coefficients)
1208 std::vector<CoefficientsPair> ret;
1209 for(
size_t i = 0; i < coefficients.size() - 1; i++) {
1210 for (
size_t j = i + 1; j < coefficients.size(); j++) {
1213 ret.push_back(pair);
virtual void getLinePoints(const jsk_recognition_utils::Line &line, const pcl::PointCloud< pcl::PointXYZRGB > &cloud, const pcl::PointIndices::Ptr indices, jsk_recognition_utils::Vertices &output)
virtual jsk_recognition_utils::ConvexPolygon::Ptr convexFromPairs(const pcl::PointCloud< PointT >::Ptr cloud, const CoefficientsPair &coefficients_pair, const IndicesPair &indices_pair)
virtual EdgeRelation perpendicularEdgeTriple(const jsk_recognition_utils::Line &edge_a, const jsk_recognition_utils::Line &edge_b, const jsk_recognition_utils::Line &edge_c)
bool distanceSmallerThan(const Eigen::Vector3f &p, double distance_threshold)
#define NODELET_ERROR(...)
virtual void foot(const Eigen::Vector3f &point, Eigen::Vector3f &output) const
#define NODELET_WARN(...)
virtual jsk_recognition_utils::PointPair computeAxisEndPoints(const jsk_recognition_utils::Line &axis, const jsk_recognition_utils::PointPair &a_candidates, const jsk_recognition_utils::PointPair &b_candidates)
virtual double computeAlpha(const Point &p) const
virtual std::vector< CoefficientsPair > combinateCoefficients(const std::vector< pcl::ModelCoefficients::Ptr > &coefficients)
virtual void configCallback(Config &config, uint32_t level)
boost::tuple< pcl::ModelCoefficients::Ptr, pcl::ModelCoefficients::Ptr > CoefficientsPair
virtual void filterBasedOnConvex(const pcl::PointCloud< PointT >::Ptr cloud, const std::vector< jsk_recognition_utils::ConvexPolygon::Ptr > &convexes, std::vector< int > &output_indices)
DiagnoalCubeHypothesis(const IndicesPair &pair, const CoefficientsPair &coefficients_pair, const double outlier_threshold)
virtual void estimateParallelPlane(const jsk_recognition_utils::ConvexPolygon::Ptr convex, const pcl::PointCloud< PointT >::Ptr filtered_cloud, pcl::PointIndices::Ptr output_inliers, pcl::ModelCoefficients::Ptr output_coefficients)
boost::shared_ptr< ConvexPolygon > Ptr
std::vector< pcl::ModelCoefficients::Ptr > convertToPCLModelCoefficients(const std::vector< PCLModelCoefficientMsg > &coefficients)
virtual jsk_recognition_utils::ConvexPolygon::Ptr buildConvexPolygon(const jsk_recognition_utils::PointPair &a_edge_pair, const jsk_recognition_utils::PointPair &b_edge_pair)
boost::tuple< pcl::ModelCoefficients::Ptr, pcl::ModelCoefficients::Ptr, pcl::ModelCoefficients::Ptr > CoefficientsTriple
virtual double evaluatePointOnPlanes(const pcl::PointCloud< pcl::PointXYZRGB > &cloud, jsk_recognition_utils::ConvexPolygon &polygon_a, jsk_recognition_utils::ConvexPolygon &polygon_b)
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
virtual std::vector< IndicesCoefficientsTriple > filterPerpendicularEdgeTriples(const std::vector< IndicesCoefficientsTriple > &triples)
virtual jsk_recognition_utils::PointPair minMaxPointOnLine(const jsk_recognition_utils::Line &line, const pcl::PointCloud< PointT >::Ptr cloud)
virtual PointPair findEndPoints(const Vertices &points) const
virtual jsk_recognition_utils::Line::Ptr midLineFromCoefficientsPair(const CoefficientsPair &pair)
T dot(T *pf1, T *pf2, int length)
virtual void estimatePerpendicularPlane(const jsk_recognition_utils::ConvexPolygon::Ptr convex, const CoefficientsPair &edge_coefficients, const pcl::PointCloud< PointT >::Ptr filtered_cloud, pcl::PointIndices::Ptr output_inliers, pcl::ModelCoefficients::Ptr output_coefficients)
std::vector< pcl::PointIndices::Ptr > convertToPCLPointIndices(const std::vector< PCLIndicesMsg > &cluster_indices)
virtual jsk_recognition_utils::ConvexPolygon::Ptr estimateConvexPolygon(const pcl::PointCloud< PointT >::Ptr cloud, const pcl::PointIndices::Ptr indices, pcl::ModelCoefficients::Ptr coefficients, pcl::PointIndices::Ptr inliers)
boost::tuple< pcl::PointIndices::Ptr, pcl::PointIndices::Ptr > IndicesPair
PlanarCubeHypothesis(const IndicesPair &pair, const CoefficientsPair &coefficients_pair, const double outlier_threshold)
virtual pcl::PointIndices::Ptr preparePointCloudForRANSAC(const jsk_recognition_utils::ConvexPolygon::Ptr convex, const CoefficientsPair &edge_coefficients_pair, const pcl::PointCloud< PointT >::Ptr cloud)
void toPCL(const pcl_msgs::PointIndices &pi, pcl::PointIndices &pcl_pi)
TFSIMD_FORCE_INLINE Vector3 normalized() const
virtual void estimate2(const sensor_msgs::PointCloud2::ConstPtr &input_cloud, const jsk_recognition_msgs::ParallelEdgeArray::ConstPtr &input_edges)
virtual std::vector< IndicesPair > combinateIndices(const std::vector< pcl::PointIndices::Ptr > &indices)
Eigen::Quaternionf rotFrom3Axis(const Eigen::Vector3f &ex, const Eigen::Vector3f &ey, const Eigen::Vector3f &ez)
const IndicesPair indices_pair_
virtual void filterPairsBasedOnParallelEdgeDistances(const std::vector< IndicesPair > &pairs, const std::vector< CoefficientsPair > &coefficients_pair, std::vector< IndicesPair > &filtered_indices_pairs, std::vector< CoefficientsPair > &filtered_coefficients_pairs)
virtual void estimate(const pcl::PointCloud< pcl::PointXYZRGB > &cloud)
jsk_pcl_ros::EdgebasedCubeFinderConfig Config
virtual pcl::PointCloud< PointT >::Ptr extractPointCloud(const pcl::PointCloud< PointT >::Ptr cloud, const pcl::PointIndices::Ptr indices)
std::vector< int > addIndices(const std::vector< int > &a, const std::vector< int > &b)
virtual std::vector< IndicesCoefficientsTriple > tripleIndicesAndCoefficients(const std::vector< pcl::PointIndices::Ptr > &indices, const std::vector< pcl::ModelCoefficients::Ptr > &coefficients)
const CoefficientsPair coefficients_pair_
void toROSMsg(const pcl::PointCloud< T > &pcl_cloud, sensor_msgs::PointCloud2 &cloud)
virtual jsk_recognition_utils::Cube::Ptr cubeFromIndicesAndCoefficients(const pcl::PointCloud< PointT >::Ptr cloud, const IndicesCoefficientsTriple &indices_coefficients_triple, pcl::PointCloud< EdgebasedCubeFinder::PointT >::Ptr points_on_edge)
static Ptr fromCoefficients(const std::vector< float > &coefficients)
std::vector< Eigen::Vector3f, Eigen::aligned_allocator< Eigen::Vector3f > > Vertices
#define NODELET_INFO(...)
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::EdgebasedCubeFinder, nodelet::Nodelet)
INLINE Rall1d< T, V, S > acos(const Rall1d< T, V, S > &x)
double outlier_threshold_
virtual void computeCentroid(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const pcl::PointIndices::Ptr &indices, Eigen::Vector3f &output)
boost::tuple< Point, Point > PointPair
boost::tuple< IndicesTriple, CoefficientsTriple > IndicesCoefficientsTriple
boost::tuple< pcl::PointIndices::Ptr, pcl::PointIndices::Ptr, pcl::PointIndices::Ptr > IndicesTriple
CubeHypothesis(const IndicesPair &pair, const CoefficientsPair &coefficients_pair, const double outlier_threshold)
virtual void estimate(const sensor_msgs::PointCloud2::ConstPtr &input_cloud, const jsk_recognition_msgs::ParallelEdgeArray::ConstPtr &input_edges)
pcl::PointIndices PCLIndicesMsg
jsk_recognition_utils::Cube::Ptr cube_
Cube cube(Eigen::Vector3f(1, 0, 0), Eigen::Quaternionf(0.108755, 0.088921, 0.108755, 0.984092), Eigen::Vector3f(0.3, 0.3, 0.3))
virtual bool isPerpendicularVector(const Eigen::Vector3f &a, const Eigen::Vector3f &b)
virtual void unsubscribe()
double distance(const urdf::Pose &transform)
virtual ~CubeHypothesis()
virtual void parallelLineNormal(const Line &other, Eigen::Vector3f &output) const
virtual int countInliers(const pcl::PointCloud< PointT >::Ptr cloud, const jsk_recognition_utils::ConvexPolygon::Ptr convex)