第05章 17 Contour 过滤器介绍与例子

news/2025/2/1 19:17:14 标签: 信息可视化, VTK

vtkContourFilter 是 VTK(Visualization Toolkit)中的一个关键类,用于从输入数据生成等值线或等值面。它是基于阈值的过滤器,可以从标量字段中提取等值线或等值面。vtkContourFilter 的核心功能是根据用户指定的值生成等值线或等值面,并将其表示为多边形网格。

vtkContourFilter 的主要功能

  • 等值线/等值面生成:根据用户指定的等值(通常是标量值)生成等值线或等值面。
  • 多重等值线/等值面:可以同时生成多个等值线或等值面。
  • 支持多种数据类型:可以处理结构化网格、非结构化网格、点云等多种数据类型。
  • 插值:在生成等值线/等值面时,支持插值操作,以确保生成的表面平滑。

vtkContourFilter 的常用方法

  • SetValue(int index, double value):设置第index个等值线的值为value
  • GenerateValues(int numContours, double range[2]):自动生成numContours个等值线,范围在range之间。
  • SetInputData(vtkDataObject input):设置输入数据。
  • Update():更新过滤器并生成输出数据。

vtkContourFilter 的衍生类

vtkContourFilter 是 VTK 中用于生成等值线/等值面的基础类。根据不同的应用场景和需求,VTK 提供了一些专门化的衍生类,这些类继承自 vtkContourFilter,并在其基础上进行了功能扩展或优化。以下是一些常见的 vtkContourFilter 衍生类:

1. vtkMarchingCubes
  • 用途:用于从体积数据(如 CT 或 MRI 扫描数据)中提取等值面。
  • 特点:使用 marching cubes 算法,能够生成高质量的多边形表面。
  • 应用场景:医学图像处理、三维重建。
2. vtkDiscreteMarchingCubes
  • 用途:专门用于处理离散数据(如标签映射数据),生成具有明确标签的等值面。
  • 特点:生成的等值面具有清晰的边界,适用于分割结果的可视化。
  • 应用场景:医学图像分割、地质数据可视化。
3. vtkFlyingEdges3D
  • 用途:用于从三维体积数据中提取等值面。
  • 特点:使用 flying edges 算法,相比于 marching cubes,计算速度更快,生成的表面质量更高。
  • 应用场景:三维体积数据的实时渲染、体绘制。
4. vtkBandedPolyDataContourFilter
  • 用途:用于生成带状等值线。
  • 特点:可以生成多个连续的等值线,通常用于数据的可视化。
  • 应用场景:气象数据中的等压线、地形数据中的等高线。
5. vtkSynchronizedTemplates3D
  • 用途:用于从三维体积数据中生成等值面。
  • 特点:使用同步模板算法,可以生成平滑的等值面。
  • 应用场景:三维体积数据的可视化。
6. vtkSynchronizedTemplatesCutter3D
  • 用途:类似于 vtkSynchronizedTemplates3D,但支持通过其他几何体进行切割。
  • 特点:可以生成与特定几何体相交的等值面。
  • 应用场景:定制化的三维数据可视化。

总结

vtkContourFilter 及其衍生类是 VTK 中用于生成等值线/等值面的核心工具。根据不同的应用场景和需求,用户可以选择合适的类来生成高质量的等值面。例如,vtkMarchingCubes 适用于医学图像中的三维重建,而 vtkFlyingEdges3D 则更适合实时渲染和体绘制。

1. vtkContourFilter

#include <vtkSmartPointer.h>
#include <vtkMarchingCubes.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSampleFunction.h>
#include <vtkSphere.h>
#include <vtkContourFilter.h>

int main(int, char *[])
{
  vtkSmartPointer<vtkSphere> sphere = vtkSmartPointer<vtkSphere>::New();
  sphere->SetCenter(0.0, 0.0, 0.0);
  sphere->SetRadius(1.0);

  vtkSmartPointer<vtkSampleFunction> sample = vtkSmartPointer<vtkSampleFunction>::New();
  sample->SetImplicitFunction(sphere);
  sample->SetModelBounds(-2.5, 2.5, -2.5, 2.5, -2.5, 2.5);
  sample->SetSampleDimensions(50, 50, 50);
  sample->SetCapping(true);
  sample->SetCapValue(100);
  sample->Update();

  vtkSmartPointer<vtkContourFilter> contourFilter = vtkSmartPointer<vtkContourFilter>::New();
  contourFilter->SetInputConnection(sample->GetOutputPort());
  contourFilter->GenerateValues(5, 0.0, 1.0); // 生成5个等值面
  contourFilter->Update();

  vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();

  vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(contourFilter->GetOutputPort());
  mapper->ScalarVisibilityOff();

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());

  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());

  renderWindow->Render();
  renderWindowInteractor->Start();

  return 0;
}

