Skip to content

Commit

Permalink
SK:
Browse files Browse the repository at this point in the history
- version: 3.402 (3.401 was never committed)
- Only dll's with the following name are loaded: <libprefix>elxName.<libextension>. So, something like elxEulerTransform.dll for example. This makes sure that not every possible dll is loaded that happens to be present in the directory where elastix lives. Bug showed up when using Condor and was reported by Ivana.
- Added AutomaticTransformInitialization functionality. The affine, rigid, and translation transform now are able to initialize themselves with an 'expected' translation (= the distance between centers of the images)
- Added an itk class to Common: itkTranslationTransformInitializer. Almost a copy of the itkCenteredTransformInitializer.
- CenterOfRotation is not anymore written to TransformParameter files. It is still understood though. Instead of CenterOfRotation, the CenterOfRotationPoint is written. This is the same point, but now in world coordinates.
- Removed the evil StochasticQuasiNewton optimizer. It will remain in the Attic anyway. No need to compile it still.
- Added the ConjugateGradientFRPR optimizer. It was already sitting in my elastix-tree for a while.This is a fully functional fletcher reeves conjugate gradient optimizer, using a dBrent exact line search, based on the description in Numerical Recipes in c++. It's not  a really good optimizer, but it works, and is known. The exact line search might proof useful somewhere/somewhen.
- Added description to parameters in ConjugateGradient and QuasiNewtonLBFGS (and to ConjugateGradientFRPR, but it's new anyway.)

pfew...


-
-
  • Loading branch information
stefanklein committed Apr 20, 2006
1 parent bc43f96 commit 1c64e2a
Show file tree
Hide file tree
Showing 25 changed files with 1,709 additions and 1,364 deletions.
4 changes: 3 additions & 1 deletion src/Common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ itkDeformationVectorFieldTransform.txx
itkScaledSingleValuedCostFunction.h
itkScaledSingleValuedCostFunction.cxx
itkScaledSingleValuedNonLinearOptimizer.h
itkScaledSingleValuedNonLinearOptimizer.cxx )
itkScaledSingleValuedNonLinearOptimizer.cxx
itkTranslationTransformInitializer.h
itkTranslationTransformInitializer.hxx)

