📄 itkmattesmutualinformationimagetoimagemetrictest.cxx
字号:
typename MovingImageType::Pointer imgMoving = MovingImageType::New();
imgMoving->SetLargestPossibleRegion( region );
imgMoving->SetBufferedRegion( region );
imgMoving->SetRequestedRegion( region );
imgMoving->Allocate();
imgMoving->SetSpacing( imgSpacing );
imgMoving->SetOrigin( imgOrigin );
typename FixedImageType::Pointer imgFixed = FixedImageType::New();
imgFixed->SetLargestPossibleRegion( region );
imgFixed->SetBufferedRegion( region );
imgFixed->SetRequestedRegion( region );
imgFixed->Allocate();
imgFixed->SetSpacing( imgSpacing );
imgFixed->SetOrigin( imgOrigin );
// Fill images with a 2D gaussian
typedef itk::ImageRegionIterator<MovingImageType>
ReferenceIteratorType;
typedef itk::ImageRegionIterator<FixedImageType>
TargetIteratorType;
itk::Point<double,2> center;
center[0] = (double)region.GetSize()[0]/2.0;
center[1] = (double)region.GetSize()[1]/2.0;
const double s = (double)region.GetSize()[0]/2.0;
itk::Point<double,2> p;
itk::Vector<double,2> d;
// Set the displacement
itk::Vector<double,2> displacement;
displacement[0] = 5;
displacement[1] = 5;
ReferenceIteratorType ri(imgMoving,region);
TargetIteratorType ti(imgFixed,region);
ri.Begin();
while(!ri.IsAtEnd())
{
p[0] = ri.GetIndex()[0];
p[1] = ri.GetIndex()[1];
d = p-center;
d += displacement;
const double x = d[0];
const double y = d[1];
ri.Set( (unsigned char) ( 200.0 * exp( - ( x*x + y*y )/(s*s) ) ) );
++ri;
}
ti.Begin();
while(!ti.IsAtEnd())
{
p[0] = ti.GetIndex()[0];
p[1] = ti.GetIndex()[1];
d = p-center;
const double x = d[0];
const double y = d[1];
ti.Set( (unsigned char) ( 200.0 * exp( - ( x*x + y*y )/(s*s) ) ) );
++ti;
}
//-----------------------------------------------------------
// Set up a transformer
//-----------------------------------------------------------
typedef itk::BSplineDeformableTransform<
double, ImageDimension, 3 > TransformType;
typedef typename TransformType::ParametersType ParametersType;
typename TransformType::Pointer transformer = TransformType::New();
// set up a 3x3 region
typename TImage::SizeType gridSize;
typename TImage::RegionType gridRegion;
gridSize.Fill( 7 );
gridRegion.SetSize( gridSize );
transformer->SetGridRegion( gridRegion );
typedef itk::Point<double,ImageDimension> PointType;
PointType startPosition;
PointType endPosition;
itk::Offset<ImageDimension> offset;
index = imgFixed->GetBufferedRegion().GetIndex();
imgFixed->TransformIndexToPhysicalPoint( index, startPosition );
index += imgFixed->GetBufferedRegion().GetSize();
offset.Fill( 1 );
index -= offset;
imgFixed->TransformIndexToPhysicalPoint( index, endPosition );
typename TransformType::SpacingType spacing;
typename TransformType::OriginType origin;
for( unsigned int j = 0; j < ImageDimension; j++ )
{
spacing[j] = ( endPosition[j] - startPosition[j] ) /
static_cast<double>( gridSize[j] - 3 );
origin[j] = -1.0 * spacing[j];
}
transformer->SetGridSpacing( spacing );
transformer->SetGridOrigin( origin );
transformer->Print( std::cout );
//------------------------------------------------------------
// Set up the metric
//------------------------------------------------------------
typedef itk::MattesMutualInformationImageToImageMetric<
FixedImageType, MovingImageType > MetricType;
typename MetricType::Pointer metric = MetricType::New();
// connect the interpolator
metric->SetInterpolator( interpolator );
// connect the transform
metric->SetTransform( transformer );
// connect the images to the metric
metric->SetFixedImage( imgFixed );
metric->SetMovingImage( imgMoving );
// set the number of histogram bins
metric->SetNumberOfHistogramBins( 50 );
metric->SetUseExplicitPDFDerivatives( useExplicitJointPDFDerivatives );
metric->SetUseCachingOfBSplineWeights( useCachingBSplineWeights );
if( useSampling )
{
// set the number of samples to use
metric->SetNumberOfSpatialSamples( 500 );
}
else
{
metric->UseAllPixelsOn();
}
// set the region over which to compute metric
metric->SetFixedImageRegion( imgFixed->GetBufferedRegion() );
// initialize the metric before use
metric->Initialize();
//------------------------------------------------------------
// Set up a B-spline deformable transform parameters
//------------------------------------------------------------
unsigned int numberOfParameters = transformer->GetNumberOfParameters();
ParametersType parameters( numberOfParameters );
parameters.Fill( 0.0 );
//---------------------------------------------------------
// Print out mutual information values
// for parameters between {-10,10} (arbitrary choice)
//---------------------------------------------------------
typename MetricType::MeasureType measure, measure2;
typename MetricType::DerivativeType derivative( numberOfParameters );
unsigned int q = numberOfParameters / 4;
std::cout << "q = " << q << std::endl;
std::cout << "param[q]\tMI\tMI2\tdMI/dparam[q]" << std::endl;
for( double trans = -10; trans <= 5; trans += 0.5 )
{
// parameters[q] = trans;
parameters.Fill( trans );
metric->GetValueAndDerivative( parameters, measure, derivative );
measure2 = metric->GetValue( parameters );
std::cout << trans << "\t" << measure << "\t" <<
measure2 << "\t" << derivative[q] <<std::endl;
// exercise the other functions
metric->GetDerivative( parameters, derivative );
}
//---------------------------------------------------------
// Check output gradients for numerical accuracy
//---------------------------------------------------------
parameters.Fill( 4.5 * imgSpacing[0] );
metric->GetValueAndDerivative( parameters, measure, derivative );
ParametersType parametersPlus( numberOfParameters );
ParametersType parametersMinus( numberOfParameters );
typename MetricType::MeasureType measurePlus;
typename MetricType::MeasureType measureMinus;
double delta = 0.01 * imgSpacing[0];
bool testFailed = false;
for( unsigned int i = 0; i < numberOfParameters; ++i )
{
//copy the parameters and perturb the current one.
for( unsigned int j = 0; j < numberOfParameters; ++j )
{
if( j == i )
{
parametersPlus[j] = parameters[i] + delta; //positive perturbation
parametersMinus[j] = parameters[i] - delta; //negative perturbation
}
else
{
parametersPlus[j] = parameters[j];
parametersMinus[j] = parameters[j];
}
}
measurePlus = metric->GetValue( parametersPlus );
measureMinus = metric->GetValue( parametersMinus );
double approxDerivative = ( measurePlus - measureMinus ) / ( 2 * delta );
double ratio = derivative[i]/approxDerivative;
std::cout << i << "\t";
std::cout << parameters[i] << "\t";
std::cout << derivative[i] << "\t";
std::cout << approxDerivative << "\t";
std::cout << ratio << "\t";
std::cout << std::endl;
if ( vnl_math_abs( ratio - 1.0 ) > 0.01 && vnl_math_abs( derivative[i] ) > 1e-4 )
{
std::cout << "computed derivative differ from central difference." << std::endl;
testFailed = true;
}
}
if( testFailed )
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int itkMattesMutualInformationImageToImageMetricTest(int argc, char * argv [] )
{
bool useExplicitJointPDFDerivatives = true;
bool useCachingBSplineWeights = true;
if( argc > 1 )
{
useExplicitJointPDFDerivatives = atoi( argv[1] );
}
if( argc > 2 )
{
useCachingBSplineWeights = atoi( argv[2] );
}
int failed;
typedef itk::Image<unsigned char,2> ImageType;
bool useSampling = true;
itk::OutputWindow::SetInstance(itk::TextOutput::New().GetPointer());
// Test metric with a linear interpolator
typedef itk::LinearInterpolateImageFunction< ImageType, double >
LinearInterpolatorType;
LinearInterpolatorType::Pointer linearInterpolator
= LinearInterpolatorType::New();
failed = TestMattesMetricWithAffineTransform<ImageType,LinearInterpolatorType>(
linearInterpolator, useSampling, useExplicitJointPDFDerivatives, useCachingBSplineWeights );
if ( failed )
{
std::cout << "Test failed" << std::endl;
return EXIT_FAILURE;
}
useSampling = false;
failed = TestMattesMetricWithAffineTransform<ImageType,LinearInterpolatorType>(
linearInterpolator, useSampling, useExplicitJointPDFDerivatives, useCachingBSplineWeights );
if ( failed )
{
std::cout << "Test failed when using all the pixels instead of sampling" << std::endl;
return EXIT_FAILURE;
}
// Test metric with a BSpline interpolator
typedef itk::BSplineInterpolateImageFunction< ImageType, double >
BSplineInterpolatorType;
BSplineInterpolatorType::Pointer bSplineInterpolator
= BSplineInterpolatorType::New();
bSplineInterpolator->SetSplineOrder( 3 );
useSampling = true;
failed = TestMattesMetricWithAffineTransform<ImageType,BSplineInterpolatorType>(
bSplineInterpolator, useSampling, useExplicitJointPDFDerivatives, useCachingBSplineWeights );
if ( failed )
{
std::cout << "Test failed" << std::endl;
return EXIT_FAILURE;
}
useSampling = false;
failed = TestMattesMetricWithAffineTransform<ImageType,BSplineInterpolatorType>(
bSplineInterpolator, useSampling, useExplicitJointPDFDerivatives, useCachingBSplineWeights );
if ( failed )
{
std::cout << "Test failed when using all the pixels instead of sampling" << std::endl;
return EXIT_FAILURE;
}
// Test metric with BSpline deformable transform
useSampling = true;
failed = TestMattesMetricWithBSplineDeformableTransform<
ImageType,BSplineInterpolatorType>( bSplineInterpolator, useSampling,
useExplicitJointPDFDerivatives, useCachingBSplineWeights );
if ( failed )
{
std::cout << "Test failed" << std::endl;
return EXIT_FAILURE;
}
// Test metric with BSpline deformable transform and using all the pixels
//
// We know this test particular combination is not working yet,
// but we left the test here in order to help with the debugging.
//
/*
std::cout << "Test metric with BSpline deformable transform and using all the pixels" << std::endl;
useSampling = false;
failed = TestMattesMetricWithBSplineDeformableTransform<
ImageType,BSplineInterpolatorType>( bSplineInterpolator, useSampling );
if ( failed )
{
std::cout << "Test failed when using all the pixels instead of sampling" << std::endl;
return EXIT_FAILURE;
}
*/
std::cout << "Test passed" << std::endl;
return EXIT_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -