VTK可视化管线详解(以点云与柱体显示为例)

1. 什么是vtk可视化管线?

定义: 可视化管线是指用于获取或创建数据处理数据以及把数据写入文件或者把数据传递给渲染引擎进行显示,这样的一种结构在VTK里就称为可视化管线。数据对象(Data Object) ,处理对象(Process Object)和数据流方向(Direction of Data Flow)是可视化管线的三个基本要素。—《VTK图形图像开发进阶》
分析: 根据上述定义,可见vtk可视化管线可基本分为三部分(缺一不可):

  • 数据源或数据集
  • 数据处理
  • 数据写入文件或进入渲染引擎渲染

因此,vtk可视化管线其流程为:
vtk可视化管线

下面对vtk可视化管线三部分分别进行介绍与解读,最后对以上可视化管线流程图进行更新。下文包括个人理解,欢迎指正与批评。

2. 数据集准备

数据对象是数据的集合(数据集),数据对象表现的数据是可以被可视化管线处理的数据,只有当数据对象被组织成一种结构后,才能被VTK提供的可视化。而数据集必须具有的结构包括:① 组织结构;② 属性数据

数据集结构组成
其中,组织结构包括几何结构与拓扑结构两部分,其中几何结构可理解为物体特征点的坐标分布,如三角形的三个顶点坐标构成了其几何结构,而三个顶点之间的连接关系构成了其拓扑结构;属性数据可表示物体组织结构的信息,如三维激光点云各点的能量值、我国各市GDP,可用颜色赋予其高低的概念,当然能量与GDP只是标量,属性数据海包括向量与张量等几大类

3. 数据处理

有时通过文件读入的数据并非我们想要的数据集形式,例如我们需要显示三角网,而读入的是点云,因此需要对输入的点云进行一定的处理,构建点云数据集新的拓扑结构。这个过程称之为Filter,即过滤或处理。
Filter演示
上图中,Source是指用于创建数据或读取数据,Filter的输出可以直接写入文件,或者经 Mapper变换后传入渲染引擎进行渲染、显示,结束可视化管线Source、Filter与Mapper共同组成数据对象处理

4. 渲染引擎

《VTK图形图像开发进阶》一书中对渲染引擎有以下比喻:整个剧院就好比 vtk程序的渲染窗口(vtkRenderWindow)舞台就相当于渲染场景( vtkRenderer);而那些演员就是程序中的 Actor(vtkActor)。

vtkActor:该类派生自 vtkProp类。数据要在场景中渲染时,不是直接把数据加入渲染场景,而是以 vtkProp的形式存在于渲染场景中,Prop依赖于两个对象:一个是 Mapper ( vtkMapper)对象,负责存放数据,另一个是属性((vtkProperty)对象,负责控制颜色、不透明度等参数。

vtkRenderer:负责管理场景的渲染过程。组成场景的对象包括 Prop,照相机(vtkCamera)和光照(vtkLight)。

vtkRenderWindow:将操作系统与VTK 渲染引擎连接到一起。

5. 案例(点云与柱体显示)

5.1 点云数据读取

参照文章:https://blog.csdn.net/weixin_42261213/article/details/102054922

	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();//渲染窗口

	//---1. 读入点集
	FILE*fp = NULL; fp = fopen("Test2.txt", "r");
	if (!fp)
	{

		printf("Open file failed!!\n");
		int m;
		cin >> m;
		exit(0);
	}
	double x = 0, y = 0, z = 0;
	int i = 0;
	while (!feof(fp))
	{
		fscanf(fp, "%lf %lf %lf", &x, &y, &z);
		m_Points->InsertPoint(i, x, y, z);		// 加入点信息,构建几何结构
		vertices->InsertNextCell(1);		
		vertices->InsertCellPoint(i);          // 表示点云索引顺序,构建拓扑结构
		i++;
	}
	fclose(fp);

	//---2.点集转换为图元并加入渲染引擎显示
	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(8);
	
	ren1->AddActor(pointActor);
	ren1->SetBackground(0, 0, 0);

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

	renWin->Render();

该方法读取与显示点云,构件了polyData,然后转换为pointMapper(数据对象处理),然后经渲染引擎进行显示。

5.2 柱体模型

参考: https://gitlab.kitware.com/vtk/vtk/blob/73465690278158b9e89661cd6aed26bead781378/Examples/Rendering/Cxx/Cylinder.cxx

 // ---1.准备柱体数据
 vtkCylinderSource *cylinder = vtkCylinderSource::New();
  cylinder->SetResolution(8);
// ---2.构建图元
  vtkPolyDataMapper *cylinderMapper = vtkPolyDataMapper::New();
  cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
// ---3.加入渲染引擎与交互
  vtkActor *cylinderActor = vtkActor::New();
  cylinderActor->SetMapper(cylinderMapper);
  cylinderActor->GetProperty()->SetColor(1.0000, 0.3882, 0.2784);
  cylinderActor->RotateX(30.0);
  cylinderActor->RotateY(-45.0);

  vtkRenderer *ren1 = vtkRenderer::New();
  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->AddRenderer(ren1);
  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);
  
  ren1->AddActor(cylinderActor);
  ren1->SetBackground(0.1, 0.2, 0.4);
  renWin->SetSize(200, 200);

  ren1->ResetCamera();
  ren1->GetActiveCamera()->Zoom(1.5);
  renWin->Render();

  iren->Start();
  
  // ---4.内存释放
  cylinder->Delete();
  cylinderMapper->Delete();
  cylinderActor->Delete();
  ren1->Delete();
  renWin->Delete();
  iren->Delete();

