📄 itkfemregistrationfiltertest.cxx
字号:
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkFEMRegistrationFilterTest.cxx,v $
Language: C++
Date: $Date: 2003-11-30 19:08:30 $
Version: $Revision: 1.13 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#include <fstream>
#include "itkFEMRegistrationFilter.h"
#include "itkFEMImageMetricLoadImplementation.h"
#include "itkIndex.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkCommand.h"
#include "vnl/vnl_math.h"
// tyepdefs necessary for FEM visitor dispatcher
typedef unsigned char PixelType;
typedef itk::Image<PixelType,3> testImageType;
typedef itk::fem::Element3DC0LinearHexahedronMembrane ElementType;
// typedef itk::fem::Element2DC0LinearQuadrilateralMembrane ElementType;
//#ifdef USEIMAGEMETRIC
typedef itk::fem::ImageMetricLoad<testImageType,testImageType> ImageLoadType2;
//#else
typedef itk::fem::FiniteDifferenceFunctionLoad<testImageType,testImageType> ImageLoadType;
//#endif
template class itk::fem::ImageMetricLoadImplementation<ImageLoadType>;
typedef ElementType::LoadImplementationFunctionPointer LoadImpFP;
typedef ElementType::LoadType ElementLoadType;
typedef itk::fem::VisitorDispatcher<ElementType,ElementLoadType, LoadImpFP>
DispatcherType;
// Template function to fill in an image with a value
template <class TImage>
void
FillImage(
TImage * image,
typename TImage::PixelType value )
{
typedef itk::ImageRegionIteratorWithIndex<TImage> Iterator;
Iterator it( image, image->GetBufferedRegion() );
it.Begin();
for( ; !it.IsAtEnd(); ++it )
{
it.Set( value );
}
}
// Template function to fill in an image with a circle.
template <class TImage>
void
FillWithCircle(
TImage * image,
double * center,
double radius,
typename TImage::PixelType foregnd,
typename TImage::PixelType backgnd )
{
typedef itk::ImageRegionIteratorWithIndex<TImage> Iterator;
Iterator it( image, image->GetBufferedRegion() );
it.Begin();
typename TImage::IndexType index;
double r2 = vnl_math_sqr( radius );
for( ; !it.IsAtEnd(); ++it )
{
index = it.GetIndex();
double distance = 0;
for( unsigned int j = 0; j < TImage::ImageDimension; j++ )
{
distance += vnl_math_sqr((double) index[j] - center[j]);
}
if( distance <= r2 ) it.Set( foregnd );
else it.Set( backgnd );
}
}
// Template function to copy image regions
template <class TImage>
void
CopyImageBuffer(
TImage *input,
TImage *output )
{
typedef itk::ImageRegionIteratorWithIndex<TImage> Iterator;
Iterator inIt( input, output->GetBufferedRegion() );
Iterator outIt( output, output->GetBufferedRegion() );
for( ; !inIt.IsAtEnd(); ++inIt, ++outIt )
{
outIt.Set( inIt.Get() );
}
}
int itkFEMRegistrationFilterTest(int, char* [] )
{
const unsigned int ImageDimension = 3;
typedef itk::Vector<float,ImageDimension> VectorType;
typedef itk::Image<VectorType,ImageDimension> FieldType;
typedef itk::Image<VectorType::ValueType,ImageDimension> FloatImageType;
typedef testImageType::IndexType IndexType;
typedef testImageType::SizeType SizeType;
typedef testImageType::RegionType RegionType;
//--------------------------------------------------------
std::cout << "Generate input images and initial deformation field";
std::cout << std::endl;
unsigned long sizeArray[ImageDimension] = { 32, 32, 32 };
SizeType size;
size.SetSize( sizeArray );
IndexType index;
index.Fill( 0 );
RegionType region;
region.SetSize( size );
region.SetIndex( index );
testImageType::Pointer moving = testImageType::New();
testImageType::Pointer fixed = testImageType::New();
FieldType::Pointer initField = FieldType::New();
moving->SetLargestPossibleRegion( region );
moving->SetBufferedRegion( region );
moving->Allocate();
fixed->SetLargestPossibleRegion( region );
fixed->SetBufferedRegion( region );
fixed->Allocate();
initField->SetLargestPossibleRegion( region );
initField->SetBufferedRegion( region );
initField->Allocate();
double center[ImageDimension];
double radius;
PixelType fgnd = 250;
PixelType bgnd = 15;
// fill moving with circle
center[0] = 16; center[1] = 16; center[2] = 16;radius = 5;
FillWithCircle<testImageType>( moving, center, radius, fgnd, bgnd );
// fill fixed with circle
center[0] = 16; center[1] = 16; center[2] = 16; radius = 8;
FillWithCircle<testImageType>( fixed, center, radius, fgnd, bgnd );
// fill initial deformation with zero vectors
VectorType zeroVec;
zeroVec.Fill( 0.0 );
FillImage<FieldType>( initField, zeroVec );
//-------------------------------------------------------------
std::cout << "Run registration and warp moving" << std::endl;
// register the elements with visitor dispatcher
{
typedef itk::fem::ImageMetricLoadImplementation<ImageLoadType> iml;
ElementType::LoadImplementationFunctionPointer fp = &iml::ImplementImageMetricLoad;
DispatcherType::RegisterVisitor((ImageLoadType*)0,fp);
}
for (int met=0; met<6; met++)
{
typedef itk::fem::FEMRegistrationFilter<testImageType,testImageType> RegistrationType;
RegistrationType::Pointer registrator = RegistrationType::New();
registrator->SetFixedImage( fixed );
registrator->SetMovingImage( moving );
registrator->DoMultiRes(true);
registrator->SetNumLevels(1);
registrator->SetMaxLevel(1);
registrator->SetMovingImage( moving );
registrator->SetFixedImage( fixed );
// registrator->SetTemp(1.0);
registrator->ChooseMetric((float)met);
unsigned int maxiters=5;
float e=1.e6;
float p=1.e5;
// std::cout << " input num iters, e, p: "; std::cin >> maxiters >> e >> p;
registrator->SetElasticity(e,0);
registrator->SetRho(p,0);
registrator->SetGamma(1.,0);
registrator->SetAlpha(1.);
registrator->SetMaximumIterations( maxiters,0 );
registrator->SetMeshPixelsPerElementAtEachResolution(4,0);
registrator->SetWidthOfMetricRegion(0 ,0);
if ( met == 0 || met == 5)
registrator->SetWidthOfMetricRegion(0 ,0);
else
registrator->SetWidthOfMetricRegion(1 ,0);
registrator->SetNumberOfIntegrationPoints(2,0);
registrator->SetDescentDirectionMinimize();
registrator->SetDescentDirectionMaximize();
registrator->DoLineSearch(false);
registrator->SetTimeStep(1.);
if (met == 0)
{
registrator->DoLineSearch((int)2);
registrator->EmployRegridding(true);
}
else
{
registrator->DoLineSearch((int)0);
registrator->EmployRegridding(false);
}
registrator->UseLandmarks(false);
itk::fem::MaterialLinearElasticity::Pointer m;
m=itk::fem::MaterialLinearElasticity::New();
m->GN=0; // Global number of the material ///
m->E=registrator->GetElasticity(); // Young modulus -- used in the membrane ///
m->A=1.0; // Crossection area ///
m->h=1.0; // Crossection area ///
m->I=1.0; // Moment of inertia ///
m->nu=0.; //.0; // poissons -- DONT CHOOSE 1.0!!///
m->RhoC=1.0;
// Create the element type
ElementType::Pointer e1 = ElementType::New();
e1->m_mat=dynamic_cast<itk::fem::MaterialLinearElasticity*>( m );
registrator->SetElement(e1);
registrator->SetMaterial(m);
registrator->Print( std::cout );
try
{
// Register the images
registrator->RunRegistration();
}
catch(... )
{
//fixme - changes to femparray cause it to fail : old version works
std::cout << "Caught an exception: " << std::endl;
delete e1;
delete m;
return EXIT_FAILURE;
// std::cout << err << std::endl;
//throw err;
}
delete e1;
delete m;
}
/*
// get warped reference image
// ---------------------------------------------------------
std::cout << "Compare warped moving and fixed." << std::endl;
// compare the warp and fixed images
itk::ImageRegionIterator<ImageType> fixedIter( fixed,
fixed->GetBufferedRegion() );
itk::ImageRegionIterator<ImageType> warpedIter( registrator->GetWarpedImage(),
fixed->GetBufferedRegion() );
unsigned int numPixelsDifferent = 0;
while( !fixedIter.IsAtEnd() )
{
if( fixedIter.Get() != warpedIter.Get() )
{
numPixelsDifferent++;
}
++fixedIter;
++warpedIter;
}
std::cout << "Number of pixels different: " << numPixelsDifferent;
std::cout << std::endl;
if( numPixelsDifferent > 400 )
{
std::cout << "Test failed - too many pixels different." << std::endl;
return EXIT_FAILURE;
}
std::cout << "Test passed" << std::endl;
*/
return EXIT_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -