VTK-等值面提取

等值面

等值面(线)提取是一种常用的可视化技术,常应用于医学、地质、气象等领域。例如,在医学图像处理中,由于CT、MRI等图像分辨率越来越高,虽然体绘制技术可以清晰地对数据内部结构进行可视化,但是其计算量和效率却制约了其使用。此时可通过等值面提取技术,仅提取感兴趣的一个或者几个组织轮廓,并生成网格模型以供后续的处理和研究。
根据数据类型的不同,VTK中提供了多个等值面提取类,其类图如图所示


VTK中的等值面提取算法多基于MarchingCube算法来实现。MarchingCube是经典的移动立方体等值面提取算法。该算法是由W.E.Lorenson和H.E.Cline在1987年提出的。由于这一方法原理简单,易于实现,目前已经得到了较为广泛的应用,称为三维数据等值面生成的经典算法。等值面提取类根据数据类型的不同而有所侧重。

  • vtkImageMarchingCubes:主要处理三维图像数据
  • vtkMarchingCubes:主要针对规则体数据生成等值面
  • vtkMarchingSquares:则是针对二维规则网格数据生成等值线
  • vtkMarchingContourFilter:可以接受任何类型的数据,其内部根据数据不同生成不同的算法对象实现等值面/线的提取,具有较高的效率
  • vtkContourFilter:则是一个更加通用的等值面提取类,其可以接受任意的数据类型生成等值线或等值面。
  • vtkDiscreteMarchingCubes 继承自vtkMarchingCubes,主要针对Label图像,比如利用图像分割算法对医学图像进行分割后得到含有不同Label值的数据,每个Label对应一个组织,通过想要得到其中一个或者几个组织的轮廓模型,则可以考虑使用该类。
  • vtkDiscreteFlyingEdges3D
    和vtkDiscreteMarchingCubes 功能类似。但产生的结果不同。此过滤器可以生成输出法线,并且每个标记区域与相邻区域完全断开连接(重合点不会合并)。这两种算法都会在具有不同分割标签的顶点之间的中间点处插入边。 此类已使用vtkSMPTools 进行线程化。使用 TBB 或其他非顺序类型(在 CMake 变量VTK_SMP_IMPLEMENTATION_TYPE中设置)可以显著提高性能
    • 类图如下

如何使用vtkDiscreteFlyingEdges3D

 // Run marching cubes

#if VTK_MAJOR_VERSION >= 9 || (VTK_MAJOR_VERSION >= 8 && VTK_MINOR_VERSION >= 2)
  // Normals computation in vtkDiscreteFlyingEdges3D is faster than computing normals in a subsequent
  // vtkPolyDataNormals filter. However, if smoothing step is applied after vtkDiscreteFlyingEdges3D then
  // computing normals after smoothing provides smoother surfaces.
  bool marchingCubesComputesSurfaceNormals = (computeSurfaceNormals > 0) && (smoothingFactor <= 0);

  vtkSmartPointer<vtkDiscreteFlyingEdges3D> marchingCubes = vtkSmartPointer<vtkDiscreteFlyingEdges3D>::New();
#else
  bool marchingCubesComputesSurfaceNormals = false;
  vtkSmartPointer<vtkDiscreteMarchingCubes> marchingCubes = vtkSmartPointer<vtkDiscreteMarchingCubes>::New();
#endif
  marchingCubes->SetInputData(binaryLabelmapWithIdentityGeometry);
  const int labelmapFillValue = binaryLabelmapWithIdentityGeometry->GetScalarRange()[1]; // max value
  marchingCubes->GenerateValues(1, labelmapFillValue, labelmapFillValue);
  marchingCubes->ComputeGradientsOff();
  marchingCubes->ComputeNormalsOff();
  marchingCubes->ComputeScalarsOff();
  marchingCubes->Update();

设置等值面的值

提取等值面时,最重要的是要设置等值面的数值,SetValue()函数用于设置等值面的值,其第一个参数表示等值面的序号,因此可以通过这个函数设置多个等值面值来提取多个等值面。另外我们也可以通过GenerateValues提取多个等值面。

  • SetValue

  /**
   * Set a particular contour value at contour number i. The index i ranges
   * between 0<=i<NumberOfContours.
   */
  void SetValue(int i, double value) {
    
    this->ContourValues->SetValue(i,value);}

//设置多个值
int valueIndex = 0;
  for (vtkIdType labelValue : labelValues)
  {
    
    
     marchingCubes->SetValue(valueIndex, labelValue);
     ++valueIndex;
  }

  • GenerateValues
   /* Generate numContours equally spaced contour values between specified
   * range. Contour values will include min/max range values.
   */
  void GenerateValues(int numContours, double range[2]) {
    
    
    this->ContourValues->GenerateValues(numContours, range);}

  /**
   * Generate numContours equally spaced contour values between specified
   * range. Contour values will include min/max range values.
   */
  void GenerateValues(int numContours, double rangeStart, double rangeEnd)
    {
    
    this->ContourValues->GenerateValues(numContours, rangeStart, rangeEnd);}

使用中遇到的问题

  • 提取的等值面渲染是黑色的
    • 关闭Scalars计算得以解决,如果计算Scalars 会导致mesh法线错误
 marchingCubes->ComputeScalarsOff();

猜你喜欢

转载自blog.csdn.net/BXD1314/article/details/122150335