ITK&&VTK读取DICOM数据并渲染

时间:2021-11-29 13:23:56

1.新建项目

附加包含目录,附加库目录添加ITK和VTK的include以及lib文件夹路径,附加依赖项添加 Visual Studio 2013编译ITK4.10.1以及 Visual Studio 2013编译VTK7.1.0中列出的.lib文件,由于ITK和VTK都是x64编译的,因此项目需改成Debug/x64配置。
属性中的C/C++下的代码生成中的运行库需要修改成多线程调试,否则ITK会报错(不记得编译ITK的时候选了这项,只有DCMTK的时候改成了MDd模式,不知为何ITK也需要修改)。
链接器->调试中的生成调试信息选为是。

2.ITK&&VTK读取DICOM数据

虽然VTK有自带的读取DICOM数据的类,vtkDICOMImageReader,但是该类支持的DICOM数据类型并不多,在测试阶段只能完整读取MR类型的数据,而CT数据读取会出错。
DCMTK能够完整读取任何DICOM的数据头等部分,但是暂未找出如何将数据传递给VTK。
ITK通过编译模块ITKVTKGlue,能够使用itkImageToVTKImageFilter.h将ITK读取的图像数据传递给VTK,其中ITK的数据读取部分如下:
	/* ITK */
typedef signed short InputPixelType;//dicom 对应数据类型
const unsigned int InputDimension = 2;
typedef itk::Image< InputPixelType, InputDimension > InputImageType;

typedef itk::ImageSeriesReader< InputImageType > ReaderType;//定义图像数据读取

ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName("D:/VTKCode/Data/IM-0001.dcm");//读取文件路径

typedef itk::GDCMImageIO ImageIOType;//GDCMImageIO读DICOM
ImageIOType::Pointer gdcmImageIO = ImageIOType::New();
//关联GDCMImageIO类后,DICOM数据信息就读入内存,ITK能获取更加全面的信息(比起VTK)
reader->SetImageIO(gdcmImageIO);//之后可以用gdcmImageIO获取读到的DICOM数据中的各字段信息

try
{
reader->Update();//读取数据
}
catch (itk::ExceptionObject &ex)
{
std::cout << ex << std::endl;
system("pause");
return EXIT_FAILURE;
}


数据读取之后传递给ImageToVTKImageFilter对象:
	/* ITK TO VTK */
typedef itk::ImageToVTKImageFilter< InputImageType> itkTovtkFilterType;
itkTovtkFilterType::Pointer itkTovtkImageFilter = itkTovtkFilterType::New();
itkTovtkImageFilter->SetInput(reader->GetOutput());//设置图像数据从ITK转向VTK
itkTovtkImageFilter->Update();
itkTovtkImageFilter将ITK读取的图像数据转换成vtkImageData并传给VTK的渲染模块:
	/* vtkImageActor在3D场景下渲染图像 */
vtkSmartPointer<vtkImageActor> actor = vtkImageActor::New();
actor->SetInputData(itkTovtkImageFilter->GetOutput());
actor->InterpolateOff();
actor->Update();
之后就是VTK渲染的一般步骤:
	vtkSmartPointer<vtkRenderer> render = vtkRenderer::New();
render->AddActor(actor);

vtkSmartPointer<vtkRenderWindow> window = vtkRenderWindow::New();
window->SetSize(800, 600);
window->AddRenderer(render);

vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkRenderWindowInteractor::New();
interactor->SetRenderWindow(window);

interactor->Initialize();
interactor->Start();
渲染结果如下图所示:
ITK&&VTK读取DICOM数据并渲染