Advertisement

VTK 读取、预处理、处理和可视化医学图像数据的过程

阅读量:

开发环境:

  1. Windows 11 家庭中文版
  2. Microsoft Visual Studio Community 2019
  3. VTK-9.3.0.rc0
  4. vtk-example

demo解决问题 : VTK 读取、预处理、处理和可视化医学图像数据的过程

图像读取和预处理:

  1. 程序使用 VTK 的图像阅读器vtkImageReader2Factory类读取作为命令行参数指定的输入图像文件。
    程序会对输入图像数据进行类型转换vtkImageCast,将标量类型转换为 double 类型,以便进一步处理。

  2. 对图像数据应用高斯平滑滤波器vtkImageGaussianSmooth,以减少噪音并创建更平滑的表示。

图像处理:

  1. 定义隐式球形函数vtkSphere并对其进行采样vtkSampleFunction(m2->SetImplicitFunction(m1);),以在图像数据中创建感兴趣的球形区域。
  2. 然后对采样球进行缩放vtkImageShiftScale(m3->SetInputConnection(m2->GetOutputPort());此处输入时上一步中的感兴趣输出),并使用乘法对原始图像数据进行数学运算vtkImageMathematics,从而有效地应用遮罩。

可视化:

  1. 程序使用 VTK 的图像演员类vtkImageActor为原始图像和滤波图像设置演员。
  2. 程序还定义了视口,用于在渲染窗口中显示原始图像和滤波图像。
  3. 程序还创建了两个独立的呈现器,用于在呈现窗口中并排显示原始图像和滤波图像。
  4. 然后,程序初始化呈现窗口,设置交互样式,并显示图像供用户交互。

以上演示了在一个应用程序中使用 VTK 读取、预处理、处理和可视化医学图像数据的过程。


prj name: AttachAttributes

复制代码
    #include <vtkImageActor.h>
    #include <vtkImageCast.h>
    #include <vtkImageGaussianSmooth.h>
    #include <vtkImageMapper3D.h>
    #include <vtkImageMathematics.h>
    #include <vtkImageProperty.h>
    #include <vtkImageReader2.h>
    #include <vtkImageReader2Factory.h>
    #include <vtkImageShiftScale.h>
    #include <vtkInteractorStyleImage.h>
    #include <vtkNamedColors.h>
    #include <vtkNew.h>
    #include <vtkRenderWindow.h>
    #include <vtkRenderWindowInteractor.h>
    #include <vtkRenderer.h>
    #include <vtkSampleFunction.h>
    #include <vtkSphere.h>
    
    /*
    这张核磁共振成像图显示了传感器位置可能导致的衰减。
    通过除以人工确定的衰减曲线,可以去除伪影。该直方图显示了伪影如何以标量值簇的形式隐藏信息。
    */
    int main(int argc, char* argv[])
    {
    
      // Verify input arguments.
      if (argc != 2)
      {
    std::cout << "Usage: " << argv[0]
              << " Filename e.g. AttenuationArtifact.pgm" << std::endl;
    return EXIT_FAILURE;
      }
    
      /*
      vtkImageReader2Factory: 该类用于在给定文件路径名的情况下创建 vtkImageReader2 对象。
      它会在所有可用的阅读器上调用 CanReadFile,直到其中一个返回 true。
      可用的阅读器列表来自三个地方。
      在该类的 InitializeReaders 函数中,内置的 VTK 类会被添加到列表中,用户可以调用 RegisterReader,或者用户可以创建一个具有 CreateObject 方法的 vtkObjectFactory,该方法会在给定字符串 "vtkImageReaderObject "时返回一个新的 vtkImageReader2 子类。
      这样,应用程序就可以通过插件 dll 或调用 RegisterReader 来扩展新的阅读器。
      当然,vtk 发行版中的所有阅读器都会自动可用。
      */
      // Read the image
      vtkNew<vtkImageReader2Factory> readerFactory;
      vtkSmartPointer<vtkImageReader2> reader;
      reader.TakeReference(readerFactory->CreateImageReader2(argv[1]));
      reader->SetFileName(argv[1]);
    
      //vtkImageCast 过滤器会转换输入类型以匹配图像处理管道中的输出类型。
      //如果输入已具有正确的类型,则该过滤器不会执行任何操作。要指定 "CastTo "类型,请使用 "SetOutputScalarType "方法。
      vtkNew<vtkImageCast> cast;
      cast->SetInputConnection(reader->GetOutputPort());
      cast->SetOutputScalarTypeToDouble();
    
      // Get rid of discrete scalars.
      vtkNew<vtkImageGaussianSmooth> smooth;
      smooth->SetInputConnection(cast->GetOutputPort());
      smooth->SetStandardDeviations(0.8, 0.8, 0);
    
      vtkNew<vtkSphere> m1;
      m1->SetCenter(310, 130, 0);
      m1->SetRadius(0);
    
      vtkNew<vtkSampleFunction> m2;
      m2->SetImplicitFunction(m1);
      m2->SetModelBounds(0, 264, 0, 264, 0, 1);
      m2->SetSampleDimensions(264, 264, 1);
    
      //使用vtkImageShiftScale可以对像素进行平移(添加一个常量值)和缩放(乘以一个标量)。
      //作为一种便利,这个类允许你设置输出标量类型,类似于vtkImageCast。这是因为平移缩放操作经常会转换数据类型。
      vtkNew<vtkImageShiftScale> m3;
      m3->SetInputConnection(m2->GetOutputPort());
      m3->SetScale(0.000095);
    
      //
      vtkNew<vtkImageMathematics> div;
      div->SetInputConnection(0, smooth->GetOutputPort());
      div->SetInputConnection(1, m3->GetOutputPort());
      div->SetOperationToMultiply();
    
      // Create actors.
      vtkNew<vtkNamedColors> colors;
    
      double colorWindow = 256.0;
      double colorLevel = 127.5;
      vtkNew<vtkImageActor> originalActor;
      originalActor->GetMapper()->SetInputConnection(cast->GetOutputPort());
      originalActor->GetProperty()->SetColorWindow(colorWindow);
      originalActor->GetProperty()->SetColorLevel(colorLevel);
    
      vtkNew<vtkImageActor> filteredActor;
      filteredActor->GetMapper()->SetInputConnection(div->GetOutputPort());
    
      // Define viewport ranges.
      // (xmin, ymin, xmax, ymax)
      double originalViewport[4] = {0.0, 0.0, 0.5, 1.0};
      double filteredViewport[4] = {0.5, 0.0, 1.0, 1.0};
    
      // Setup renderers.
      vtkNew<vtkRenderer> originalRenderer;
      originalRenderer->SetViewport(originalViewport);
      originalRenderer->AddActor(originalActor);
      originalRenderer->ResetCamera();
      originalRenderer->SetBackground(colors->GetColor3d("SlateGray").GetData());
    
      vtkNew<vtkRenderer> filteredRenderer;
      filteredRenderer->SetViewport(filteredViewport);
      filteredRenderer->AddActor(filteredActor);
      filteredRenderer->ResetCamera();
      filteredRenderer->SetBackground(
      colors->GetColor3d("LightSlateGray").GetData());
    
      vtkNew<vtkRenderWindow> renderWindow;
      renderWindow->SetSize(600, 300);
      renderWindow->AddRenderer(originalRenderer);
      renderWindow->AddRenderer(filteredRenderer);
      renderWindow->SetWindowName("Attenuation");
    
      vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
      vtkNew<vtkInteractorStyleImage> style;
    
      renderWindowInteractor->SetInteractorStyle(style);
    
      renderWindowInteractor->SetRenderWindow(renderWindow);
      renderWindow->Render();
      renderWindowInteractor->Initialize();
    
      renderWindowInteractor->Start();
    
      return EXIT_SUCCESS;
    }
    
    
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-17/wEaLuNkpJ40DQGf8Wes1hyzgimUd.png)

全部评论 (0)

还没有任何评论哟~