Go to the documentation of this file.00001 #include <rail_segmentation/bounding_volume_calculator.h>
00002
00003 rail_manipulation_msgs::BoundingVolume BoundingVolumeCalculator::computeBoundingVolume(sensor_msgs::PointCloud2 cloud)
00004 {
00005
00006 pcl::PointCloud<pcl::PointXYZ>::Ptr object_cloud(new pcl::PointCloud<pcl::PointXYZ>);
00007 pcl::PCLPointCloud2 converter;
00008 pcl_conversions::toPCL(cloud, converter);
00009 pcl::fromPCLPointCloud2(converter, *object_cloud);
00010
00011 return BoundingVolumeCalculator::computeBoundingVolume(object_cloud);
00012 }
00013
00014 rail_manipulation_msgs::BoundingVolume
00015 BoundingVolumeCalculator::computeBoundingVolume(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud)
00016 {
00017 pcl::PointCloud<pcl::PointXYZ>::Ptr xyz_cloud(new pcl::PointCloud<pcl::PointXYZ>);
00018 pcl::copyPointCloud(*cloud, *xyz_cloud);
00019
00020 return BoundingVolumeCalculator::computeBoundingVolume(xyz_cloud);
00021 }
00022
00023 rail_manipulation_msgs::BoundingVolume
00024 BoundingVolumeCalculator::computeBoundingVolume(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
00025 {
00026
00027 pcl::PointXYZ min_original, max_original;
00028 pcl::getMinMax3D(*cloud, min_original, max_original);
00029
00030
00031
00032 pcl::PointCloud<pcl::PointXYZ>::Ptr projected_cloud(new pcl::PointCloud<pcl::PointXYZ>);
00033 pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients());
00034 coefficients->values.resize(4);
00035 coefficients->values[0] = coefficients->values[1] = 0;
00036 coefficients->values[2] = 1;
00037 coefficients->values[3] = 0;
00038 pcl::ProjectInliers<pcl::PointXYZ> projector;
00039 projector.setModelType(pcl::SACMODEL_PLANE);
00040 projector.setInputCloud(cloud);
00041 projector.setModelCoefficients(coefficients);
00042 projector.filter(*projected_cloud);
00043
00044
00045 Eigen::Matrix3f covariance;
00046 Eigen::Vector4f centroid;
00047
00048 centroid[0] = static_cast<float>((min_original.x + max_original.x)/2.0);
00049 centroid[1] = static_cast<float>((min_original.y + max_original.y)/2.0);
00050 centroid[2] = 0;
00051 pcl::computeCovarianceMatrixNormalized(*projected_cloud, centroid, covariance);
00052 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver(covariance, Eigen::ComputeEigenvectors);
00053 Eigen::Matrix3f eig_dx = eigen_solver.eigenvectors();
00054 eig_dx.col(2) = eig_dx.col(0).cross(eig_dx.col(1));
00055
00056
00057 Eigen::Matrix4f p2w(Eigen::Matrix4f::Identity());
00058 p2w.block(0, 0, 3, 3) = eig_dx.transpose();
00059 p2w.block(0, 3, 3, 1) = -1.f * (p2w.block(0, 0, 3, 3) * centroid.head(3));
00060 pcl::PointCloud<pcl::PointXYZ> c_points;
00061 pcl::transformPointCloud(*projected_cloud, c_points, p2w);
00062
00063 pcl::PointXYZ min_pt, max_pt;
00064 pcl::getMinMax3D(c_points, min_pt, max_pt);
00065 const Eigen::Vector3f mean_diag = 0.5f * (max_pt.getVector3fMap() + min_pt.getVector3fMap());
00066
00067
00068 const Eigen::Quaternionf qfinal(eig_dx);
00069 const Eigen::Vector3f tfinal = eig_dx * mean_diag + centroid.head(3);
00070
00071
00072 rail_manipulation_msgs::BoundingVolume bounding_box;
00073 bounding_box.dimensions.x = max_original.z - min_original.z;
00074 bounding_box.dimensions.y = max_pt.y - min_pt.y;
00075 bounding_box.dimensions.z = max_pt.z - min_pt.z;
00076 bounding_box.pose.header.frame_id = cloud->header.frame_id;
00077 bounding_box.pose.pose.position.x = tfinal[0];
00078 bounding_box.pose.pose.position.y = tfinal[1];
00079 bounding_box.pose.pose.position.z = (min_original.z + max_original.z)/2.0;
00080 bounding_box.pose.pose.orientation.w = qfinal.w();
00081 bounding_box.pose.pose.orientation.x = qfinal.x();
00082 bounding_box.pose.pose.orientation.y = qfinal.y();
00083 bounding_box.pose.pose.orientation.z = qfinal.z();
00084
00085 return bounding_box;
00086 }