PCL Ransac 点云平面拟合 将三维不平整表面投影到一个平面 C++代码(没有用绘制平面的内部函数)

自古美人都是妖i 提交于 2019-12-22 20:45:11

参考链接(投影):https://blog.csdn.net/soaryy/article/details/82884691

参考链接(Ransac拟合):https://blog.csdn.net/weixin_41758695/article/details/85322304

利用开源的点云库PCL,使用VS2015完成的C++代码,测试文件(.obj)已经在本站(csdn)上传资源,供大家交流,如有问题欢迎多提宝贵意见

对于不平整表面,利用ransac平面拟合,然后将三维不平整表面(或者曲面)近似为一个平面,并将表面上的点投影到该平面,并且显示出来,如图所示,白色为原始点云,绿色为拟合的平面

依据公式:

 

代码如下

#define _CRT_SECURE_NO_WARNINGS
#include <glut.h>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
 
#include <iostream>
#include <string>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/obj_io.h>
#include <pcl/PolygonMesh.h>
#include <pcl/point_cloud.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <cstdlib>
#include <vector>
 
using namespace pcl;
using namespace std;
 
 
int main()
{   //--------------------- Input path ----------------------------------------------
    pcl::PolygonMesh mesh;
    pcl::io::loadPolygonFile(".\\Original.obj", mesh);
 
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPCLPointCloud2(mesh.cloud, *cloud);
 
    //--------------------------- Plane ---------------------------------
 
    pcl::SACSegmentation<pcl::PointXYZ> sac;
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane(new pcl::PointCloud<pcl::PointXYZ>);
 
    sac.setInputCloud(cloud);
    sac.setMethodType(pcl::SAC_RANSAC);
    sac.setModelType(pcl::SACMODEL_PLANE);
    sac.setDistanceThreshold(15);                  //Distance need to be adjusted according to the obj
    sac.setMaxIterations(100);
    sac.setProbability(0.95); 
    sac.segment(*inliers, *coefficients);
 
    boost::shared_ptr<pcl::visualization::PCLVisualizer> view(new pcl::visualization::PCLVisualizer);
    view->addPointCloud(cloud);
 
    //Plane Model: ax+by+cz+d=0; saved in *coefficients
 
    float a, b, c, d;
    a = coefficients->values[0];
    b = coefficients->values[1];
    c = coefficients->values[2];
    d = coefficients->values[3];
 
    int i, j, k;
    int size = cloud->size();
    //------------------------ Projection ------------------------
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_proj(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointXYZ point;
    for (i = 0; i<size; i++)
    {
        float x, y, z;
        x = cloud->at(i).x;
        y = cloud->at(i).y;
        z = cloud->at(i).z;
 
        point.x = ((b*b + c*c)*x - a*(b*y + c*z + d)) / (a*a + b*b + c*c);
        point.y = ((a*a + c*c)*y - b*(a*x + c*z + d)) / (a*a + b*b + c*c);
        point.z = ((b*b + a*a)*z - c*(a*x + b*y + d)) / (a*a + b*b + c*c);
        cloud_proj->push_back(point);
    }
 
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color_handler(cloud_proj, 50, 230, 12);
    view->addPointCloud(cloud_proj, color_handler, "CH");
    view->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "CH");
 
    while (!view->wasStopped())
    {
        view->spinOnce(100);
    }
 
    system("pause");
    return 0;
}
 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!