VTK 示例:点云显示

本文演示如何通过 VTK 实现点云(Point Cloud)显示,完整代码位于 GitHub 仓库 getiot/vtk-courses

示例代码

源代码 main.cpp

#include <vtkActor.h>
#include <vtkCleanPolyData.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPointSource.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkInteractorStyleTrackballCamera.h>

using namespace std;

#define DEFAULT_DATA_FILE    "data.txt"

int main(int argc, char **argv)
{
    vtkSmartPointer<vtkPoints> m_Points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();  //_存放细胞顶点,用于渲染(显示点云所必须的)
    vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
    vtkSmartPointer<vtkPolyDataMapper> pointMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    vtkSmartPointer<vtkActor> pointActor = vtkSmartPointer<vtkActor>::New();
    vtkSmartPointer<vtkRenderer> ren1 = vtkSmartPointer< vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
    vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    vtkSmartPointer<vtkInteractorStyleTrackballCamera> istyle = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();

    //_读进点云数据信息
    const char *filename = NULL;
    if (argc > 1) {
        filename = argv[1];
    }
    else {
        filename = DEFAULT_DATA_FILE;
    }

    ifstream infile(filename, ios::in);
    double x, y, z;
    char line[128];
    int i = 0;
    while (infile.getline(line, sizeof(line)))
    {
        stringstream ss(line);
        ss >> x;
        ss >> y;
        ss >> z;

        m_Points->InsertPoint(i, x, y, z);  //_加入点信息
        vertices->InsertNextCell(1);        //_加入细胞顶点信息----用于渲染点集
        vertices->InsertCellPoint(i);
        i++;
    }
    infile.close();

    //_创建待显示数据源

    polyData->SetPoints(m_Points);      //_设置点集
    polyData->SetVerts(vertices);       //_设置渲染顶点
    pointMapper->SetInputData(polyData);

    pointActor->SetMapper(pointMapper);
    pointActor->GetProperty()->SetColor(1, 0, 0);
    pointActor->GetProperty()->SetAmbient(0.5);
    pointActor->GetProperty()->SetPointSize(3);
    //pointActor->GetProperty()->SetRepresentationToWireframe();
    //pointActor->GetProperty()->SetRepresentationToSurface();

    ren1->AddActor(pointActor);
    ren1->SetBackground(0, 0, 0);

    renWin->AddRenderer(ren1);
    renWin->SetSize(800, 800);

    iren->SetInteractorStyle(istyle);
    iren->SetRenderWindow(renWin);  //交互

    renWin->Render();
    iren->Start();
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

project(PointCloud_01)

find_package(VTK COMPONENTS 
  vtkCommonColor
  vtkCommonCore
  vtkCommonDataModel
  vtkFiltersCore
  vtkFiltersSources
  vtkInteractionStyle
  vtkRenderingContextOpenGL2
  vtkRenderingCore
  vtkRenderingFreeType
  vtkRenderingGL2PSOpenGL2
  vtkRenderingOpenGL2
  QUIET
)

if (NOT VTK_FOUND)
  message("Skipping PointCloud_01: {VTK_NOT_FOUND_MESSAGE}")
  return()
endif()
message (STATUS "VTK_VERSION:{VTK_VERSION}")
if (VTK_VERSION VERSION_LESS "8.90.0")
  # old system
  include({VTK_USE_FILE})
  add_executable(PointCloud_01 MACOSX_BUNDLE main.cpp )
  target_link_libraries(PointCloud_01 PRIVATE{VTK_LIBRARIES})
else()
  # Prevent a "command line is too long" failure in Windows.
  set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
  add_executable(PointCloud_01 MACOSX_BUNDLE main.cpp )
  target_link_libraries(PointCloud_01 PRIVATE {VTK_LIBRARIES})
  # vtk_module_autoinit is needed
  vtk_module_autoinit(
    TARGETS PointCloud_01
    MODULES{VTK_LIBRARIES}
    )
endif()

编译运行

$ mkdir build
$ cd build/
$ cmake ..
$ make

在运行程序之前,需要先准备一个 data.txt 文件存放点云的坐标数据。假设 data.txt 文件内容如下(依次为 X Y Z):

0 0 0
0 0 2
0 2 2
0 2 0
2 0 0
2 0 2
2 2 2
2 2 0
1 0 0
0 1 0
0 0 1
0 1 1
1 1 0
1 0 1
1 1 1
1 0 2
0 1 2
1 1 2
1 2 2
1 2 0
0 2 1
1 2 1
2 1 0
2 0 1
2 1 1
2 1 2
2 2 1

现在,执行 ./PointCloud_01 命令运行示例程序,运行效果如下: