17 #ifndef __itkKappaStatisticImageToImageMetric_txx
18 #define __itkKappaStatisticImageToImageMetric_txx
30 template <
class TFixedImage,
class TMovingImage>
34 itkDebugMacro(
"Constructor");
36 this->SetComputeGradient(
true );
37 m_ForegroundValue = 255;
45 template <
class TFixedImage,
class TMovingImage>
50 itkDebugMacro(
"GetValue( " << parameters <<
" ) ");
52 this->SetTransformParameters( parameters );
60 itkExceptionMacro( <<
"Fixed image has not been assigned" );
67 typename FixedImageType::IndexType fixedIndex;
68 FixedIteratorType fi( fixedImage, fixedImage->GetBufferedRegion() );
76 itkExceptionMacro( <<
"Moving image has not been assigned" );
89 MeasureType intersection = NumericTraits< MeasureType >::Zero;
90 MeasureType movingForegroundArea = NumericTraits< MeasureType >::Zero;
91 MeasureType fixedForegroundArea = NumericTraits< MeasureType >::Zero;
99 fixedIndex = fi.GetIndex();
102 fixedImage->TransformIndexToPhysicalPoint( fixedIndex, fixedInputPoint );
104 if( this->m_FixedImageMask && !this->m_FixedImageMask->IsInside( fixedInputPoint ) )
110 const RealType fixedValue = fi.Get();
115 if (fixedValue==m_ForegroundValue)
117 fixedForegroundArea++;
125 transformedPoint = this->m_Transform->TransformPoint( fixedInputPoint );
127 if( this->m_MovingImageMask && !this->m_MovingImageMask->IsInside( transformedPoint ) )
136 if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) )
138 const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
139 if (movingValue==m_ForegroundValue)
141 movingForegroundArea++;
143 if ((movingValue==m_ForegroundValue)&&(fixedValue==m_ForegroundValue))
156 measure = 2.0*(intersection)/(fixedForegroundArea+movingForegroundArea);
160 measure = 1.0-2.0*(intersection)/(fixedForegroundArea+movingForegroundArea);
170 template <
class TFixedImage,
class TMovingImage>
176 itkDebugMacro(
"GetDerivative( " << parameters <<
" ) ");
178 if( !this->GetGradientImage() )
180 itkExceptionMacro(<<
"The gradient image is null, maybe you forgot to call Initialize()");
186 itkExceptionMacro( <<
"Fixed image has not been assigned" );
189 const unsigned int ImageDimension = FixedImageType::ImageDimension;
193 FixedIteratorType ti( fixedImage, this->GetFixedImageRegion() );
195 typename FixedImageType::IndexType index;
197 this->m_NumberOfPixelsCounted = 0;
199 this->SetTransformParameters( parameters );
201 const unsigned int ParametersDimension = this->GetNumberOfParameters();
203 derivative.
Fill( NumericTraits<ITK_TYPENAME DerivativeType::ValueType>::Zero );
207 ArrayType sum1 = ArrayType( ParametersDimension );
208 sum1.Fill( NumericTraits<ITK_TYPENAME ArrayType::ValueType>::Zero );
210 ArrayType sum2 = ArrayType( ParametersDimension );
211 sum2.Fill( NumericTraits<ITK_TYPENAME ArrayType::ValueType>::Zero );
215 int intersection = 0;
220 index = ti.GetIndex();
223 fixedImage->TransformIndexToPhysicalPoint( index, inputPoint );
225 if( this->m_FixedImageMask && !this->m_FixedImageMask->IsInside( inputPoint ) )
231 const RealType fixedValue = ti.Value();
232 if ( fixedValue == m_ForegroundValue )
237 OutputPointType transformedPoint = this->m_Transform->TransformPoint( inputPoint );
239 if( this->m_MovingImageMask && !this->m_MovingImageMask->IsInside( transformedPoint ) )
245 if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) )
247 const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
249 if ( movingValue == m_ForegroundValue )
254 if (( movingValue == m_ForegroundValue )&&( fixedValue == m_ForegroundValue ))
260 this->m_Transform->GetJacobian( inputPoint );
262 this->m_NumberOfPixelsCounted++;
268 MovingImageContinuousIndexType;
270 MovingImageContinuousIndexType tempIndex;
271 this->m_MovingImage->TransformPhysicalPointToContinuousIndex( transformedPoint, tempIndex );
273 typename MovingImageType::IndexType mappedIndex;
274 mappedIndex.CopyWithRound( tempIndex );
276 const GradientPixelType gradient = this->m_GradientImage->GetPixel( mappedIndex );
278 for(
unsigned int par=0; par<ParametersDimension; par++)
280 for(
unsigned int dim=0; dim<ImageDimension; dim++)
282 sum2[par] += jacobian( dim, par )*gradient[dim];
283 if ( fixedValue == m_ForegroundValue )
285 sum1[par] += 2.0*jacobian( dim, par )*gradient[dim];
293 if( !this->m_NumberOfPixelsCounted )
295 itkExceptionMacro(<<
"All the points mapped to outside of the moving image");
299 double areaSum = double(fixedArea)+double(movingArea);
300 for(
unsigned int par=0; par<ParametersDimension; par++)
302 derivative[par] = -(areaSum*sum1[par]-2.0*intersection*sum2[par])/(areaSum*areaSum);
311 template <
class TFixedImage,
class TMovingImage>
316 const unsigned int dim = MovingImageType::ImageDimension;
319 tempGradientImage->SetRegions( this->m_MovingImage->GetBufferedRegion().GetSize() );
320 tempGradientImage->Allocate();
321 tempGradientImage->Update();
326 GradientIteratorType git( tempGradientImage, tempGradientImage->GetBufferedRegion() );
327 MovingIteratorType mit( this->m_MovingImage, this->m_MovingImage->GetBufferedRegion() );
332 typename MovingImageType::IndexType minusIndex;
333 typename MovingImageType::IndexType plusIndex;
334 typename MovingImageType::IndexType currIndex;
336 typename MovingImageType::SizeType movingSize = this->m_MovingImage->GetBufferedRegion().GetSize();
337 while(!mit.IsAtEnd())
339 currIndex = mit.GetIndex();
340 minusIndex = mit.GetIndex();
341 plusIndex = mit.GetIndex();
342 for (
unsigned int i=0; i<dim; i++ )
344 if ((currIndex[i] == 0) ||
345 (static_cast<typename MovingImageType::SizeType::SizeValueType>(currIndex[i]) == (movingSize[i]-1)))
347 tempGradPixel[i] = 0;
351 minusIndex[i] = currIndex[i]-1;
352 plusIndex[i] = currIndex[i]+1;
353 double minusVal = double(this->m_MovingImage->GetPixel(minusIndex));
354 double plusVal = double(this->m_MovingImage->GetPixel(plusIndex));
355 if ((minusVal != m_ForegroundValue)&&(plusVal == m_ForegroundValue))
357 tempGradPixel[i] = 1;
359 else if ((minusVal == m_ForegroundValue)&&(plusVal != m_ForegroundValue))
361 tempGradPixel[i] = -1;
365 tempGradPixel[i] = 0;
368 minusIndex = currIndex;
369 plusIndex = currIndex;
371 git.Set( tempGradPixel );
376 this->m_GradientImage = tempGradientImage;
382 template <
class TFixedImage,
class TMovingImage>
388 Value = this->GetValue( parameters );
389 this->GetDerivative( parameters, Derivative );
396 template <
class TFixedImage,
class TMovingImage>
401 Superclass::PrintSelf( os, indent );
402 os << indent <<
"Complement: " << (m_Complement ?
"On" :
"Off") << std::endl;
403 os << indent <<
"ForegroundValue: " << m_ForegroundValue << std::endl;