Strange output from RegionOfInterestImageFilter

After applying RegionOfInterestImageFilter to a two-dimensional image like so:

#include <itkImage.h>
#include <itkRegionOfInterestImageFilter.h>

#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>

#include <iostream>
#include <string>

int main(int argc, char *argv[]) {
    if(argc != 5) {
        std::cerr << "Usage: ";
        std::cerr << argv[0] << " inputImageFile outputImageFile start size" << std::endl;
        return EXIT_FAILURE;
    }

    std::string inputName  = argv[1];
    std::string outputName = argv[2];

    typedef itk::Image<itk::RGBPixel<unsigned char>, 2> ImageType;
    typedef itk::ImageFileReader<ImageType>             ReaderType;

    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(inputName.c_str());
    reader->Update();

    const auto input = reader->GetOutput();
    ImageType::SizeType inSize = input->GetLargestPossibleRegion().GetSize();
    std::cout << "Input size: " << inSize << std::endl;

    typedef itk::RegionOfInterestImageFilter< ImageType, ImageType > FilterType;
    FilterType::Pointer filter = FilterType::New();

    ImageType::IndexType start;
    ImageType::SizeType size;
    start.Fill(atoi(argv[3]));
    size.Fill(atoi(argv[4]));

    ImageType::RegionType desiredRegion;
    desiredRegion.SetSize(size);
    desiredRegion.SetIndex(start);

    filter->SetRegionOfInterest(desiredRegion);
    filter->SetInput(input);

    const auto output = filter->GetOutput();
    std::cout << "Output size: " << output->GetLargestPossibleRegion().GetSize() << std::endl;
    itk::WriteImage(output, outputName);

    return EXIT_SUCCESS;
}

I get an image with the output size [0, 0]:

Input size: [500, 500]
Output size: [0, 0]

The image which is written to the disk is OK, but I cannot use output anywhere in my program because of this strange size. What is wrong with my program? Tested with ITK 5.3.0 on FreeBSD and on Ubuntu (I don’t remember ITK version there).

The same thing happens with ExtractImageFilter.

1 Like

Hello @Vasily_Postnicov,

You are missing a call to filter->Update(); before the filter->GetOutput();.

ITK uses lazy evaluation. You build the pipeline of filters and then invoke an update on the last filter. In your case the WriteImage initiates this action and you do not need to explicitly call Update on any filter, including the image reader, which you currently do. The only time to explicitly call Update for a filter that is in the middle of a pipeline is if you want some intermediate information which seems to be what you want here.

2 Likes

Hello,

Yes, the Update call is missing. The Update does the complete running up the upstream filters in the pipeline. This include several steps including UpdateOutputInformation, PropagateRequestedRegion, and UpdateOutputData. A full description can be found in the software guide: 3 System Overview

But the Update does trigger the image to be read and processed. If you just want the size of the output with out running the whole pipeline then UpdateOutputInformation can be called.

1 Like

Thanks @zivy @blowekamp !