VTK笔记-从vtkImageData中获取子vtkImageData数据-感兴趣区提取-vtkExtractVOI类

感兴趣区

  感兴趣区(Region of Interest,ROIs) 是图像的一部分,是数据集为特殊目的而选出的一些样本。它通过在图像上选择或使用诸如设定阈值(thresholding) 或者从其他文件(如矢量图转换获得等方法生成。感趣区可以是点、线、面等组成的不规则形状,通常用来作为图像分类的样本、掩膜、裁剪区或及其他操作。
  获取刚兴趣区的图像是图像处理中常见的操作。
  ROI的概念通常在许多应用领域中使用。例如,在机器视觉、图像处理中,ROI是从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区域;在医学成像中,为了测量肿瘤的大小,可以在图像中圈定肿瘤的边界作为ROI;为了评估心脏功能,可以在心动周期的不同阶段(例如,心脏收缩末期和心脏舒张末期)在图像上选择心内膜边界为ROI;在地理信息系统(GIS)中,ROI从可以2D地图中特殊的多边形区域。
  在Halcon、OpenCV、Matlab等机器视觉软件上常用到各种算子(Operator)和函数来求得感兴趣区域ROI,并进行图像的下一步处理。

vtkExtractVOI

  vtkExtractVOI类获取数据(体数据volume)中一部分和结构化点数据集中的一部分。
  vtkExtractVOI是一个Filter类,用于选择输入结构化点数据集的一部分,或对输入数据集进行子采样(选定的感兴趣的部分称为感兴趣的体积(VOI)。此Filter的输出是结构化的点数据集。过滤器处理任何拓扑维度(即点、线、图像或体积)的输入数据,并可以生成任何拓扑维度的输出数据。如果要使用此过滤器,则要设置VOI ivar,即指定数据中矩形区域的XYZ方向上最小/最大范围,也可以指定采样率对数据进行二次抽样。
  vtkExtractVOI类的典型应用是从一个卷中提取一个切片进行图像处理,对大的卷进行二次采样以减小数据量,或者用感兴趣的数据提取一个卷的区域。
VTK笔记-从vtkImageData中获取子vtkImageData数据-感兴趣区提取-vtkExtractVOI类_第1张图片

常用接口

设置感兴趣区范围

  VOI是6个itme的数组,分别是Xmin,Xmax,Ymin,Ymax,Zmin,Zmax的坐标;

int VOI[6];
vtkSetVector6Macro(VOI, int);
vtkGetVectorMacro(VOI, int, 6);

重采样

  在获取ROI图像后,可以对获取到的图像设定采样率,对图像进行重采样;可以对XYZ三个方向设置采样率;
  如果设置采样率大于1,则产生的VOI将是输入图像重新的二次抽样。例如,如果SampleRate=(2,2,2),则每隔一个点将被选择一次,结果是体积为原始大小的1/8。值为int类型,可以看出只能抽样,不能插值;默认值为(1,1,1);

int SampleRate[3];
vtkSetVector3Macro(SampleRate, int);
vtkGetVectorMacro(SampleRate, int, 3);

示例

  官方给出例子是:生成一幅曼德布罗特二维图像,使用vtkExtractVOI类从图像中获取X方向上[1/4,3/4]范围,Y方向上[1/4,3/4]范围形成的正方形ROI内的图像;

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(int, char*[])
{
  vtkNew<vtkNamedColors> colors;

  // Create an image
  vtkNew<vtkImageMandelbrotSource> source;
  source->Update();

  int* inputDims = source->GetOutput()->GetDimensions();
  vtkNew<vtkExtractVOI> extractVOI;
  extractVOI->SetInputConnection(source->GetOutputPort());
  extractVOI->SetVOI(inputDims[0] / 4., 3. * inputDims[0] / 4.,[1] / 4., 3. * inputDims[1] / 4., 0, 0);
  extractVOI->Update();

  vtkImageData* extracted = extractVOI->GetOutput();

  int* extractedDims = extracted->GetDimensions();
  vtkNew<vtkImageCast> inputCastFilter;
  inputCastFilter->SetInputConnection(source->GetOutputPort());
  inputCastFilter->SetOutputScalarTypeToUnsignedChar();
  inputCastFilter->Update();

  vtkNew<vtkImageCast> extractedCastFilter;
  extractedCastFilter->SetInputData(extracted);
  extractedCastFilter->SetOutputScalarTypeToUnsignedChar();
  extractedCastFilter->Update();

  // Create actors
  vtkNew<vtkImageActor> inputActor;
  inputActor->GetMapper()->SetInputConnection(inputCastFilter->GetOutputPort());

  vtkNew<vtkImageActor> extractedActor;
  extractedActor->GetMapper()->SetInputConnection(extractedCastFilter->GetOutputPort());

  // There will be one render window
  vtkNew<vtkRenderWindow> renderWindow;
  renderWindow->SetSize(600, 300);

  // And one interactor
  vtkNew<vtkRenderWindowInteractor> interactor;
  interactor->SetRenderWindow(renderWindow);

  // Define viewport ranges
  // (xmin, ymin, xmax, ymax)
  double leftViewport[4] = {0.0, 0.0, 0.5, 1.0};
  double rightViewport[4] = {0.5, 0.0, 1.0, 1.0};

  // Setup both renderers
  vtkNew<vtkRenderer> leftRenderer;
  renderWindow->AddRenderer(leftRenderer);
  leftRenderer->SetViewport(leftViewport);
  leftRenderer->SetBackground(colors->GetColor3d("Burlywood").GetData());

  vtkNew<vtkRenderer> rightRenderer;
  renderWindow->AddRenderer(rightRenderer);
  rightRenderer->SetViewport(rightViewport);
  rightRenderer->SetBackground(colors->GetColor3d("DarkTurquoise").GetData());

  leftRenderer->AddActor(inputActor);
  rightRenderer->AddActor(extractedActor);

  leftRenderer->ResetCamera();
  rightRenderer->ResetCamera();
  renderWindow->SetWindowName("ExtractVOI");
  renderWindow->Render();
  interactor->Start();

  return EXIT_SUCCESS;
}

  可以看到右侧图像为左侧图像中间1/2范围的图像的放大显示;
VTK笔记-从vtkImageData中获取子vtkImageData数据-感兴趣区提取-vtkExtractVOI类_第2张图片

  例子是二维的图像获取ROI图像,vtkExtractVOI不仅可以处理二维图像,也可以处理三维图像。输入是vtkImageData输出也是vtkImageData,方便对图像的处理和显示。

扩展应用

  如果需要在一系列的DICOM文件中,获取中间范围或者指定范围内的DICOM文件,该怎么做?
  思路:
  1.把所有得DICOM文件都读出信息来,每张DICOM对应一个<序号,z轴坐标>,然后按照z轴坐标排序,加载z轴坐标指定z范围内的dicom文件;后面的处理和正常的加载DICOM序列是一样的;
  2.把所有dicom用vtk生成vtkImageData,然后从vtkImageData的标量指针中拷贝出到指定范围内数据,生成子vtkImageData数据;
  3.使用vtkExtractVOI类指定ROI的范围,获取到结果vtkImageData。

参考资料

1.VTK修炼之道25:图像基本操作_图像子块提取(特征区域提取)
2.ExtractVOI
3.vtkExtractVOI Class Reference

你可能感兴趣的:(VTK笔记-图像相关)