[Insight-users] Behavior of Observer in registration example

Kent Ogden ogdenk at upstate.edu
Fri Mar 23 16:00:26 EDT 2012


Hello ITK experts, 

I am using the DeformableRegistration16 example as the basis for a program to register mammo images.  In that example there are two observers set up, one for the multi-resolution filter, and one for the demons registration filter.  The observers for the demons filter and multi-res filters are both looking for the IterationEvent, so I expect the demons observer to fire at the end of every iteration (currently set to 40 per level), and the multi-res observer to see the changes in resolution level (4 levels).  I would like to look at the RMS difference at the end of each iteration (mostly for educational purposes) but what I see is that the event does not fire for the demons filter as expected.  Instead, it seems to fire only once for each resolution level (i.e. both observers execute the same number of times while the registration is running). 

What's really confusing, is that every once in a while, the demons observer seems to function as I would expect, so I see for example 40 Iteration Events for a given resolution level of the multi res filter.  Could this be a bug?  Can anyone shed light on how to get this to function properly?  The registration itself seems to work fine, though I'm not sure this is the best algorithm to try to register digital mammos with.  I am able to get a warped image and the displacement map output back to Matlab, which I am using for my front end interface, and  the results are actually not too bad looking, at least to the eye. 

Thanks for any light that may be shed on this issue. 

Kent 


In case someone would like to see the code, this is pretty much verbatim from the example: 

//  The following section of code implements a Command observer 
//  that will monitor the evolution of the registration process. 
//  This observer has a layer of intelligence, for deciding what 
//  MaximumRMS convergence criteria to use at every resolution level. 
// 
class CommandIterationUpdate : public itk::Command 
{ 
public: 
  typedef  CommandIterationUpdate   Self; 
  typedef  itk::Command             Superclass; 
  typedef  itk::SmartPointer<Self>  Pointer; 
  itkNewMacro( Self ); 
protected: 
  CommandIterationUpdate() {}; 

  // define ITK short-hand types 
  typedef short                                PixelType; 
  typedef float                                InternalPixelType; 
  typedef itk::Image< PixelType, 2 >           ImageType; 
  typedef itk::Image< InternalPixelType, 2 >   InternalImageType; 
  typedef itk::Vector< float, 2 >              VectorPixelType; 
  typedef itk::Image< VectorPixelType, 2 >     DisplacementFieldType; 
  typedef itk::DemonsRegistrationFilter< InternalImageType, 
    InternalImageType, DisplacementFieldType>  RegistrationFilterType; 

public: 

  void Execute(const itk::Object *, const itk::EventObject & ) 
    { 
    std::cout << "Warning: The const Execute method shouldn't be called" << std::endl; 
    } 

  void Execute(itk::Object *caller, const itk::EventObject & event) 
    { 
       RegistrationFilterType * filter = 
        dynamic_cast<  RegistrationFilterType * >( caller ); 

       if( !(itk::IterationEvent().CheckEvent( &event )) ) 
        { 
        return; 
        } 
      if(filter) 
        { 
        filter->SetMaximumRMSError(MaxRmsE[RmsCounter]); 
        std::cout << filter->GetMetric() <<  "  RMS Change: " << filter->GetRMSChange() << std::endl; 

         std::cout << "Level Tolerance=  "<<filter->GetMaximumRMSError ()<<std::endl; 
    } 

} 
}; 

// The following command observer reports the progress of the registration 
// inside a given resolution level. 
// 
class CommandResolutionLevelUpdate : public itk::Command 
{ 
public: 
  typedef  CommandResolutionLevelUpdate   Self; 
  typedef  itk::Command                   Superclass; 
  typedef  itk::SmartPointer<Self>        Pointer; 
  itkNewMacro( Self ); 

protected: 
  CommandResolutionLevelUpdate() {}; 

public: 
  void Execute(itk::Object *caller, const itk::EventObject & event) 
    { 
    Execute( (const itk::Object *)caller, event); 
    } 
  void Execute(const itk::Object *, const itk::EventObject & ) 
    { 
    std::cout << "----------------------------------" << std::endl; 
    RmsCounter = RmsCounter + 1; 
    std::cout << "----------------------------------" << std::endl; 
    } 
}; 
. 
. 
. 
// 
  // Create the Command observer and register it with the demons registration filter. 
  // 
  CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); 
  filter->AddObserver( itk::IterationEvent(), observer ); 
. 
. 
. 
// Create the Command observer and register it with the multi-res registration filter. 
  // 
  CommandResolutionLevelUpdate::Pointer levelobserver = CommandResolutionLevelUpdate::New(); 
  multires->AddObserver( itk::IterationEvent(), levelobserver ); 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20120323/3a31dff7/attachment.htm>


More information about the Insight-users mailing list