[Insight-users] registration->SetFixedImage - puzzled about how pipeline handles data

Luis Ibanez luis.ibanez at kitware.com
Thu Oct 8 21:16:26 EDT 2009


Hi Darren,

Please find comments interleaved with your email.

    Thanks

         Luis


--------------------------------
On Thu, Oct 8, 2009 at 2:15 PM, Darren Weber
<darren.weber.lists at gmail.com> wrote:
>
> Hi Luis,
>
> Thank you for your very interesting and significant insight on this pipeline
> puzzle.
>
> Suppose this code to read an image file works (assume all variables are
> defined somewhere):
>
> typedef itk::Image< InputPixelType,  ImageDimension > InputImageType;
> typedef itk::ImageFileReader< InputImageType > ImageReaderType;
> ImageReaderType::Pointer fixImgReader = ImageReaderType::New();
> fixImgReader->SetFileName( fixImgFileName );
> fixImgReader->Update(); // loads data into RAM?


Yes, This should load the image into RAM.
Unless.... something goes wrong, in which case it
should throw an exception.  It is wise to put all
Update() calls inside a try/catch block...


> InputImageType::Pointer fixImg = fixImgReader->GetOutput();
>
> At this point, can we assume that whenever the fixImg is used, there is no
> longer any access back to the image data in a file on disk?  In other words,
> the fixImgReader has done it's job and it's no longer updated in the
> pipeline (so the file on disk is accessed only once during the program run,
> unless there is another call to fixImgReader->Update() and, even then, the
> object is smart enough to avoid another file read).  Is that assumption
> correct?


Yes, that a correct assumption.
Once you execute the reader, (call Update()),
it should not run again due to updates in the
subsequent pipeline filters.  UNLESS you
change the filename in the reader.