SET( TransformGrouperFiles
TransformGrouper/itkBSplineTransformGrouper.h
Expand Down
140 changes: 140 additions & 0 deletions src/Common/itkTranslationTransformInitializer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#ifndef __itkTranslationTransformInitializer_h
#define __itkTranslationTransformInitializer_h

#include "itkObject.h"
#include "itkObjectFactory.h"
#include "itkImageMomentsCalculator.h"

#include <iostream>

namespace itk
{

/** \brief TranslationTransformInitializer is a helper class intended to
* initialize the translation of a TranslationTransforms
*
* This class is connected to the fixed image, moving image and transform
* involved in the registration. Two modes of operation are possible:
*
* - Geometrical,
* - Center of mass
*
* In the first mode, the geometrical centers of the images are computed.
* The distance between them is set as an initial translation. This mode
* basically assumes that the anatomical objects
* to be registered are centered in their respective images. Hence the best
* initial guess for the registration is the one that superimposes those two
* centers.
*
* In the second mode, the moments of gray level values are computed
* for both images. The vector between the two centers of
* mass is passes as the initial translation to the transform. This
* second approach assumes that the moments of the anatomical objects
* are similar for both images and hence the best initial guess for
* registration is to superimpose both mass centers. Note that this
* assumption will probably not hold in multi-modality registration.
*
* \ingroup Transforms
*/
template < class TTransform,
class TFixedImage,
class TMovingImage >
class TranslationTransformInitializer : public Object
{
public:
/** Standard class typedefs. */
typedef TranslationTransformInitializer Self;
typedef Object Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;

/** New macro for creation of through a Smart Pointer. */
itkNewMacro( Self );

/** Run-time type information (and related methods). */
itkTypeMacro( TranslationTransformInitializer, Object );

/** Type of the transform to initialize */
typedef TTransform TransformType;
typedef typename TransformType::Pointer TransformPointer;

/** Dimension of parameters. */
itkStaticConstMacro(SpaceDimension, unsigned int, TransformType::SpaceDimension);
itkStaticConstMacro(InputSpaceDimension, unsigned int, TransformType::InputSpaceDimension);
itkStaticConstMacro(OutputSpaceDimension, unsigned int, TransformType::OutputSpaceDimension);


/** Image Types to use in the initialization of the transform */
typedef TFixedImage FixedImageType;
typedef TMovingImage MovingImageType;

typedef typename FixedImageType::ConstPointer FixedImagePointer;
typedef typename MovingImageType::ConstPointer MovingImagePointer;

/** Moment calculators */
typedef ImageMomentsCalculator< FixedImageType > FixedImageCalculatorType;
typedef ImageMomentsCalculator< MovingImageType > MovingImageCalculatorType;

typedef typename FixedImageCalculatorType::Pointer FixedImageCalculatorPointer;
typedef typename MovingImageCalculatorType::Pointer MovingImageCalculatorPointer;

/** Point type. */
typedef typename TransformType::InputPointType InputPointType;

/** Vector type. */
typedef typename TransformType::OutputVectorType OutputVectorType;

/** Set the transform to be initialized */
itkSetObjectMacro( Transform, TransformType );

/** Set the fixed image used in the registration process */
itkSetConstObjectMacro( FixedImage, FixedImageType );

/** Set the moving image used in the registration process */
itkSetConstObjectMacro( MovingImage, MovingImageType );


/** Initialize the transform using data from the images */
virtual void InitializeTransform() const;

/** Select between using the geometrical center of the images or
using the center of mass given by the image intensities. */
void GeometryOn() { m_UseMoments = false; }
void MomentsOn() { m_UseMoments = true; }

/** Get() access to the moments calculators */
itkGetConstObjectMacro( FixedCalculator, FixedImageCalculatorType );
itkGetConstObjectMacro( MovingCalculator, MovingImageCalculatorType );

protected:
TranslationTransformInitializer();
~TranslationTransformInitializer(){};

void PrintSelf(std::ostream &os, Indent indent) const;

private:
TranslationTransformInitializer(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented

TransformPointer m_Transform;

FixedImagePointer m_FixedImage;

MovingImagePointer m_MovingImage;

bool m_UseMoments;

FixedImageCalculatorPointer m_FixedCalculator;
MovingImageCalculatorPointer m_MovingCalculator;

}; //class TranslationTransformInitializer


} // namespace itk


#ifndef ITK_MANUAL_INSTANTIATION
#include "itkTranslationTransformInitializer.hxx"
#endif

#endif /* __itkTranslationTransformInitializer_h */
185 changes: 185 additions & 0 deletions src/Common/itkTranslationTransformInitializer.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#ifndef __itkTranslationTransformInitializer_hxx
#define __itkTranslationTransformInitializer_hxx

#include "itkTranslationTransformInitializer.h"

namespace itk
{


template < class TTransform, class TFixedImage, class TMovingImage >
TranslationTransformInitializer<TTransform, TFixedImage, TMovingImage >
::TranslationTransformInitializer()
{
m_FixedCalculator = FixedImageCalculatorType::New();
m_MovingCalculator = MovingImageCalculatorType::New();
}



template < class TTransform, class TFixedImage, class TMovingImage >
void
TranslationTransformInitializer<TTransform, TFixedImage, TMovingImage >
::InitializeTransform() const
{
// Sanity check
if( !m_FixedImage )
{
itkExceptionMacro( "Fixed Image has not been set" );
return;
}
if( !m_MovingImage )
{
itkExceptionMacro( "Moving Image has not been set" );
return;
}
if( !m_Transform )
{
itkExceptionMacro( "Transform has not been set" );
return;
}

// If images come from filters, then update those filters.
if( m_FixedImage->GetSource() )
{
m_FixedImage->GetSource()->Update();
}
if( m_MovingImage->GetSource() )
{
m_MovingImage->GetSource()->Update();
}

OutputVectorType translationVector;


if( m_UseMoments )
{
m_FixedCalculator->SetImage( m_FixedImage );
m_FixedCalculator->Compute();

m_MovingCalculator->SetImage( m_MovingImage );
m_MovingCalculator->Compute();

typename FixedImageCalculatorType::VectorType fixedCenter =
m_FixedCalculator->GetCenterOfGravity();

typename MovingImageCalculatorType::VectorType movingCenter =
m_MovingCalculator->GetCenterOfGravity();

for ( unsigned int i=0; i<InputSpaceDimension; i++)
{
translationVector[i] = movingCenter[i] - fixedCenter[i];
}
}
else
{
// Here use the geometrical center of each image.

const typename FixedImageType::SpacingType&
fixedSpacing = m_FixedImage->GetSpacing();
const typename FixedImageType::PointType&
fixedOrigin = m_FixedImage->GetOrigin();

typename FixedImageType::SizeType fixedSize =
m_FixedImage->GetLargestPossibleRegion().GetSize();

typename TransformType::InputPointType centerFixed;

for( unsigned int k=0; k<InputSpaceDimension; k++ )
{
centerFixed[k] = fixedOrigin[k] + fixedSpacing[k] * fixedSize[k] / 2.0;
}


const typename MovingImageType::SpacingType&
movingSpacing = m_MovingImage->GetSpacing();
const typename MovingImageType::PointType&
movingOrigin = m_MovingImage->GetOrigin();

typename MovingImageType::SizeType movingSize =
m_MovingImage->GetLargestPossibleRegion().GetSize();

typename TransformType::InputPointType centerMoving;

for( unsigned int m=0; m<InputSpaceDimension; m++ )
{
centerMoving[m] = movingOrigin[m] + movingSpacing[m] * movingSize[m] / 2.0;
}

for( unsigned int i=0; i<InputSpaceDimension; i++)
{
translationVector[i] = centerMoving[i] - centerFixed[i];
}

}

m_Transform->SetOffset( translationVector );


}




template < class TTransform, class TFixedImage, class TMovingImage >
void
TranslationTransformInitializer<TTransform, TFixedImage, TMovingImage >
::PrintSelf(std::ostream& os, Indent indent) const
{
Superclass::PrintSelf(os,indent);

os << indent << "Transform = " << std::endl;
if (m_Transform)
{
os << indent << m_Transform << std::endl;
}
else
{
os << indent << "None" << std::endl;
}

os << indent << "FixedImage = " << std::endl;
if (m_FixedImage)
{
os << indent << m_FixedImage << std::endl;
}
else
{
os << indent << "None" << std::endl;
}

os << indent << "MovingImage = " << std::endl;
if (m_MovingImage)
{
os << indent << m_MovingImage << std::endl;
}
else
{
os << indent << "None" << std::endl;
}

os << indent << "MovingMomentCalculator = " << std::endl;
if (m_MovingCalculator)
{
os << indent << m_MovingCalculator << std::endl;
}
else
{
os << indent << "None" << std::endl;
}

os << indent << "FixedMomentCalculator = " << std::endl;
if (m_FixedCalculator)
{
os << indent << m_FixedCalculator << std::endl;
}
else
{
os << indent << "None" << std::endl;
}

}

} // namespace itk

#endif /* __itkTranslationTransformInitializer_hxx */
18 changes: 18 additions & 0 deletions src/Components/Metrics/MeanSquares/elxMeanSquaresMetric.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ using namespace itk;
* computing the metric value and its derivative in each iteration.
* Choose one of {"true", "false"}. Default is "true". \n
* example: <tt>(UseAllPixels "false")</tt> \n
* note: the NewSamplesEveryIteration parameter is ignored by this metric.\n
*
* \ingroup Metrics
*
Expand Down Expand Up @@ -113,6 +114,23 @@ using namespace itk;
*/
virtual void Initialize(void) throw (ExceptionObject);

/**
* Force the metric to base its computation on a new subset of image samples.
*
* This metric cannot respond to this function correctly. It is meant for stochastic
* optimizers, to allow them to request a refreshment of the sample set.
* However, this metric can not deal with such a request.
*
* It has two modes of operation, defined by the (UseAllPixels ...) option. If this
* parameter is set to true, all voxels in the image are used. If set to false,
* every derivative/value calculation is based on a new, randomly selected subset
* of voxels. So, if you want to combine the metric with a stochastic optimizer,
* simply set the UseAllPixels parameter to false.
*
* Therefore, this metric just silently ignores the request.
*/
virtual void SelectNewSamples(void){};

protected:

/** The constructor. */
Expand Down
Loading

0 comments on commit 1c64e2a

Please sign in to comment.