根据https://vtk.org/doc/nightly/html/classvtkCylinderSource.html中继承关系,可见类vtkCylinderSource继承于类vtkAlgorithm,vtkCylinderSource->vtkPolyDataAlgorithm->vtkAlgorithm->vtkObject,如下图。而vtkAlgorithm 是 VTK 中所有源、过滤器和接收器的超类。 它定义了一个用于执行数据处理算法的通用接口。 管道连接与输入和输出端口相关联,输入和输出端口与通过连接的数据类型无关。
在这里插入图片描述由官方类继承查询:https://vtk.org/doc/nightly/html/classes.html,可见类vtkPolyDataMapper的Function SetInputConnection()参数与类vtkCylinderSource的Function GetOutputPort()返回值一致,因此可直接构建图元。构建完图元即可进入渲染引擎并进行显示。
vtkAlgorithm输出端口
mapper输入链接

6. 总结

最后,以流程图形式回顾一下三步过程,也算最后总结。
在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在ROS中,可以使用RViz来可视化点云数据。但是,如果您需要更高级的可视化功能,可以使用VTK库来创建自定义的点云可视化程序。下面是一个基本的VTK点云可视化程序: ```cpp #include <vtkSmartPointer.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderWindow.h> #include <vtkRenderer.h> #include <vtkRenderWindowInteractor.h> #include <vtkPLYReader.h> #include <vtkPoints.h> #include <vtkPointData.h> #include <vtkVertexGlyphFilter.h> int main(int argc, char* argv[]) { // 初始ROS节点 ros::init(argc, argv, "ros_vtk_point_cloud_visualization"); ros::NodeHandle nh; // 读取点云数据 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile<pcl::PointXYZ> ("input.pcd", *cloud); // 创建VTK点云数据 vtkSmartPointer<vtkPoints> vtkPoints = vtkSmartPointer<vtkPoints>::New(); for (size_t i = 0; i < cloud->points.size(); i++) { vtkPoints->InsertNextPoint(cloud->points[i].x, cloud->points[i].y, cloud->points[i].z); } // 创建VTK点云数据的Actor vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); polyData->SetPoints(vtkPoints); vtkSmartPointer<vtkVertexGlyphFilter> vertexGlyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New(); vertexGlyphFilter->SetInputData(polyData); vertexGlyphFilter->Update(); vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection(vertexGlyphFilter->GetOutputPort()); vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); // 创建渲染器和渲染窗口 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New(); renWin->AddRenderer(renderer); renWin->SetSize(640, 480); // 创建交互器 vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor->SetRenderWindow(renWin); // 开始渲染 interactor->Start(); return 0; } ``` 在上面的程序中,我们首先使用ROS读取了点云数据,然后创建了一个VTK点云数据,并将其渲染到一个窗口中。请注意,上面的程序只是一个基本的模板,您可以根据自己的需要进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值