计算机系统:Win8.1 (64 bit)
计算机内存:4GB
ITK:4.7.2(64 bit)
IDE:Qt Creator 3.0.1
Compiler:MSVC 2012 (64 bit)
1 背景
使用ITK处理3D数据时,有时候数据比较庞大(达到4GB以上),但是计算机内存毕竟有限(现在主要的笔记本内存为4GB)。那么,现在的问题是如何在有限的内存情况下,处理庞大的3D数据,正如参考资料[1][7]所描述的那样。
2 解决方案
2.1 32/64位系统
参考资料[8]指出,当使用32位系统进行实验时,提示无法分配大内存。当改用64位系统的时候,不再出现此问题。因此,计算机系统的选择很重要。
2.2 ITK的大数据处理策略
2.2.1 IO Streaming
针对大数据的问题,参考资料[2]介绍了ITK的IO Streaming机制,并给出相关例子。但是经过测试发现,关于IO Streaming的实例的代码并不完整,完整的代码可见参考资料[6]。关于IO Streaming更详细的原理介绍,可见参考资料[5]的第8.3小节Streaming Large Data。
IO Streaming的主要思想是,将大数据分块处理,例如:
typedef itk::ImageFileWriter< ToVectorImageAdaptorType > ImageWriterType; ImageWriterType::Pointer writer = ImageWriterType::New(); writer->SetNumberOfStreamDivisions( 10 ); // 将数据分成10个小块进行处理上述代码片通过ImageFileWriter类的SetNumberOfStreamDivisions()函数实现分块处理。
注意:虽然参考资料[2]中提到,ImageSeriesWriter也会实现对IO Streaming的支持。然而,直到ITK4.7.2版本为止,ImageSeriesWriter还没有SetNumberOfStreamDivisions() 函数,也就是说它还不能通过分块处理来达到处理大数据的目的[10]。
2.2.2 Pasting
参考资料[2]还介绍了另外一种方法:pasting。由于文中的实例不完整,完整的例子可见参考资料[9]。Pasting处理的主要思想是,只处理特定的部分,例如下面的代码片段所示:
typedef itk::ImageFileWriter< ToVectorImageAdaptorType > ImageWriterType; ImageWriterType::Pointer writer = ImageWriterType::New(); writer->SetNumberOfStreamDivisions( 10 ); // 分10块处理 writer->SetIORegion( halfIO ); // 设置处理的区域上述代码片通过ImageFileWriter类的SetIORegion()函数实现区域处理;另外,上述的代码片段不仅实用了Pasting方法,还使用了2.2.1小节所说的IO Streaming方法。由此可见,它们两者可以结合使用[2]。
注意:ImageSeriesWriter并没有SetIORegion()函数,也就是说它不能通过区域处理来达到处理大数据的目的。
3 StreamingImageFilter
由于目前ImageSeriesWriter并不支持SetNumberOfStreamDivisions(),可以借助StreamingImageFilter来达到这个目的:
typedef itk::StreamingImageFilter< UCharImageType3D, UCharImageType3D > StreamingFilterType; StreamingFilterType::Pointer streamingFilter = StreamingFilterType::New(); streamingFilter->SetInput( caster->GetOutput() ); streamingFilter->SetNumberOfStreamDivisions( 200 ); // 对caster的输入分成200片 seriesWriter->SetInput( streamingFilter->GetOutput() );4 总结
其实不管是第2章介绍的方法还是第3章的折中措施,效果都不理想(导致电脑运行非常的慢,而且内存的消耗并没有减少!)。因此,最好的方法还是增加计算机的内存!
参考资料
[1]ImageSeriesReader memory allocation for large datasets
[2]IO Streaming in ITK
[3]itk smartpoint 以及内存管理研究
[4]Problem reading a big nifti volume
[5]InsightSoftwareGuide-Book1-4.7.1.pdf
[6]Examples/IO/VisibleHumanStreamReadWrite.cxx
[7][ITK-users] Connected Threshold Filter crashes but only for large images
[8]Error of failed to allocate memory for image for large data set
[9]Examples/IO/VisibleHumanPasteWrite.cxx
[10][ITK-users] why can the ImageSeriesWriter not stream?