#include #include <pcl/io/ply_io.h> #include <pcl/point_types.h> #include <pcl/common/pca.h> #include <pcl/segmentation/sac_segmentation.h> #include <pcl/visualization/pcl_visualizer.h>

int main() { //------------------------------输入点云----------------------------------- pcl::PointCloudpcl::PointXYZ::Ptr cloud(new pcl::PointCloudpcl::PointXYZ); if (pcl::io::loadPLYFilepcl::PointXYZ("D:\DIANYUNWENJIANJIA\newkruskal2_ply.ply", *cloud) < 0) { PCL_ERROR("读取文件错误"); return -1; } //---------------------------------PCA------------------------------------- pcl::PCApcl::PointXYZ pca; pca.setInputCloud(cloud);

// 获取特征值对应的特征向量
Eigen::Vector3f V1 = pca.getEigenVectors().col(0);
Eigen::Vector3f V2 = pca.getEigenVectors().col(1);
Eigen::Vector3f V3 = pca.getEigenVectors().col(2);

//---------------------------直线的点向式---------------------------------
float m = V1[0], n = V1[1], p = V1[2];
float x0 = pca.getMean()[0], y0 = pca.getMean()[1], z0 = pca.getMean()[2];
std::cout << "直线的方向向量为:" << V1.transpose() << std::endl;
std::cout << "直线上一点的坐标为:" << pca.getMean().head<3>().transpose() << std::endl;

//---------------------------直线的一般式---------------------------------
Eigen::Matrix<float, 2, 3> A;
A.row(0) = V2.transpose();
A.row(1) = V3.transpose();
Eigen::Vector3f sigma = pca.getMean().head<3>();
Eigen::Vector2f b = A * sigma;

std::cout << "直线的一般式为:" << std::endl;
std::cout << V2[0] << "x+(" << V2[1] << "y)+(" << V2[2] << "z)=" << b[0] << std::endl;
std::cout << V3[0] << "x+(" << V3[1] << "y)+(" << V3[2] << "z)=" << b[1] << std::endl;

//----------------------------点云可视化----------------------------------
pcl::visualization::PCLVisualizer viewer("Point Cloud Viewer");
viewer.setBackgroundColor(0, 0, 0);
viewer.addPointCloud<pcl::PointXYZ>(cloud, "cloud");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");

//--------------------------拟合直线可视化--------------------------------
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
coefficients->values.resize(6);
coefficients->values[0] = x0;
coefficients->values[1] = y0;
coefficients->values[2] = z0;
coefficients->values[3] = m;
coefficients->values[4] = n;
coefficients->values[5] = p;

viewer.addLine<pcl::PointXYZ, pcl::PointXYZ>(*cloud, *cloud, "line");
viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.0, 0.0, "line");

while (!viewer.wasStopped())
{
    viewer.spinOnce();
}

//----------------------------输出点云-----------------------------------
pcl::io::savePLYFile("D:\\DIANYUNWENJIANJIA\\最小二乘法拟合直线_ply.ply", *cloud);

return 0;

原文地址: https://www.cveoy.top/t/topic/ihBP 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录