解释

  1. 生成隐式几何体:使用 vtkSphere 生成一个球体。
  2. 采样函数:使用 vtkSampleFunction 对球体进行采样,生成一个标量场。
  3. 等值面生成:使用 vtkContourFilter 从采样结果中提取多个等值面。
  4. 渲染:使用 VTK 的渲染管道将等值面显示出来。

2. vtkMarchingCubes

#include <vtkSmartPointer.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSampleFunction.h>
#include <vtkSphere.h>
#include <vtkMarchingCubes.h>

int main(int, char *[])
{
  vtkSmartPointer<vtkSphere> sphere = vtkSmartPointer<vtkSphere>::New();
  sphere->SetCenter(0.0, 0.0, 0.0);
  sphere->SetRadius(1.0);

  vtkSmartPointer<vtkSampleFunction> sample = vtkSmartPointer<vtkSampleFunction>::New();
  sample->SetImplicitFunction(sphere);
  sample->SetModelBounds(-2.5, 2.5, -2.5, 2.5, -2.5, 2.5);
  sample->SetSampleDimensions(50, 50, 50);
  sample->SetCapping(true);
  sample->SetCapValue(100);
  sample->Update();

  vtkSmartPointer<vtkMarchingCubes> marchingCubes = vtkSmartPointer<vtkMarchingCubes>::New();
  marchingCubes->SetInputConnection(sample->GetOutputPort());
  marchingCubes->SetValue(0, 0.0); // 生成单个等值面
  marchingCubes->Update();

  vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();

  vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(marchingCubes->GetOutputPort());
  mapper->ScalarVisibilityOff();

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());

  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());

  renderWindow->Render();
  renderWindowInteractor->Start();

  return 0;
}

解释

  1. 生成隐式几何体:使用 vtkSphere 生成一个球体。
  2. 采样函数:使用 vtkSampleFunction 对球体进行采样,生成一个标量场。
  3. 等值面生成:使用 vtkMarchingCubes 从采样结果中提取单个等值面。
  4. 渲染:使用 VTK 的渲染管道将等值面显示出来。

3. vtkDiscreteMarchingCubes

#include <vtkSmartPointer.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSampleFunction.h>
#include <vtkSphere.h>
#include <vtkDiscreteMarchingCubes.h>

int main(int, char *[])
{
  vtkSmartPointer<vtkSphere> sphere = vtkSmartPointer<vtkSphere>::New();
  sphere->SetCenter(0.0, 0.0, 0.0);
  sphere->SetRadius(1.0);

  vtkSmartPointer<vtkSampleFunction> sample = vtkSmartPointer<vtkSampleFunction>::New();
  sample->SetImplicitFunction(sphere);
  sample->SetModelBounds(-2.5, 2.5, -2.5, 2.5, -2.5, 2.5);
  sample->SetSampleDimensions(50, 50, 50);
  sample->SetCapping(true);
  sample->SetCapValue(100);
  sample->Update();

  vtkSmartPointer<vtkDiscreteMarchingCubes> discreteMarchingCubes = vtkSmartPointer<vtkDiscreteMarchingCubes>::New();
  discreteMarchingCubes->SetInputConnection(sample->GetOutputPort());
  discreteMarchingCubes->SetValue(0, 100); // 生成单个等值面
  discreteMarchingCubes->Update();

  vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();

  vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(discreteMarchingCubes->GetOutputPort());
  mapper->ScalarVisibilityOff();

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());

  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());

  renderWindow->Render();
  renderWindowInteractor->Start();

  return 0;
}

解释

  1. 生成隐式几何体:使用 vtkSphere 生成一个球体。
  2. 采样函数:使用 vtkSampleFunction 对球体进行采样,生成一个标量场。
  3. 等值面生成:使用 vtkDiscreteMarchingCubes 从采样结果中提取单个离散等值面。
  4. 渲染:使用 VTK 的渲染管道将等值面显示出来。

