ITK版本:5.2
一、包含文件与自定义类型
1.需要包含的头文件如下:
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImportImageFilter.h"
#include "itkRawImageIO.h"
2.自定义类型名如下:
const unsigned int ImgDim = 3; //图像维度
typedef itk::Image<unsigned short, ImgDim> ImageType;
typedef itk::ImportImageFilter<unsigned short, ImgDim> ImportFilterType;
typedef itk::RawImageIO<unsigned short, ImgDim> ImageIOType;
typedef itk::ImageFileReader<ImageType> ImageRType;
typedef itk::ImageFileWriter<ImageType> ImageWType;
二、参数的设置
给定图像的初始化参数,用于后续处理。
1.图像的尺寸与初值
ImageType::SizeType size;
size[0] = 256;
size[1] = 256;
size[2] = 128;
size_t ElemCounts = size[0] * size[1] * size[2];
ImageType::IndexType start;
start.Fill(0);
ImageType::RegionType region;
region.SetSize(size);
region.SetIndex(start);
2.IO参数设定
ImageIOType::Pointer rawImgIO = ImageIOType::New();
rawImgIO->SetFileTypeToBinary(); //设置二进制形式打开
rawImgIO->SetFileDimensionality(ImgDim); //设置图像维度
rawImgIO->SetByteOrderToLittleEndian(); //设置小端序
rawImgIO->SetDimensions(0, size[0]);
rawImgIO->SetDimensions(1, size[1]);
rawImgIO->SetDimensions(2, size[2]);
rawImgIO->SetHeaderSize(0); //文件头大小
rawImgIO->SetNumberOfComponents(1); //像素通道数(灰度为1,RGB为3)
rawImgIO->SetPixelType(itk::ImageIOBase::SCALAR); //设置标量类型,即灰度图
rawImgIO->SetComponentType(itk::ImageIOBase::IOComponentEnum::USHORT);//设置像素数值类型为ushort
三、本地数据的读取
1.创建缓存空间
unsigned short* OriData = nullptr;
OriData = new unsigned short[ElemCounts];
2.使用ImageFileReader类读取并拷贝数据
使用ITK读取数据需要创建一个ImageFileReader对象,加载上述的IO设定,通过GetBufferPointer()索引缓存数据,将数据进行拷贝到OriData中。
ImageRType::Pointer reader = ImageRType::New();
reader->SetFileName("./TestImgA 256x256x128 ushort.raw");
reader->SetImageIO(rawImgIO);
reader->Update();
memcpy(OriData, reader->GetOutput()->GetBufferPointer(), sizeof(unsigned short) * ElemCounts);
对比一下C++ 的fread函数的读取方法。
FILE* fpread = nullptr;
fopen_s(&fpread, "./TestImgA 256x256x128 ushort.raw", "rb");
if (fpread != nullptr)
{
fread(OriData, sizeof(unsigned short), ElemCounts, fpread);
fclose(fpread);
}
四、像素的遍历
针对读取图像的像素遍历赋值,有两种方式
1.方式一:直接对缓存数据进行遍历
for (int p = 0; p < size[2]; p++)
{
for (int i = 0; i < size[0] * size[1]; i++)
{
OriData[p * size[0] * size[1] + i] *= (i / size[0] + p);
}
}
遍历处理之后,需要将缓存数据导入到itk::ImportImageFilter类进行后续处理。
ImportFilterType::Pointer imageFilter01 = ImportFilterType::New();
imageFilter01->SetRegion(region);
imageFilter01->SetImportPointer(OriData, ElemCounts, false);
imageFilter01->Update();
2.方式二:通过SetPixel的方式进行遍历
for (int p = 0; p < size[2]; p++)
{
itk::Index<3> ind;
ind[2] = p;
for (int i = 0; i < size[0] * size[1]; i++)
{
ind[0] = i % size[0];
ind[1] = i / size[0];
unsigned short pixValue = imageFilter01->GetOutput()->GetPixel(ind);
imageFilter01->GetOutput()->SetPixel(ind, pixValue / (p + 1));
}
}
五、图像的保存
与读取本地数据类似,使用ITK写入本地数据,需要创建一个ImageFileWriter对象,加载IO设置,然后保存到本地。
ImageWType::Pointer writer = ImageWType::New();
writer->SetFileName("./TestImgB.raw");
writer->SetInput(imageFilter01->GetOutput());
writer->SetImageIO(rawImgIO);
writer->SetUseCompression(true);
try
{
writer->Update();
}
catch (itk::ExceptionObject& e)
{
std::cerr << e << std::endl;
}
对比C++的fwrite函数的写入方法。
FILE* fpwrite = nullptr;
fopen_s(&fpwrite, "./TestImgC.raw", "wb");
if (fpwrite != nullptr)
{
fwrite(imageFilter01->GetOutput()->GetBufferPointer(), sizeof(unsigned short), ElemCounts, fpwrite);
fclose(fpwrite);
}


参考资料:https://blog.csdn.net/yunzhaoqiang/article/details/7905113