<br>Hi Luis,<br><br>Thank you for your very interesting and significant insight on this pipeline puzzle.<br><br>Suppose this code to read an image file works (assume all variables are defined somewhere):<br><br><span style="font-family: courier new,monospace;">typedef itk::Image< InputPixelType, ImageDimension > InputImageType;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> typedef itk::ImageFileReader< InputImageType > ImageReaderType;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">ImageReaderType::Pointer fixImgReader = ImageReaderType::New();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> fixImgReader->SetFileName( fixImgFileName );</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> fixImgReader->Update(); // loads data into RAM?</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">InputImageType::Pointer fixImg = fixImgReader->GetOutput();</span><br style="font-family: courier new,monospace;"><br>At this point, can we assume that whenever the <span style="font-family: courier new,monospace;">fixImg</span> is used, there is no longer any access back to the image data in a file on disk? In other words, the <span style="font-family: courier new,monospace;">fixImgReader</span> 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 <span style="font-family: courier new,monospace;">fixImgReader->Update()</span> and, even then, the object is smart enough to avoid another file read). Is that assumption correct?<br>
<br>Now, suppose some attributes of <span style="font-family: courier new,monospace;">fixImg </span>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, <i>Heart of Darkness</i>),<br>
<br><span style="font-family: courier new,monospace;">InputImageType::SpacingType imgSpacing;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">imgSpacing[0] = xScale; </span><span style="font-family: courier new,monospace;"> // assume this exists</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">imgSpacing[1] = yScale;</span><span style="font-family: courier new,monospace;"> // assume this exists</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">fixImg->SetSpacing( imgSpacing );</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"></span><br>At this point, there may be an inconsistency in the spacing parameters between the image file on disk and the data now in <span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">fixImg. </span>Now suppose that <span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">fixImg</span> is input to another filter, like a smoothing filter or a registration method (filter), which probably calls <span style="font-family: courier new,monospace;">fixImg->Update()</span>. Are there any circumstances that would result in changes to the spacing attributes of <span style="font-family: courier new,monospace;">fixImg</span> as a result of calling <span style="font-family: courier new,monospace;">fixImg->Update()</span>? To put the question another way, is it possible that a call to <span style="font-family: courier new,monospace;">fixImg->Update()</span> could "redefine" the spacing attributes in <span style="font-family: courier new,monospace;">fixImg</span> by reading data from a file on disk?<br>
<br>Take care,<br>Darren<br><br><br><br><br><br><div class="gmail_quote">On Thu, Oct 8, 2009 at 7:27 AM, Luis Ibanez <span dir="ltr"><<a href="mailto:luis.ibanez@kitware.com">luis.ibanez@kitware.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Hi Darren,<br>
<br>
Excellent question !.<br>
<br>
It used to be the case that the ImageRegistration class will not behave<br>
as a pipelined filter. It that old age, it was necessary for you to call<br>
update in the filters that provided the Fixed image and Moving image.<br>
<br>
<br>
Today, the ImageRegistration class behaves like a filter in which the<br>
Fixed and Moving images are two inputs. Therefore, the call to:<br>
<br>
<br>
registration->Update() or<br>
registration->StartRegistration()<br>
<br>
<br>
will first trigger a call to Update() in the filters that provide the fixed<br>
and moving images.<br>
<br>
<br>
HOWEVER, the FixedImageRegion() is NOT taken as a filter input,<br>
but as a filter parameter. Therefore, if you intend to take that region<br>
from one of the images, it is important to manually update the filter<br>
(or reader) that provide that image before you trigger an update in<br>
the registration class.<br>
<br>
<br>
Otherwise,<br>
the image in question will have invalid values in its regions.<br>
<br>
<br>
For an example on how to use the ImageRegistration class as<br>
an filter, please look at:<br>
<br>
Insight/Examples/Registration/ImageRegistration1.cxx<br>
<br>
Note that the output is a Transform, packaged in a Decorator<br>
DataObject. (line 579):<br>
<br>
resampler->SetTransform( registration->GetOutput()->Get() );<br>
<br>
<br>
<br>
Regards,<br>
<br>
<br>
Luis<br>
<br>
<br>
------------------------------------------------------------------<br>
<div><div></div><div class="h5">On Tue, Sep 29, 2009 at 9:10 PM, Darren Weber<br>
<<a href="mailto:darren.weber.lists@gmail.com">darren.weber.lists@gmail.com</a>> wrote:<br>
><br>
> Dear Luis et al.,<br>
><br>
> This question is about how to handle image data in an image registration<br>
> algorithm (based on the book section 8.2 "Hello World" Registration).<br>
><br>
> Given this code (most of this is straight from the example):<br>
><br>
> // Define the types of the images to be registered.<br>
> const unsigned short Dimension = 3;<br>
> typedef float bwPixelType;<br>
> typedef itk::Image< bwPixelType, Dimension > bwImageType;<br>
> typedef itk::ImageFileReader< bwImageType > bwImageReaderType;<br>
> // Instantiate the image readers.<br>
> // How do they convert tif file data to bwPixelType?<br>
> bwImageReaderType::Pointer fixBWimgReader = bwImageReaderType::New();<br>
> bwImageReaderType::Pointer movBWimgReader = bwImageReaderType::New();<br>
> // create image data objects (this a slight variation on the example)<br>
> fixBWimgReader->SetFileName( fixBWImgFileName ); // assume this works<br>
> fixBWimgReader->Update();<br>
> movBWimgReader->SetFileName( movBWImgFileName ); // assume this works<br>
> movBWimgReader->Update();<br>
> bwImageType::Pointer fixBWimg = fixBWimgReader->GetOutput();<br>
> bwImageType::Pointer movBWimg = movBWimgReader->GetOutput();<br>
><br>
> // *****************************************************<br>
> // Imagine code here (not in the example);<br>
> // the additional code sets specific 'spacing' and 'origin'<br>
> // values on fixBWimg and movBWimg (ommited for brevity).<br>
> // *****************************************************<br>
><br>
> // Now create registration objects (some elements ommited in this email)<br>
> typedef itk::ImageRegistrationMethod< bwImageType, bwImageType ><br>
> RegistrationType;<br>
> RegistrationType::Pointer registration = RegistrationType::New();<br>
><br>
><br>
> Is there any significant functional difference (or problems) in using this:<br>
><br>
> // Add images to the registration method.<br>
> registration->SetFixedImage( fixBWimgReader->GetOutput() );<br>
> registration->SetMovingImage( movBWimgReader->GetOutput() );<br>
> fixBWimgReader->Update();<br>
> registration->SetFixedImageRegion(<br>
> fixBWimgReader->GetOutput()->GetBufferedRegion() );<br>
><br>
> OR this:<br>
><br>
> // Add images to the registration method.<br>
> registration->SetFixedImage( fixBWimg );<br>
> registration->SetMovingImage( movBWimg );<br>
> registration->SetFixedImageRegion(<br>
> fixBWimg->GetLargestPossibleRegion().GetSize() );<br>
><br>
> The puzzle hinges on how the data pipeline handles the file/image data and<br>
> whether or not it is necessary to have some kind of "update object" for the<br>
> image data in the registration object? Is there some sense in which the<br>
> 'fixBWimg' object contains 'static' data in memory (which is modified after<br>
> reading the file data by calls to fixBWimg->SetSpacing() and<br>
> fixBWimg->SetOrigin())? Given changes to the image spacing and origin, it<br>
> is preferable to have 'static' image data in memory and to avoid any<br>
> automatic refresh or update of the image data from disk for every iteration<br>
> in the registration method (which might wipe out the settings for spacing<br>
> and origin).<br>
><br>
> Please share some insight on the Insight(ITK) data pipeline during<br>
> registration. :-)<br>
><br>
> Take care,<br>
> Darren<br>
><br>
><br>
</div></div>> _____________________________________<br>
> Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
><br>
> Visit other Kitware open-source projects at<br>
> <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
><br>
> Please keep messages on-topic and check the ITK FAQ at:<br>
> <a href="http://www.itk.org/Wiki/ITK_FAQ" target="_blank">http://www.itk.org/Wiki/ITK_FAQ</a><br>
><br>
> Follow this link to subscribe/unsubscribe:<br>
> <a href="http://www.itk.org/mailman/listinfo/insight-users" target="_blank">http://www.itk.org/mailman/listinfo/insight-users</a><br>
><br>
><br>
</blockquote></div><br>