4. vtkFlyingEdges3D

#include <vtkSmartPointer.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSampleFunction.h>
#include <vtkSphere.h>
#include <vtkFlyingEdges3D.h>

int main(int, char *[])
{
  vtkSmartPointer<vtkSphere> sphere = vtkSmartPointer<vtkSphere>::New();
  sphere->SetCenter(0.0, 0.0, 0.0);
  sphere->SetRadius(1.0);

  vtkSmartPointer<vtkSampleFunction> sample = vtkSmartPointer<vtkSampleFunction>::New();
  sample->SetImplicitFunction(sphere);
  sample->SetModelBounds(-2.5, 2.5, -2.5, 2.5, -2.5, 2.5);
  sample->SetSampleDimensions(50, 50, 50);
  sample->SetCapping(true);
  sample->SetCapValue(100);
  sample->Update();

  vtkSmartPointer<vtkFlyingEdges3D> flyingEdges = vtkSmartPointer<vtkFlyingEdges3D>::New();
  flyingEdges->SetInputConnection(sample->GetOutputPort());
  flyingEdges->GenerateValues(5, 0.0, 1.0); // 生成5个等值面
  flyingEdges->Update();

  vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();

  vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(flyingEdges->GetOutputPort());
  mapper->ScalarVisibilityOff();

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());

  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());

  renderWindow->Render();
  renderWindowInteractor->Start();

  return 0;
}

解释

  1. 生成隐式几何体:使用 vtkSphere 生成一个球体。
  2. 采样函数:使用 vtkSampleFunction 对球体进行采样,生成一个标量场。
  3. 等值面生成:使用 vtkFlyingEdges3D 从采样结果中提取多个等值面。
  4. 渲染:使用 VTK 的渲染管道将等值面显示出来。

5. vtkBandedPolyDataContourFilter

#include <vtkSmartPointer.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSampleFunction.h>
#include <vtkSphere.h>
#include <vtkBandedPolyDataContourFilter.h>

int main(int, char *[])
{
  vtkSmartPointer<vtkSphere> sphere = vtkSmartPointer<vtkSphere>::New();
  sphere->SetCenter(0.0, 0.0, 0.0);
  sphere->SetRadius(1.0);

  vtkSmartPointer<vtkSampleFunction> sample = vtkSmartPointer<vtkSampleFunction>::New();
  sample->SetImplicitFunction(sphere);
  sample->SetModelBounds(-2.5, 2.5, -2.5, 2.5, -2.5, 2.5);
  sample->SetSampleDimensions(50, 50, 50);
  sample->SetCapping(true);
  sample->SetCapValue(100);
  sample->Update();

  vtkSmartPointer<vtkBandedPolyDataContourFilter> bandedContourFilter = vtkSmartPointer<vtkBandedPolyDataContourFilter>::New();
  bandedContourFilter->SetInputConnection(sample->GetOutputPort());
  bandedContourFilter->GenerateValues(5, 0.0, 1.0); // 生成5个带状等值线
  bandedContourFilter->Update();

  vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();

  vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(bandedContourFilter->GetOutputPort());
  mapper->ScalarVisibilityOff();

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());

  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());

  renderWindow->Render();
  renderWindowInteractor->Start();

  return 0;
}

解释

  1. 生成隐式几何体:使用 vtkSphere 生成一个球体。
  2. 采样函数:使用 vtkSampleFunction 对球体进行采样,生成一个标量场。
  3. 等值线生成:使用 vtkBandedPolyDataContourFilter 从采样结果中提取多个带状等值线。
  4. 渲染:使用 VTK 的渲染管道将等值线显示出来。

6. vtkSynchronizedTemplates3D

#include <vtkSmartPointer.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSampleFunction.h>
#include <vtkSphere.h>
#include <vtkSynchronizedTemplates3D.h>

