我有一个CImg图像(带有double值),在c ++中有以下形式:
CImg<double> image(512,512);
Tcyl.fill(1);
我想使用ITK功能来转换此图像。所以我需要将这个CImg图像转换为itkImage对象。我怎么转换?
答案 0 :(得分:1)
我之前从未使用过 ITK ,所以这是一个学习曲线。无论如何,我设法在 CImg 中制作了一个径向渐变的浮点数,并将其转换为 ITK 图像,然后将其写为浮点TIFF
。
#include <iostream>
#include <cstdlib>
#define cimg_display 0
#include "CImg.h"
#include "itkImage.h"
#include "itkImportImageFilter.h"
#include "itkImageFileWriter.h"
#include "itkTIFFImageIO.h"
using namespace cimg_library;
using namespace std;
#define W 512
#define H 512
int main() {
// Create and initialise float image with radial gradient
cimg_library::CImg<float> img(W,H);
cimg_forXY(img,x,y) {img(x,y) = hypot((float)(W/2-x),(float)(H/2-y)); }
// Now convert CImg image to ITK image
const unsigned int Dimension = 2;
typedef itk::Image<float,Dimension> InputImageType;
typedef itk::ImportImageFilter<float,Dimension> ImportFilterType;
ImportFilterType::Pointer importFilter = ImportFilterType::New();
InputImageType::SizeType imsize;
imsize[0] = img.width();
imsize[1] = img.height();
ImportFilterType::IndexType start;
start.Fill(0);
ImportFilterType::RegionType region;
region.SetIndex(start);
region.SetSize(imsize);
importFilter->SetRegion(region);
const itk::SpacePrecisionType origin[Dimension] = {0.0,0.0};
importFilter->SetOrigin(origin);
const itk::SpacePrecisionType spacing[Dimension] = {1.0,1.0};
importFilter->SetSpacing(spacing);
// Tell ITK importFilter to take pixels directly from CImg's buffer
importFilter->SetImportPointer(img.data(),imsize[0]*imsize[1],false);
// Write result as a TIFF - so I can check it worked
typedef itk::ImageFileWriter<InputImageType> WriterType;
typedef itk::TIFFImageIO TIFFIOType;
TIFFIOType::Pointer tiffIO = TIFFIOType::New();
tiffIO->SetPixelType(itk::ImageIOBase::SCALAR);
WriterType::Pointer writer = WriterType::New();
writer->SetFileName("result.tif");
writer->SetInput(importFilter->GetOutput());
writer->SetImageIO(tiffIO);
writer->Update();
}
这里是结果(为SO转换为JPEG):
如果您为float
更改double
,它的工作原理相同,只是您无法将double
写入TIFF,因此最后一位不会起作用。
我已经搞砸了一些,并设法将像素加载到新的ITK图像中,以便进一步处理,而不是输出:
#include <iostream>
#include <cstdlib>
#define cimg_display 0
#include "CImg.h"
#include "itkImage.h"
#include "itkImageRegionIterator.h"
using namespace cimg_library;
using namespace std;
#define W 5
#define H 3
int main() {
// Create and initialise double image with simple formula
cimg_library::CImg<double> img(W,H);
cimg_forXY(img,x,y) {img(x,y) = (double)x+(10.0*(double)y); }
// Now convert CImg image to ITK image
const unsigned int Dimension = 2;
typedef itk::Image<double,2> ImageType;
ImageType::Pointer image = ImageType::New();
ImageType::SizeType size;
size[0] = img.width();
size[1] = img.height();
ImageType::IndexType start;
start.Fill(0);
ImageType::RegionType region;
region.SetSize(size);
region.SetIndex(start);
image->SetRegions(region);
image->Allocate();
double origin[2];
origin[0]=0;
origin[1]=0;
image->SetOrigin(origin);
double spacing[2];
spacing[0]=1;
spacing[1]=1;
image->SetSpacing(spacing);
typedef itk::ImageRegionIterator<ImageType> IteratorType;
IteratorType it(image,region);
it.GoToBegin();
const double* data = img.data();
while(!it.IsAtEnd()){
it.Set(*data);
++it;
++data;
}
// Display pixels for checking purposes
for(unsigned int r = 0; r < H; r++)
{
for(unsigned int c = 0; c < W; c++)
{
ImageType::IndexType pixelIndex;
pixelIndex[0] = c;
pixelIndex[1] = r;
ImageType::PixelType pixelValue = image->GetPixel( pixelIndex );
cout << "Image[" << r << "," << c << "]: " << pixelValue << endl;
}
}
}
示例输出
Image[0,0]: 0
Image[0,1]: 1
Image[0,2]: 2
Image[0,3]: 3
Image[0,4]: 4
Image[1,0]: 10
Image[1,1]: 11
Image[1,2]: 12
Image[1,3]: 13
Image[1,4]: 14
Image[2,0]: 20
Image[2,1]: 21
Image[2,2]: 22
Image[2,3]: 23
Image[2,4]: 24