可靠的读写图像的类位于
数据处理通道的开始和结束
。这些类被认为是数据源(readers)
和数据槽
(writers)
。一般来说,它们作为滤波器被涉及了,虽然readers
没有输入通道,
writers
也没有输出通道。
itk::ImageFileReader类管理图像的读入,而itk::ImageFileWriter管理图像的写操作。两个类
对于任何文件格式都是独立
的。实际上低水平的读、写特殊文件格式的任务由一组
itk::ImageIO
类在后台执行。
执行读、写的第一步是要包含以下头文件:
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
这时,就像前面一样,必须决定被数据通道处理的表现图像的像素类型。注意:当读、写图像时,图像的像素类型不必与存储在文件中的像素类型一样。你对像素类型的选择主要有以下两个考虑:
医学图像处理一个典型的选择
在下面的代码中介绍:
typedef unsigned short PixelType;//无符号短型
const unsigned int Dimension = 2;//二维图片
typedef itk::Image< PixelType, Dimension > ImageType;//定义图像类型
注意:在内存中图像的维数应该与文件中的图像的维数相匹配。有一对特别的状态,这种情况也许不是很严格,但一般能够确保两个维数匹配。
我们现在以reader
和writer的类型为例,这两个类通过图像类型被参数化:
typedef itk::ImageFileReader< ImageType > ReaderType;
typedef itk::ImageFileWriter< ImageType > WriterType;
这时,我们用New( )函数并把结果赋值给一个itk::SmartPointer来创建每个类型的对象:
ReaderType::Pointer reader = ReaderType::New( );
WriterType::Pointer writer = WriterType::New( );
//智能指针(详见),现在可以暂时把它看做是对一个对象的实例的操作
被读或写的文件名用SetFileName( )
函数传递:
reader->SetFileName( inputFilename );//读取的文件名(路径)
writer->SetFileName( outputFilename );//写入的文件名(路径)
我们把这些readers
和writers
连接到滤波器上来创建一个数据通道。例如,我们直接传递reader的输出给writer
的输入来创建一个短数据通道:
writer->SetInput( reader->GetOutput( ) );
这也许是一个很没有用的程序,实际上是一个强大的文件格式转换工具。数据通道的执行被最后对象的Update( )触发。在这个情况下,最终的数据通道对象是
writer
。在通道被执行时,最明智的自我保护程序的做法是在一个try/catch模块中插入
Update( )以抛出异常。
try
{
writer->Update( );
}
catch( itk::ExceptionObject & err )
{
std::cerr << "ExceptionObject caught !" << std::endl;
std::cerr << err << std::endl;
return EXIT_FAILURE;
}
注意:异常只能被知道用它们去做什么的代码捕捉到。Catch
模块的典型应用应该是存在于GUI代码里。Catch 模块的活动是通知用户IO操作的失败。
//ITK官网完整代码(英文注释删减版,源代码见Examples/IO/ImageReadWrite.cxx)
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImage.h"
int main(int argc, char** argv)
{
typedef short PixelType;
const unsigned int Dimension = 2;
typedef itk::Image< PixelType, Dimension > ImageType;
typedef itk::ImageFileReader< ImageType > ReaderType;
typedef itk::ImageFileWriter< ImageType > WriterType;
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
const char* inputFilename = argv[1];
const char* outputFilename = argv[2];
reader->SetFileName(inputFilename);
writer->SetFileName(outputFilename);
writer->SetInput(reader->GetOutput());
try
{
writer->Update();
}
catch (itk::ExceptionObject& err)
{
std::cerr << "ExceptionObject caught !" << std::endl;
std::cerr << err << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
"异常"后续:直接对上述官网源码添加读写文件名,会产生错误"Could not create IO object for writing file. There are no registered IO factories."
该错误提示就是由Try/Catch异常处理提供.根据错误类型,我们创建一个GDCMImageIO对象(对应格式的ImageIO对象)并将其与reader和writer相连即可。