How can I pad an image when I only know its physical bounds?

171 views Asked by At

I am trying to apply a mask on an image but the masking image has different dimensions that the one to be masked. To apply the mask I must ensure that the images have the same dimensions, so I'm using the ITK PadImageFilter class, but to do so the padding values must be given in indexes instead of physical coordinates. My program enables me to get the boundaries of both images in physical coordinates but not their indexes.

Is there a way in ITK to get the corresponding index of a given point? I understand the relation between pixels and the image dimensions, I just want to know if there is a method which automatically does it in ITK.

Edit: Below is my code. I know that the problem is due to the fact that the padding margins (x_min, x_max, ...) are given in physical coordinates instead of indexes. How could I solve this?

typedef unsigned char UcharPixelType;
typedef short ShortPixelType;
const int Dimension = 3; 

//Declare readers for both images (which are of different types)
typedef itk::ImageFileReader< ShortImageType > ShortReaderType;
typedef itk::ImageFileReader< UcharImageType > UcharReaderType;

ShortImageType::Pointer imageToBeMasked = ShortImageType::New();
// Setting imageToBeMasked to read the corresponding image

UcharImageType::Pointer maskingImage = UcharImageType::New();
// Do the same for reading the image that will mask the former one.

// Compute the bounds of both images (i.e. physical coordinates)
double* img_bounds = imageToBeMasked->GetBounds();
double* mask_bounds = maskingImage->GetBounds();

// Compute margins needed to pad the masking image
double x_min = abs(img_bounds[0] - mask_bounds[0]);
double x_max = abs(img_bounds[1] - mask_bounds[1]);
double y_min = abs(img_bounds[2] - mask_bounds[2]);
double y_max = abs(img_bounds[3] - mask_bounds[3]);
double z_min = abs(img_bounds[4] - mask_bounds[4]);
double z_max = abs(img_bounds[5] - mask_bounds[5]);

// Declare the padding filter
typedef itk::PadImageFilter< UcharImageType, UcharImageType > PadFilterType;
PadFilterType::Pointer l_enlarge_mask = PadFilterType::New();
l_enlarge_mask->SetInput(maskingImage->GetOutput());

// Create indexes for giving padding margins to the filter,
// But these are physical coordinates! How to convert them? 
UcharImageType::IndexType indexMin;
indexMin[0] = x_min;
indexMin[1] = y_min;
indexMin[2] = z_min;

UcharImageType::IndexType indexMax;
indexMax[0] = x_max;
indexMax[1] = y_max;
indexMax[2] = z_max;

l_enlarge_mask->SetPadLowerBound(indexMin);
l_enlarge_mask->SetPadUpperBound(indexMax);

typedef itk::ImageFileWriter< UcharImageType > UcharWriterType;
UcharWriterType l_writer = UcharWriterType::New();

l_writer->SetInput(l_enlarge_mask->GetOutput());
l_writer->SetFileName("padded_mask.mhd");

try{ 
    l_writer->Update();
catch(itk::ExceptionObject& err) {
    std::cerr << "Exception caught!" << err.what() << std::endl;
} // Error: boundary condition is ITK_NULLPTR

I also tried to do the opposite, i.e. computing a view of interest (VOI) on the image to be masked (hence "cropping" the biggest image instead of padding the smallest). I therefore have given the masking image's dimensions as the VOI boundaries, but the resulting image is always a few voxels bigger (1 or 2 voxels) that the given boundaries and I have no idea why. Thought it could be because of the difference of types between the two images but computing the masking image's boundaries on its casted version does not solve the problem either.

1

There are 1 answers

3
Dženan On BEST ANSWER

What you need are TransformPhysicalPointToIndex and friends. Those methods are part of ImageBase class.