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

Michael Kuhn michakuhn at gmx . ch
Mon, 14 Jul 2003 14:01:28 -0600


Hi,

the error message I got was:

Compiling...
RegistrationTest.cxx
D:\pack\vtkMy\src\Applications\Mixed\RegistrationTest\RegistrationTest.cxx(97) 
: error C2679: binary '=' : no operator defined which takes a right-hand 
operand of type 'void' (or there is no acceptable conversion)
        
D:\pack\vtkMy\src\Applications\Mixed\RegistrationTest\RegistrationTest.cxx(213) 
: see reference to function template instantiation 'void __cdecl 
GetAIM(char *,class itk::SmartPointer<class itk::Image<short,3> > 
*,double *)' being compiled
D:\pack\vtkMy\src\Applications\Mixed\RegistrationTest\RegistrationTest.cxx(98) 
: error C2679: binary '=' : no operator defined which takes a right-hand 
operand of type 'const class itk::Image<short,3> *' (or there is no 
acceptable conversion)
        
D:\pack\vtkMy\src\Applications\Mixed\RegistrationTest\RegistrationTest.cxx(213) 
: see reference to function template instantiation 'void __cdecl 
GetAIM(char *,class itk::SmartPointer<class itk::Image<short,3> > 
*,double *)' being compiled
Error executing cl.exe.

TestRegistrationTest.exe - 2 error(s), 0 warning(s)

The code basically looks like this:

template<typename ImageTypePointer>
void GetAIM(char* inputFilename, ImageTypePointer *img) {
    (...)
    vtk2itkFilter->SetInput(reader->GetOutput());
    vtk2itkFilter->GetImporter()->Update();
    *img = vtk2itkFilter->Update();
    *img = vtk2itkFilter->GetOutput();
}

main(...) {
    (...)
    typedef short PixelType;
    typedef itk::Image<PixelType, Dimension> ImageType;
    ImageType::Pointer myImage;
    (...)
    GetAIM(filename, myImage);
    (...)
}

Kind regards,

Michael


Luis Ibanez wrote:

>
> 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
>>>
>>>
>
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk . org
> http://www . itk . org/mailman/listinfo/insight-users
>
>