1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
19 /*=========================================================================
21 Program: Insight Segmentation & Registration Toolkit
22 Module: $RCSfile: itkMeanSquaresImageToImageMetricFor3DBLUTFFD.txx,v $
24 Date: $Date: 2010/06/14 17:32:07 $
25 Version: $Revision: 1.1 $
27 Copyright (c) Insight Software Consortium. All rights reserved.
28 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
30 This software is distributed WITHOUT ANY WARRANTY; without even
31 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
32 PURPOSE. See the above copyright notices for more information.
34 =========================================================================*/
35 #ifndef __itkMeanSquaresImageToImageMetricFor3DBLUTFFD_txx
36 #define __itkMeanSquaresImageToImageMetricFor3DBLUTFFD_txx
38 // First make sure that the configuration is available.
39 // This line can be removed once the optimized versions
40 // gets integrated into the main directories.
41 #include "itkConfigure.h"
43 #if defined(ITK_USE_OPTIMIZED_REGISTRATION_METHODS) || ITK_VERSION_MAJOR >= 4
44 #include "itkOptMeanSquaresImageToImageMetricFor3DBLUTFFD.txx"
47 #include "itkMeanSquaresImageToImageMetricFor3DBLUTFFD.h"
48 #include "itkImageRegionConstIteratorWithIndex.h"
56 template <class TFixedImage, class TMovingImage>
57 MeanSquaresImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
58 ::MeanSquaresImageToImageMetricFor3DBLUTFFD()
60 itkDebugMacro("Constructor");
64 * Get the match Measure
66 template <class TFixedImage, class TMovingImage>
67 typename MeanSquaresImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>::MeasureType
68 MeanSquaresImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
69 ::GetValue( const TransformParametersType & parameters ) const
72 itkDebugMacro("GetValue( " << parameters << " ) ");
74 FixedImageConstPointer fixedImage = this->m_FixedImage;
77 itkExceptionMacro( << "Fixed image has not been assigned" );
80 typedef itk::ImageRegionConstIteratorWithIndex<FixedImageType> FixedIteratorType;
83 FixedIteratorType ti( fixedImage, this->GetFixedImageRegion() );
85 typename FixedImageType::IndexType index;
87 MeasureType measure = NumericTraits< MeasureType >::Zero;
89 this->m_NumberOfPixelsCounted = 0;
91 this->SetTransformParameters( parameters );
93 while(!ti.IsAtEnd()) {
95 index = ti.GetIndex();
97 InputPointType inputPoint;
98 fixedImage->TransformIndexToPhysicalPoint( index, inputPoint );
100 if( this->m_FixedImageMask && !this->m_FixedImageMask->IsInside( inputPoint ) ) {
105 OutputPointType transformedPoint = this->m_Transform->TransformPoint( inputPoint );
107 if( this->m_MovingImageMask && !this->m_MovingImageMask->IsInside( transformedPoint ) ) {
112 if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
113 const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
114 const RealType fixedValue = ti.Get();
115 this->m_NumberOfPixelsCounted++;
116 const RealType diff = movingValue - fixedValue;
117 measure += diff * diff;
123 if( !this->m_NumberOfPixelsCounted ) {
124 itkExceptionMacro(<<"All the points mapped to outside of the moving image");
126 measure /= this->m_NumberOfPixelsCounted;
134 * Get the Derivative Measure
136 template < class TFixedImage, class TMovingImage>
138 MeanSquaresImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
139 ::GetDerivative( const TransformParametersType & parameters,
140 DerivativeType & derivative ) const
143 itkDebugMacro("GetDerivative( " << parameters << " ) ");
145 if( !this->GetGradientImage() ) {
146 itkExceptionMacro(<<"The gradient image is null, maybe you forgot to call Initialize()");
149 FixedImageConstPointer fixedImage = this->m_FixedImage;
152 itkExceptionMacro( << "Fixed image has not been assigned" );
155 const unsigned int ImageDimension = FixedImageType::ImageDimension;
158 typedef itk::ImageRegionConstIteratorWithIndex<
159 FixedImageType> FixedIteratorType;
161 typedef itk::ImageRegionConstIteratorWithIndex<GradientImageType> GradientIteratorType;
164 FixedIteratorType ti( fixedImage, this->GetFixedImageRegion() );
166 typename FixedImageType::IndexType index;
168 this->m_NumberOfPixelsCounted = 0;
170 this->SetTransformParameters( parameters );
172 const unsigned int ParametersDimension = this->GetNumberOfParameters();
173 derivative = DerivativeType( ParametersDimension );
174 derivative.Fill( NumericTraits<typename DerivativeType::ValueType>::Zero );
178 while(!ti.IsAtEnd()) {
180 index = ti.GetIndex();
182 InputPointType inputPoint;
183 fixedImage->TransformIndexToPhysicalPoint( index, inputPoint );
185 if( this->m_FixedImageMask && !this->m_FixedImageMask->IsInside( inputPoint ) ) {
190 OutputPointType transformedPoint = this->m_Transform->TransformPoint( inputPoint );
192 if( this->m_MovingImageMask && !this->m_MovingImageMask->IsInside( transformedPoint ) ) {
197 if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
198 const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
200 #if ITK_VERSION_MAJOR >= 4
201 TransformJacobianType jacobian;
202 this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
204 const TransformJacobianType & jacobian =
205 this->m_Transform->GetJacobian( inputPoint );
208 const RealType fixedValue = ti.Value();
209 this->m_NumberOfPixelsCounted++;
210 const RealType diff = movingValue - fixedValue;
212 // Get the gradient by NearestNeighboorInterpolation:
213 // which is equivalent to round up the point components.
214 typedef typename OutputPointType::CoordRepType CoordRepType;
215 typedef ContinuousIndex<CoordRepType,MovingImageType::ImageDimension>
216 MovingImageContinuousIndexType;
218 MovingImageContinuousIndexType tempIndex;
219 this->m_MovingImage->TransformPhysicalPointToContinuousIndex( transformedPoint, tempIndex );
221 typename MovingImageType::IndexType mappedIndex;
222 mappedIndex.CopyWithRound( tempIndex );
224 const GradientPixelType gradient =
225 this->GetGradientImage()->GetPixel( mappedIndex );
227 for(unsigned int par=0; par<ParametersDimension; par++) {
228 RealType sum = NumericTraits< RealType >::Zero;
229 for(unsigned int dim=0; dim<ImageDimension; dim++) {
230 sum += 2.0 * diff * jacobian( dim, par ) * gradient[dim];
232 derivative[par] += sum;
239 if( !this->m_NumberOfPixelsCounted ) {
240 itkExceptionMacro(<<"All the points mapped to outside of the moving image");
242 for(unsigned int i=0; i<ParametersDimension; i++) {
243 derivative[i] /= this->m_NumberOfPixelsCounted;
251 * Get both the match Measure and theDerivative Measure
253 template <class TFixedImage, class TMovingImage>
255 MeanSquaresImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
256 ::GetValueAndDerivative(const TransformParametersType & parameters,
257 MeasureType & value, DerivativeType & derivative) const
260 itkDebugMacro("GetValueAndDerivative( " << parameters << " ) ");
262 if( !this->GetGradientImage() ) {
263 itkExceptionMacro(<<"The gradient image is null, maybe you forgot to call Initialize()");
266 FixedImageConstPointer fixedImage = this->m_FixedImage;
269 itkExceptionMacro( << "Fixed image has not been assigned" );
272 const unsigned int ImageDimension = FixedImageType::ImageDimension;
274 typedef itk::ImageRegionConstIteratorWithIndex<
275 FixedImageType> FixedIteratorType;
277 typedef itk::ImageRegionConstIteratorWithIndex<GradientImageType> GradientIteratorType;
280 FixedIteratorType ti( fixedImage, this->GetFixedImageRegion() );
282 typename FixedImageType::IndexType index;
284 MeasureType measure = NumericTraits< MeasureType >::Zero;
286 this->m_NumberOfPixelsCounted = 0;
288 this->SetTransformParameters( parameters );
290 const unsigned int ParametersDimension = this->GetNumberOfParameters();
291 derivative = DerivativeType( ParametersDimension );
292 derivative.Fill( NumericTraits<typename DerivativeType::ValueType>::Zero );
296 while(!ti.IsAtEnd()) {
298 index = ti.GetIndex();
300 InputPointType inputPoint;
301 fixedImage->TransformIndexToPhysicalPoint( index, inputPoint );
303 if( this->m_FixedImageMask && !this->m_FixedImageMask->IsInside( inputPoint ) ) {
308 OutputPointType transformedPoint = this->m_Transform->TransformPoint( inputPoint );
310 if( this->m_MovingImageMask && !this->m_MovingImageMask->IsInside( transformedPoint ) ) {
315 if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
316 const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
318 #if ITK_VERSION_MAJOR >= 4
319 TransformJacobianType jacobian;
320 this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
322 const TransformJacobianType & jacobian =
323 this->m_Transform->GetJacobian( inputPoint );
326 const RealType fixedValue = ti.Value();
327 this->m_NumberOfPixelsCounted++;
329 const RealType diff = movingValue - fixedValue;
331 measure += diff * diff;
333 // Get the gradient by NearestNeighboorInterpolation:
334 // which is equivalent to round up the point components.
335 typedef typename OutputPointType::CoordRepType CoordRepType;
336 typedef ContinuousIndex<CoordRepType,MovingImageType::ImageDimension>
337 MovingImageContinuousIndexType;
339 MovingImageContinuousIndexType tempIndex;
340 this->m_MovingImage->TransformPhysicalPointToContinuousIndex( transformedPoint, tempIndex );
342 typename MovingImageType::IndexType mappedIndex;
343 mappedIndex.CopyWithRound( tempIndex );
345 const GradientPixelType gradient =
346 this->GetGradientImage()->GetPixel( mappedIndex );
348 for(unsigned int par=0; par<ParametersDimension; par++) {
349 RealType sum = NumericTraits< RealType >::Zero;
350 for(unsigned int dim=0; dim<ImageDimension; dim++) {
351 sum += 2.0 * diff * jacobian( dim, par ) * gradient[dim];
353 derivative[par] += sum;
360 if( !this->m_NumberOfPixelsCounted ) {
361 itkExceptionMacro(<<"All the points mapped to outside of the moving image");
363 for(unsigned int i=0; i<ParametersDimension; i++) {
364 derivative[i] /= this->m_NumberOfPixelsCounted;
366 measure /= this->m_NumberOfPixelsCounted;
373 } // end namespace itk