int main(int, char *[])
{
  vtkSmartPointer<vtkSphere> sphere = vtkSmartPointer<vtkSphere>::New();
  sphere->SetCenter(0.0, 0.0, 0.0);
  sphere->SetRadius(1.0);

  vtkSmartPointer<vtkSampleFunction> sample = vtkSmartPointer<vtkSampleFunction>::New();
  sample->SetImplicitFunction(sphere);
  sample->SetModelBounds(-2.5, 2.5, -2.5, 2.5, -2.5, 2.5);
  sample->SetSampleDimensions(50, 50, 50);
  sample->SetCapping(true);
  sample->SetCapValue(100);
  sample->Update();

  vtkSmartPointer<vtkSynchronizedTemplates3D> syncTemplates = vtkSmartPointer<vtkSynchronizedTemplates3D>::New();
  syncTemplates->SetInputConnection(sample->GetOutputPort());
  syncTemplates->SetValue(0, 0.0); // 生成单个等值面
  syncTemplates->Update();

  vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New();

  vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(syncTemplates->GetOutputPort());
  mapper->ScalarVisibilityOff();

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());

  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());

  renderWindow->Render();
  renderWindowInteractor->Start();

  return 0;
}

解释

  1. 生成隐式几何体:使用 vtkSphere 生成一个球体。
  2. 采样函数:使用 vtkSampleFunction 对球体进行采样,生成一个标量场。
  3. 等值面生成:使用 vtkSynchronizedTemplates3D 从采样结果中提取单个等值面。
  4. 渲染:使用 VTK 的渲染管道将等值面显示出来。

这些示例代码展示了如何使用 vtkContourFilter 及其衍生类来生成等值线或等值面,并将其渲染出来。每个类都有其特定的应用场景和优势,可以根据具体需求选择合适的类。

 


http://www.niftyadmin.cn/n/5839530.html

相关文章

【玩转全栈】--创建一个自己的vue项目

目录 vue介绍 创建vue项目 vue页面介绍 element-plus组件库 启动项目 vue介绍 Vue.js 是一款轻量级、易于上手的前端 JavaScript 框架&#xff0c;旨在简化用户界面的开发。它采用了响应式数据绑定和组件化的设计理念&#xff0c;使得开发者可以通过声明式的方式轻松管理数据和…

前端力扣刷题 | 4:hot100之 子串

560. 和为K的子数组 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2 法一&#xff1a;暴力法 var subar…

android安卓用Rime

之前 [1] 在 iOS 配置用上自改方案 [2]&#xff0c;现想在安卓也用上。Rime 主页推荐了两个安卓平台支持 rime 的输入法 [3]&#xff1a; 同文 Tongwen Rime Input Method Editor&#xff0c;但在我的 Realme X2 Pro 上似乎有 bug&#xff1a;弹出的虚拟键盘只有几个 switcher…

2.1.2 Bayer阵列与去马赛克

文章目录 Bayer阵列去马赛克方法 Bayer阵列 由于传感器只能感受到光的强度&#xff0c;而无法感知颜色&#xff0c;所以需要用红、绿、蓝颜色的滤光片将光中的R、G、B亮度滤出&#xff0c;再通过R、G、B的组合得到各种色彩。Bayer阵列是使用一个传感器获得彩色图像的方法&#…

讯飞星火大模型API使用Python调用

本文仅仅为简单API调用&#xff0c;更多复杂使用方法请参见接口文档 先在科大讯飞开放平台注册账号&#xff0c;点击控制台&#xff0c;在我的应用中创建新应用&#xff0c;新应用的名称可以自定义&#xff0c;这里我写的是ai对话&#xff1a; 在这里我们使用的模型为Speak Ul…

deepseek+vscode自动化测试脚本生成

近几日Deepseek大火,我这里也尝试了一下,确实很强。而目前vscode的AI toolkit插件也已经集成了deepseek R1,这里就介绍下在vscode中利用deepseek帮助我们完成自动化测试脚本的实践分享 安装AI ToolKit并启用Deepseek 微软官方提供了一个针对AI辅助的插件,也就是 AI Toolk…

Qt事件处理:理解处理器、过滤器与事件系统

1. 事件 事件 是一个描述应用程序中、发生的某些事情的对象。 在 Qt 中&#xff0c;所有事件都继承自 QEvent &#xff0c;并且每个事件都有特定的标识符&#xff0c;如&#xff1a;Qt::MouseButtonPress 代表鼠标按下事件。 每个事件对象包含该事件的所有相关信息&#xff…

学习数据结构(5)单向链表的实现

&#xff08;1&#xff09;头部插入 &#xff08;2&#xff09;尾部删除 &#xff08;3&#xff09;头部删除 &#xff08;4&#xff09;查找 &#xff08;5&#xff09;在指定位置之前插入节点 &#xff08;6&#xff09;在指定位置之后插入节点 &#xff08;7&#xff09;删除…