使用 ITK 和 VTK 进行 CT 脑血管分割

CT Brain vessel segmentation using ITK and VTK

我正在做我自己的项目,其中我需要分割 脑血管 CT dicom 图像。我有 2 套 DICOM 图像。

1)CT dicom images of head with DSA (888 slices)
2)CT dicom images of head without DSA(same 888 slices),

所以我使用 vtkDICOMImageReader 分别阅读了这两个系列,并使用 vtkImageMathematics 减去这两个系列,并将结果存储在变量 mat 中,然后将其复制到 vtkImageReslice * reslice; 然后我使用 VKImageToImageFilter *filter_toitkimage 将此 reslice 导入 ITK 并使用此代码:

using HessianFilterType = itk::HessianRecursiveGaussianImageFilter<ImageType>;
HessianFilterType::Pointer hessianFilter = HessianFilterType::New();
hessianFilter->SetInput(filter_toitkimage->GetOutput());
hessianFilter->SetSigma(.6);

using VesselnessMeasureFilterType = itk::Hessian3DToVesselnessMeasureImageFilter<PixelType>;
VesselnessMeasureFilterType::Pointer vesselnessFilter = VesselnessMeasureFilterType::New();
vesselnessFilter->SetInput(hessianFilter->GetOutput());
vesselnessFilter->SetAlpha1(1);
vesselnessFilter->SetAlpha2(2); 

然后我使用 ImageToVTKImageFilter 将其转换回 VTK 并使用了这个:

       vtkSmartPointer<vtkGPUVolumeRayCastMapper> volumeMapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
volumeMapper->CroppingOff();
volumeMapper->RemoveAllInputs();
volumeMapper->SetInputData(conv->GetOutput());   //conv is the converted output   
volumeMapper->SetBlendModeToMaximumIntensity();
volumeMapper->AutoAdjustSampleDistancesOff();
volumeMapper->SetSampleDistance(.1);

volumeMapper->Update();

//-----volume color
vtkSmartPointer<vtkColorTransferFunction> volumeColor = vtkSmartPointer<vtkColorTransferFunction>::New();
volumeColor->RemoveAllPoints();

////-----volume color

//---air
volumeColor->AddRGBPoint(0, 0.0, 0.0, 0.0);
volumeColor->AddRGBPoint(220, 1, 1, 1);
//---skin
volumeColor->AddRGBPoint(250, 0, 0, 0);
volumeColor->AddRGBPoint(300, 0, 0, 0);
//---muscle
volumeColor->AddRGBPoint(800, 1, 1, 1);
volumeColor->AddRGBPoint(1000, 1, 1, 1);
volumeColor->AddRGBPoint(1320, 1, 1, 1);
//---soft bone
volumeColor->AddRGBPoint(1350, 0, 0, 0);
volumeColor->AddRGBPoint(1500, 0, 0, 0);
//---hard bone
volumeColor->AddRGBPoint(1550, 0, 0, 0);
volumeColor->AddRGBPoint(2000, 0, 0, 0);
//---hardest bone
volumeColor->AddRGBPoint(2050, 0, 0, 0);
volumeColor->AddRGBPoint(4096, 0, 0, 0);

vtkSmartPointer<vtkPiecewiseFunction> volumeScalarOpacity =
    vtkSmartPointer<vtkPiecewiseFunction>::New();
volumeScalarOpacity->AddPoint(0, 0.00);
volumeScalarOpacity->AddPoint(500, 0.15);
volumeScalarOpacity->AddPoint(1000, 0.15);
volumeScalarOpacity->AddPoint(1150, 0.85);

vtkSmartPointer<vtkPiecewiseFunction> volumeGradientOpacity =
    vtkSmartPointer<vtkPiecewiseFunction>::New();
volumeGradientOpacity->AddPoint(0, 0.0);
volumeGradientOpacity->AddPoint(90, 0.5);
volumeGradientOpacity->AddPoint(100, 1.0);

vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetColor(volumeColor);
    volumeProperty->SetScalarOpacity(volumeScalarOpacity);
    volumeProperty->SetGradientOpacity(volumeGradientOpacity);
    volumeProperty->SetInterpolationTypeToLinear();
    volumeProperty->ShadeOn();
    volumeProperty->SetAmbient(0.5);
    volumeProperty->SetDiffuse(0.3);
    volumeProperty->SetSpecular(0.3);

    vtkSmartPointer<vtkVolume> volume =vtkSmartPointer<vtkVolume>::New();
    volume->SetMapper(volumeMapper);
    volume->SetProperty(volumeProperty);
    renderer->AddVolume(volume);

我得到了肺部的血管但是我没有得到脑血管的清晰图像。有人可以给点建议吗?

您的传递函数采用 CT 强度,但血管滤波器的输出与它完全不同。它可能被标准化为 0.0-1.0 范围,或 0-255 范围,或其他范围。你应该检查一下。

DSA 已经意味着 "Digital subtraction angiography"。因此您不应该再次执行差异,它已经由扫描仪的软件完成。您正在查看的可能是差异的一些中间步骤,但除非您想进行新的 CT 重建,否则我建议直接使用 DSA 而不要再次进行差异。请注意,在 PACS 中,它可能被称为模态 "XA" 用于血管造影(您不应该寻找 "CT" 模态)。

每个系统都不同,这可能很复杂,但我也在处理大脑的血管造影数据,一开始这让我感到困惑,所以我认为值得一提。

对于血管检测的原型设计,我建议首先使用 3D Slicer。有一个名为 VMTK 的库的插件实现了 vesselness 过滤器,但您也可以添加其他插件,尤其是用于获取所有 ITK 过滤器的插件。我认为使用它作为起点更容易,在实施之前尝试一些东西。

如果你真的想自己计算 DSA,在这种情况下你需要有 2 个 CTs 有和没有造影剂(但不是 DSAs),你必须确保在做差异之前两个体积都被完美地配准。如果您发现未对齐,我建议您使用简单的 elastix 框架来注册您的图像。

最后,vesselness 过滤器的临界点实际上是您 select 与 sigma 的频率。这基本上定义了容器的大小。在 VTMK 实现中,您可以有不同的频率,因此您可以设置开始和停止 sigma。在 Slicer 中,如果您在容器周围输入一些基准点,您甚至可以使用一个插件来找到正确的 sigma。所以如果你能看到一些血管但看不到其他血管,我建议将这个 sigma=0.6 降低到更低的值(假设血管显示比肺血管小)

希望对您有所帮助!