[Insight-users] registration and spacing: GetOutput() / SetSpacing() and const-correctness

Luis Ibanez luis . ibanez at kitware . com
Mon, 14 Jul 2003 15:38:56 -0400


Hi Michael,


GetOutput() on the VTKImageToImage filter shouldn't generate a
compiler error.  Could you please post this error message to
the users-list ?

You probably need "img" to be a

                 "ImageTypeConstPointer * img"

Instead of what you seem to be passing now:

                 "ImageTypePointer * img"


The reason why you don't find documentation of VTKImageToImage
in the Doxygen pages is that this class is not officially part
of ITK. It is just provided for convenience for exactly what
you are using : interfacing VTK with ITK.

----

Your new test is better configured, since now you are setting
the spacing in the right place (the input images).


The Optimizer steps are not necessarily in millimeters since
they represent in general the parameters of any transform.
However in the case of the Translation transform you can
probably make this assumption safely.

If the pixel spacing of your images is 0.0199, you may want to
set the MinimumStepLength() to half of this value (e.g. your
registration will have a precision of half a pixel), and you
may want to set the MaximumStepLength() to 10X 0.0199, (that
is, the first step will be ten pixels long).

I'm affraid that at this point your code contains much more lines
than what you really need for this task.  I would suggest you
to generate MetaImages from your data, and use the example in


    Insight/Examples/Registration/ImageRegistration3.cxx


for refining your parameters.

Start trying with

      minStepLength = 0.01
      maxStepLength = 0.20

Note that the optimizer can stop due to several different
reasons. There is a method

                GetStopCondition()

that will tell you the reason for the optimizer to stop

Valid reasons are defined in

    itkRegularStepGradientDescentBaseOptimizer.h


     GradientMagnitudeTolerance,
     StepTooSmall,
     ImageNotAvailable,
     SamplesNotAvailable,
     MaximumNumberOfIterations


Call this GetStopCondition() method after the optimizer
stops, and double check the reason for stopping.



    Regards,


      Luis


----------------------
Michael Kuhn wrote:
> Hi Luis,
> 
> I've meanwhile rewritten the GetAIM() function. It now uses the 
> VTKImageToImage filter you've suggested. [By the way, I didn't find the 
> class in the "alphabetical list" in the html documentation 
> (http://www . itk . org/Doxygen12/html/classes . html) of itk. Is there a html 
> documentation around? I had the problem, that invoking 
> vtk2itkFilter->GetOutput() produced a compile error (probably because of 
> the "const"). I used vtk2itkFilter->GetImporter()->GetOutput() instead. 
> Everything seems to work fine, however, I'm not quite sure if this is a 
> nice solution]
> 
> Back to my problem about spacing. Instead of adjusting the spacing of my 
> aim data inside my program, I've adjusted them outside the program (i.e. 
> using a tool which allows to adjust the aim data itself). Using a 
> spacing of 1, the registration works fine. Using a spacing of 0.019998 
> (which is the original spacing), the registration creates a start event, 
> no iteration event, and a end event (i.e. doesn't iterate). Since the 
> length of the translation vector, the min and max step size and the 
> initial parameters have to be adjusted according to the scaling (since 
> all of them are measured in mm, aren't they?), I've replaced FACTOR by a 
> double variable factor, which is set to spacing[0]. (The spacings in 
> other directions are in about the same (0.019998, 0.019998, 0.021)).
> 
> I've attached the new code.
> 
> Thanks a lot for your help.
> 
> Kind regards,
> 
> Michael
> 
> 
> 
> 
> Luis Ibanez wrote:
> 
>>
>> Hi Michael,
>>
>>
>> Thanks for sending your code.
>> It helps to clarify the produre you are using.
>>
>>
>> Here are some factor that can be preventing your
>> registration process from working correctly.
>>
>>
>> 1) The mechanism you are using for changing the
>>     image scale is not reliable.  You are taking
>>     the output of the reader and invoking its
>>     SetSpacing() method.
>>
>>
>>     double spacing[2];
>>     spacing[0] = 1.0 * FACTOR;
>>     spacing[1] = 1.0 * FACTOR;
>>     reader->GetOutput()->SetSpacing(spacing);
>>     *img = reader->GetOutput();
>>
>>
>>      You shouldn't attempt to change the spacing
>>      of the Output() in any ITK filter, nor any
>>      other property of the filter output. The output
>>      of a filter belongs to the filter itself, and
>>      can be recomputed at any call of the Update()
>>      method.  The changes of spacing that you
>>      are applying could be overriden by the next
>>      call to an Update() in the pipeline.
>>
>>      If you double check in your GetAIM() method,
>>      you are invoking Update() on the importer,
>>      after having reset the Spacing of the reader.
>>      This Update() will override your spacing
>>      modifications.
>>
>>
>>      The GetOutput() method of ITK filters should
>>      infact return a ConstSmartPointer in order
>>      to prevent this miss-use of the output of a filter.
>>      This is something we may have to fix in a future
>>      release...
>>
>>      Since you are doing this spacing change more
>>      for debugging purposes than for being part of
>>      a  normal data pipeline, I'll suggest you to
>>      convert your PNG images into MetaImage format
>>      and then simply modify the spacing in the .mhd
>>      file. Then, execute your program using the .mhd
>>      files as input (instead of the PNG).
>>
>>      Another option is to use the "ChangeInformationImageFilter"
>>      which allows you to modify image data in a pipeline
>>      compatible fashion.  Note that this is a very risky
>>      operation that you would not like to have in a
>>      real medical application. Please don't use this
>>      for anything different than debugging.
>>
>>
>>
>> 2)  In the conversion from VTK image to ITK image
>>      you may find convenient to use the filters:
>>
>>      ImageToVTKImageFilter
>>      VTKImateToImageFilter
>>
>>      available in InsightApplications/Auxiliary/vtk
>>
>>      That will simplify the code in your GetAIM() function.
>>
>>
>>
>> 3) The only occasion in which you are entitled to call
>>     the SetSpacing() and SetOrigin() methods is when you
>>     create the image in a program, instead of reading it
>>     from a file, or taking it from the output of a filter.
>>
>>     Filter outputs should not be modified.
>>
>>
>> 4) PNG is a poor format for storing medical images.
>>     It is supported in ITK only for facilitating simple
>>     experiments, examples and demos. In real applications
>>     you may want to use a more reliable format like GIPL,
>>     Analyze, MetaImage or VTK.
>>
>>
>>
>>
>> Regards,
>>
>>
>>     Luis
>>
>>