《PCL点云库学习&VS2010(X64)》Part 28 BoundingBox&addArray
2017-04-18 09:51
2066 查看
《PCL点云库学习&VS2010(X64)》Part 28 BoundingBox&addArray
参考资源1
参考资源2
参考资源3
代码:
注:
算法的基本流程步骤如下:
1) compute the centroid (c0, c1, c2) and the normalized covariance
2) compute the eigenvectors e0, e1, e2. The reference system will be (e0, e1, e0 X e1) --- note: e0 X e1 = +/- e2
3) move the points in that RF --- note: the transformation given by the rotation matrix (e0, e1, e0 X e1) & (c0, c1, c2) must be inverted
4) compute the max, the min and the center of the diagonal
5) given a box centered at the origin with size (max_pt.x - min_pt.x, max_pt.y - min_pt.y, max_pt.z - min_pt.z) the transformation you have to apply is Rotation = (e0, e1, e0 X e1) & Translation = Rotation * center_diag + (c0, c1, c2)
参考资源1
参考资源2
参考资源3
代码:
#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); VTK_MODULE_INIT(vtkInteractionStyle); VTK_MODULE_INIT(vtkRenderingFreeType); #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/visualization/pcl_visualizer.h> #include <pcl/filters/project_inliers.h> #include <string> #include <Eigen/Core> #include <boost/thread/thread.hpp> #include <pcl/features/normal_3d_omp.h> #include <pcl/common/transforms.h> using namespace std; int main(int argc, char** argv) { //pcl::PointXYZRGBNormal pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBNormal>); string fileName("Bunny.pcd"); pcl::io::loadPCDFile(fileName, *cloud); pcl::visualization::PCLVisualizer viewer; pcl::NormalEstimationOMP<pcl::PointXYZRGBNormal, pcl::PointXYZRGBNormal> nor; pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZRGBNormal>); nor.setSearchMethod(tree); nor.setInputCloud(cloud); nor.setNumberOfThreads(10); nor.setRadiusSearch(0.03); nor.compute(*cloud); size_t cloud_size = cloud->size(); for (size_t i = 0; i < cloud_size; ++i) { uint8_t r = (cloud->at(i).normal_x + 1) / 2 * 255; uint8_t g = (cloud->at(i).normal_y + 1) / 2 * 255; uint8_t b = (cloud->at(i).normal_z + 1) / 2 * 255; uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b); cloud->at(i).rgb = *reinterpret_cast<float*>(&rgb); } Eigen::Vector4f pcaCentroid; pcl::compute3DCentroid(*cloud, pcaCentroid); Eigen::Matrix3f covariance; pcl::computeCovarianceMatrixNormalized(*cloud, pcaCentroid, covariance); Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver(covariance, Eigen::ComputeEigenvectors); Eigen::Matrix3f eigenVectorsPCA = eigen_solver.eigenvectors(); eigenVectorsPCA.col(2) = eigenVectorsPCA.col(0).cross(eigenVectorsPCA.col(1)); /* // Note that getting the eigenvectors can also be obtained via the PCL PCA interface with something like: pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPCAprojection (new pcl::PointCloud<pcl::PointXYZ>); pcl::PCA<pcl::PointXYZ> pca; pca.setInputCloud(cloudSegmented); pca.project(*cloudSegmented, *cloudPCAprojection); std::cerr << std::endl << "EigenVectors: " << pca.getEigenVectors() << std::endl;//计算特征向量 std::cerr << std::endl << "EigenValues: " << pca.getEigenValues() << std::endl;//计算特征值 // In this case, pca.getEigenVectors() gives similar eigenVectors to eigenVectorsPCA. */ // Transform the original cloud to the origin where the principal components correspond to the axes. Eigen::Matrix4f transform(Eigen::Matrix4f::Identity()); transform.block<3, 3>(0, 0) = eigenVectorsPCA.transpose(); transform.block<3, 1>(0, 3) = -1.f * (transform.block<3, 3>(0, 0) * pcaCentroid.head<3>()); pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr transformedCloud(new pcl::PointCloud<pcl::PointXYZRGBNormal>); pcl::transformPointCloudWithNormals(*cloud, *transformedCloud, transform); pcl::PointXYZRGBNormal min_pt, max_pt; pcl::getMinMax3D(*transformedCloud, min_pt, max_pt); const Eigen::Vector3f meanDiagonal = 0.5f*(max_pt.getVector3fMap() + min_pt.getVector3fMap()); const Eigen::Quaternionf bboxQuaternion(eigenVectorsPCA); //Quaternions are a way to do rotations https://www.youtube.com/watch?v=mHVwd8gYLnI const Eigen::Vector3f bboxTransform = eigenVectorsPCA * meanDiagonal + pcaCentroid.head<3>(); //get the array //------------------------------------------------------------------------------------------------------------------ // getting the two points for the arrow pcl::PointXYZ front_midpoint, back_midpoint; front_midpoint.x = (max_pt.x + min_pt.x) / 2; front_midpoint.y = (max_pt.y + min_pt.y) / 2; front_midpoint.z = max_pt.z; back_midpoint.x = (max_pt.x + min_pt.x) / 2; back_midpoint.y = (max_pt.y + min_pt.y) / 2; back_midpoint.z = min_pt.z; //------------------------------------------------------------------------------------------------------------------ //visualization viewer.addPointCloud<pcl::PointXYZRGBNormal>(cloud); viewer.addCube(bboxTransform, bboxQuaternion, max_pt.x - min_pt.x, max_pt.y - min_pt.y, max_pt.z - min_pt.z, "bbox"); viewer.addArrow(front_midpoint, back_midpoint, 1.0, 0.7, 0.0, false, "arrow_box"); viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "bbox"); viewer.addCoordinateSystem(1.0); while (!viewer.wasStopped()) { viewer.spinOnce(100); boost::this_thread::sleep(boost::posix_time::microseconds(100000)); } return 0; }
注:
算法的基本流程步骤如下:
1) compute the centroid (c0, c1, c2) and the normalized covariance
2) compute the eigenvectors e0, e1, e2. The reference system will be (e0, e1, e0 X e1) --- note: e0 X e1 = +/- e2
3) move the points in that RF --- note: the transformation given by the rotation matrix (e0, e1, e0 X e1) & (c0, c1, c2) must be inverted
4) compute the max, the min and the center of the diagonal
5) given a box centered at the origin with size (max_pt.x - min_pt.x, max_pt.y - min_pt.y, max_pt.z - min_pt.z) the transformation you have to apply is Rotation = (e0, e1, e0 X e1) & Translation = Rotation * center_diag + (c0, c1, c2)
相关文章推荐
- 《PCL点云库学习&VS2010(X64)》Part 2 A simple test of PCL in MFC
- 《PCL点云库学习&VS2010(X64)》Part 1 Installation of PCL in VS2010(x64)
- 《PCL点云库学习&VS2010(X64)》Part 3 CMake2.8.2+VTK5.10.1+VS2010 64bit
- 《PCL点云库学习&VS2010(X64)》Part 24 PCL&VTK&Eigen Spline曲线拟合
- 《PCL点云库学习&VS2010(X64)》Part 5 VTK6.2+VS2013+Qt5.5 测试VTK基于VS2013的Qt程序
- 《PCL点云库学习&VS2010(X64)》Part 31 pcl::PointCloud::Ptr和pcl::PointCloud相互转换
- 《PCL点云库学习&VS2010(X64)》Part 26 PCL中的fromPCLPointCloud2与toPCLPointCloud2
- 《PCL点云库学习&VS2010(X64)》Part 16 PCL1.72(VTK6.2.0)滤波例程(2)之双边滤波
- 《PCL点云库学习&VS2010(X64)》Part 15 PCL1.72(VTK6.2.0)三角网格化(2)之泊松重构
- 《PCL点云库学习&VS2010(X64)》Part 21 VTK6.2+VS2013 利用PCL读取ply格式网格曲面
- 《PCL点云库学习&VS2010(X64)》Part 22 激光雷达点云数据处理相关算法库收集
- 《PCL点云库学习&VS2010(X64)》Part 18 PCL1.72(VTK6.2.0)编译CloudCompare注意点
- 《PCL点云库学习&VS2010(X64)》Part 8 PCL1.72(VTK6.2.0)可视化例程
- 《PCL点云库学习&VS2010(X64)》Part 7 PCL双边滤波BilateralFilter
- 《PCL点云库学习&VS2010(X64)》Part 17 PCL1.72(VTK6.2.0)数据格式转换txt2pcd
- 《PCL点云库学习&VS2010(X64)》Part 12 PCL1.72(VTK6.2.0)三角网格化(1)
- 《PCL点云库学习&VS2010(X64)》Part 30 空间中求一点到两点所构成的直线的距离
- 《PCL点云库学习&VS2010(X64)》Part 6 VTK6.2+VS2013+Qt5.5 测试VTK基于VS2013的Qt程序之PCLViewer
- 《PCL点云库学习&VS2010(X64)》Part 10 PCL1.72(VTK6.2.0)选点操作
- 《PCL点云库学习&VS2010(X64)》Part 20 PCL1.72(VTK6.2.0)PCL控制台程序线程