>
> Now, suppose some attributes of fixImg are modified.  For example, suppose
> there is some user input to set the x,y spacing of a 2D image ("The horror!
> The horror!" - Joseph Conrad, Heart of Darkness),
>
> InputImageType::SpacingType imgSpacing;
> imgSpacing[0] = xScale; // assume this exists
> imgSpacing[1] = yScale; // assume this exists
> fixImg->SetSpacing( imgSpacing );
>


Yes, "The Horror !"
Do not do that.
If you need to change the spacing you should
use the itkChangeInformationImageFilter.
Otherwise your changes may be lost when the
pipeline updates.

For all purposes you should try the Output of
ITK filters as "const".  It was an unfortunate
oversight of our initial design/implementation
that we didn't enforced const-correctness in the
Outputs.  We probably will fix that in ITK 4.0.



> At this point, there may be an inconsistency in the spacing parameters
> between the image file on disk and the data now in fixImg.  Now suppose that
> fixImg is input to another filter, like a smoothing filter or a registration
> method (filter), which probably calls fixImg->Update().  Are there any
> circumstances that would result in changes to the spacing attributes of
> fixImg as a result of calling fixImg->Update()?  To put the question another
> way, is it possible that a call to fixImg->Update() could "redefine" the
> spacing attributes in fixImg by reading data from a file on disk?
>


Yes, that is possible.
and it is the reason why you should not touch the internal
parameters of an image that is the output of a filter.

Please use the itkChangeInformationImageFilter for this
purpose. This filter will only change the metadata of the
image and will not duplicate the image buffer.



> Take care,
> Darren
>
>
>
>
>
> On Thu, Oct 8, 2009 at 7:27 AM, Luis Ibanez <luis.ibanez at kitware.com> wrote:
>>
>> Hi Darren,
>>
>> Excellent question !.
>>
>> It used to be the case that the ImageRegistration class will not behave
>> as a pipelined filter.   It that old age, it was necessary for you to call
>> update in the filters that provided the Fixed image and Moving image.
>>
>>
>> Today, the ImageRegistration class behaves like a filter in which the
>> Fixed and Moving images are two inputs.  Therefore, the call to:
>>
>>
>>    registration->Update()   or
>>    registration->StartRegistration()
>>
>>
>> will first trigger a call to Update() in the filters that provide the
>> fixed
>> and moving images.
>>
>>
>> HOWEVER, the FixedImageRegion() is NOT taken as a filter input,
>> but as a filter parameter.  Therefore, if you intend to take that region
>> from one of the images, it is important to manually update the filter
>> (or reader) that provide that image before you trigger an update in
>> the registration class.
>>
>>
>> Otherwise,
>> the image in question will have invalid values in its regions.
>>
>>
>> For an example on how to use the ImageRegistration class as
>> an filter, please look at:
>>
>>    Insight/Examples/Registration/ImageRegistration1.cxx
>>
>> Note that the output is a Transform, packaged in a Decorator
>> DataObject. (line 579):
>>
>>   resampler->SetTransform( registration->GetOutput()->Get() );
>>
>>
>>
>>     Regards,
>>
>>
>>          Luis
>>
>>
>> ------------------------------------------------------------------
>> On Tue, Sep 29, 2009 at 9:10 PM, Darren Weber
>> <darren.weber.lists at gmail.com> wrote:
>> >
>> > Dear Luis et al.,
>> >
>> > This question is about how to handle image data in an image registration
>> > algorithm (based on the book section 8.2 "Hello World" Registration).
>> >
>> > Given this code (most of this is straight from the example):
>> >
>> >     //  Define the types of the images to be registered.
>> >     const    unsigned short  Dimension = 3;
>> >     typedef  float           bwPixelType;
>> >     typedef itk::Image< bwPixelType,  Dimension > bwImageType;
>> >     typedef itk::ImageFileReader< bwImageType  >  bwImageReaderType;
>> >     // Instantiate the image readers.
>> >     // How do they convert tif file data to bwPixelType?
>> >     bwImageReaderType::Pointer fixBWimgReader =
>> > bwImageReaderType::New();
>> >     bwImageReaderType::Pointer movBWimgReader =
>> > bwImageReaderType::New();
>> >     // create image data objects (this a slight variation on the
>> > example)
>> >     fixBWimgReader->SetFileName( fixBWImgFileName ); // assume this
>> > works
>> >     fixBWimgReader->Update();
>> >     movBWimgReader->SetFileName( movBWImgFileName ); // assume this
>> > works
>> >     movBWimgReader->Update();
>> >     bwImageType::Pointer fixBWimg = fixBWimgReader->GetOutput();
>> >     bwImageType::Pointer movBWimg = movBWimgReader->GetOutput();
>> >
>> >     // *****************************************************
>> >     // Imagine code here (not in the example);
>> >     // the additional code sets specific 'spacing' and 'origin'
>> >     // values on fixBWimg and movBWimg (ommited for brevity).
>> >     // *****************************************************
>> >
>> >     // Now create registration objects (some elements ommited in this
>> > email)
>> >     typedef itk::ImageRegistrationMethod< bwImageType, bwImageType >
>> > RegistrationType;
>> >     RegistrationType::Pointer registration = RegistrationType::New();
>> >
>> >
>> > Is there any significant functional difference (or problems) in using
>> > this:
>> >
>> > // Add images to the registration method.
>> > registration->SetFixedImage(  fixBWimgReader->GetOutput() );
>> > registration->SetMovingImage( movBWimgReader->GetOutput() );
>> > fixBWimgReader->Update();
>> > registration->SetFixedImageRegion(
>> > fixBWimgReader->GetOutput()->GetBufferedRegion() );
>> >
>> > OR this:
>> >
>> > // Add images to the registration method.
>> > registration->SetFixedImage(  fixBWimg );
>> > registration->SetMovingImage( movBWimg );
>> > registration->SetFixedImageRegion(
>> > fixBWimg->GetLargestPossibleRegion().GetSize() );
>> >
>> > The puzzle hinges on how the data pipeline handles the file/image data
>> > and
>> > whether or not it is necessary to have some kind of "update object" for
>> > the
>> > image data in the registration object?  Is there some sense in which the
>> > 'fixBWimg' object contains 'static' data in memory (which is modified
>> > after
>> > reading the file data by calls to fixBWimg->SetSpacing() and
>> > fixBWimg->SetOrigin())?  Given changes to the image spacing and origin,
>> > it
>> > is preferable to have 'static' image data in memory and to avoid any
>> > automatic refresh or update of the image data from disk for every
>> > iteration
>> > in the registration method (which might wipe out the settings for
>> > spacing
>> > and origin).
>> >
>> > Please share some insight on the Insight(ITK) data pipeline during
>> > registration. :-)
>> >
>> > Take care,
>> > Darren
>> >
>> >
>> > _____________________________________
>> > Powered by www.kitware.com
>> >
>> > Visit other Kitware open-source projects at
>> > http://www.kitware.com/opensource/opensource.html
>> >
>> > Please keep messages on-topic and check the ITK FAQ at:
>> > http://www.itk.org/Wiki/ITK_FAQ
>> >
>> > Follow this link to subscribe/unsubscribe:
>> > http://www.itk.org/mailman/listinfo/insight-users
>> >
>> >
>
>


More information about the Insight-users mailing list