1. 问题概述
在使用VTK读取DICOM图像时有一个常见问题:通过vtkDICOMReader
类读取的图像,与DICOM文件中记录的"ImagePositionPatient"值不一致,导致图像在三维空间中的定位出现偏差。
这一问题在与MITK等医学图像处理框架进行数据交互时尤为明显,MITK是直接读取"ImagePositionPatient"值自动变换的,如果有同时使用VTK和MITK读取、处理、对齐图像的场景,那这个偏差就很致命。
2. 解决问题
该问题的本质原因是VTK默认对DICOM图像进行了行序(ROW Order)的自动调整:
- DICOM标准存储:采用从上到下(Top-Down)的存储方式
- 显示系统惯例:使用从下到上(Bottom-Up)的显示方式
- VTK默认行为:
vtkDICOMReader
默认启用BottomUp
模式,会自动翻转图像行序
那么只要调用SetMemoryRowOrderToFileNative()
方法强制与文件中对齐即可。
3. SetMemoryRowOrder()
详细介绍
VTK在vtkDICOMReader
类中提供了SetMemoryRowOrder()
方法来控制这一行为。
-
使用介绍
VTK提供了三种行序模式,分别为FileNative、TopDown、BottomUp。
且提供了多种设置方式,可参照源码如下:
//! Enumeration for top-down vs. bottom-up ordering. enum RowOrder { FileNative, TopDown, BottomUp }; //@{ //! Set the ordering of the image rows in memory. /*! * If the order is BottomUp (which is the default) then * the images will be flipped when they are read from disk. * The native orientation of DICOM images is top-to-bottom. */ void SetMemoryRowOrder(int order); void SetMemoryRowOrderToFileNative() { this->SetMemoryRowOrder(FileNative); } void SetMemoryRowOrderToTopDown() { this->SetMemoryRowOrder(TopDown); } void SetMemoryRowOrderToBottomUp() { this->SetMemoryRowOrder(BottomUp); } int GetMemoryRowOrder() { return this->MemoryRowOrder; } const char *GetMemoryRowOrderAsString();
-
三种行序模式对比
方法 行序模式 行为特点 适用场景 SetMemoryRowOrderToFileNative()
文件原生 保持DICOM原始行序 需要精确几何信息时 SetMemoryRowOrderToTopDown()
从上到下 强制Top-Down存储 特殊需求场景 SetMemoryRowOrderToBottomUp()
从下到上 VTK默认模式 直接显示场景 -
使用示例
vtkNew
reader; reader->SetDirectoryName(dicomDir); // 关键设置:保持DICOM原始行序 reader->SetMemoryRowOrderToFileNative(); // reader->SetMemoryRowOrder(0); reader->Update(); vtkImageData* image = reader->GetOutput();