桌子模型

下载:https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_lms400.pcd

代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkInteractorStyle.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkCellArray.h>
#include <vtkInteractorStyleTrackballCamera.h>

VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);

// VTK绘制剩下的点云
void drawSegment(pcl::PointIndices &indices, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();
    for (int i: (indices).indices) {
        vtkIdType pid[1];
        pid[0] = points->InsertNextPoint(cloud->at(i).x, cloud->at(i).y,
                                         cloud->at(i).z);
        vertices->InsertNextCell(1, pid);
    }
    vtkPolyData *polyData = vtkPolyData::New();
    polyData->SetPoints(points);
    polyData->SetVerts(vertices);

    vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
    mapper->SetInputData(polyData);

    vtkActor *actor = vtkActor::New();
    actor->SetMapper(mapper);
    actor->GetProperty()->SetColor(1.0, 0.0, 0.0);
    actor->GetProperty()->SetPointSize(3);

    vtkRenderer *renderer = vtkRenderer::New();
    renderer->AddActor(actor);
    renderer->SetBackground(.0, .0, .0);//set background

    vtkRenderWindow *renderwind = vtkRenderWindow::New();
    renderwind->AddRenderer(renderer);

    vtkInteractorStyleTrackballCamera *style = vtkInteractorStyleTrackballCamera::New();

    vtkRenderWindowInteractor *renderwindIt = vtkRenderWindowInteractor::New();
    renderwindIt->SetRenderWindow(renderwind);
    renderwindIt->SetInteractorStyle(style);

    renderwind->Render();
    renderwindIt->Start();
}

int main()
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_source(new pcl::PointCloud<pcl::PointXYZ>);
    std::string fileName = getenv("HOME") + std::string("/data_set/table_scene_lms400.pcd");
    std::cout << fileName << std::endl;
    pcl::io::loadPCDFile(fileName, *cloud_source);
    // 模型系数
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
    // 点索引数组
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
    pcl::SACSegmentation<pcl::PointXYZ> sac;
    sac.setInputCloud(cloud_source);
    // 提取方法
    sac.setMethodType(pcl::SAC_RANSAC);
    // 提取的物体模型
    sac.setModelType(pcl::SACMODEL_PLANE);
    sac.setDistanceThreshold(0.01);
    sac.setMaxIterations(100);
    sac.setProbability(0.95);
    sac.segment(*inliers, *coefficients);
    // 拟合系数
    std::cout << *coefficients << std::endl;

    // 绘制分割后的点云
    drawSegment(*inliers, cloud_source);
}

运行结果

header:
seq: 0 stamp: 0 frame_id:
values[]
  values[0]:   -0.00691321
  values[1]:   -0.875345
  values[2]:   -0.48345
  values[3]:   -1.17686

参考

https://pcl.readthedocs.io/projects/tutorials/en/master/planar_segmentation.html#planar-segmentation