17 #ifndef __itkFEMRegistrationFilter_txx
18 #define __itkFEMRegistrationFilter_txx
22 #pragma warning(disable: 4786)
42 #include "vnl/algo/vnl_determinant.h"
48 template<
class TMovingImage,
class TFixedImage>
54 template<
class TMovingImage,
class TFixedImage>
60 m_MinE=vnl_huge_val(m_MinE);
63 m_DescentDirection=positive;
66 m_Gamma[m_CurrentLevel]=1;
70 m_Maxiters.set_size(1);
71 m_Maxiters[m_CurrentLevel]=1;
75 m_MeshPixelsPerElementAtEachResolution.set_size(1);
76 m_NumberOfIntegrationPoints.set_size(1);
77 m_NumberOfIntegrationPoints[m_CurrentLevel]=4;
78 m_MetricWidth.set_size(1);
79 m_MetricWidth[m_CurrentLevel]=3;
80 m_DoLineSearchOnImageEnergy=1;
81 m_LineSearchMaximumIterations=100;
96 for (
unsigned int i=0; i < ImageDimension; i++)
99 m_CurrentImageScaling[i]=1;
100 m_FullImageSize[i]=0;
110 DefaultInterpolatorType::New();
121 template<
class TMovingImage,
class TFixedImage>
125 if (!m_DoMultiRes && m_Maxiters[m_CurrentLevel] > 0)
129 mySolver.
SetRho(m_Rho[m_CurrentLevel]);
131 CreateMesh(static_cast<double>(m_MeshPixelsPerElementAtEachResolution[m_CurrentLevel]),
132 mySolver,m_FullImageSize);
133 ApplyLoads(mySolver,m_FullImageSize);
135 const unsigned int ndofpernode=(m_Element)->GetNumberOfDegreesOfFreedomPerNode();
136 const unsigned int numnodesperelt=(m_Element)->GetNumberOfNodes()+1;
141 nzelts=numnodesperelt*ndofpernode*ndof;
145 nzelts=((2*numnodesperelt*ndofpernode*ndof > 25*ndof) ? 2*numnodesperelt*ndofpernode*ndof : 25*ndof);
155 if( m_UseMassMatrix )
164 IterativeSolve(mySolver);
174 if (m_TotalField) m_Field=m_TotalField;
175 this->ComputeJacobian(1.,m_Field,2.5);
176 WarpImage(m_OriginalMovingImage);
181 template<
class TMovingImage,
class TFixedImage>
185 if (m_TotalIterations == 0)
187 m_OriginalMovingImage=R;
191 template<
class TMovingImage,
class TFixedImage>
195 m_FullImageSize = m_FixedImage->GetLargestPossibleRegion().GetSize();
198 for (
unsigned int i=0; i < ImageDimension; i++)
205 m_CurrentLevelImageSize=m_FullImageSize;
210 template<
class TMovingImage,
class TFixedImage>
217 #ifdef USEIMAGEMETRIC
220 typedef itk::PatternIntensityImageToImageMetric<FixedImageType,MovingImageType> MetricType2;
229 MetricType3::Pointer m=MetricType3::New();
230 MetricType4::Pointer ma=MetricType4::New();
232 unsigned int whichmetric=(
unsigned int) which;
236 for (
int i=0; i<ImageDimension; i++)
238 nsp *= m_MetricWidth[m_CurrentLevel];
240 if (whichmetric == 3 )
242 m->SetNumberOfSpatialSamples(nsp/2);
243 m->SetFixedImageStandardDeviation(0.4);
244 m->SetMovingImageStandardDeviation(0.4);
246 else if (whichmetric == 4 )
248 ma->SetNumberOfHistogramBins( 10 );
249 ma->SetNumberOfSpatialSamples( nsp/2 );
255 m_Metric=MetricType0::New();
256 m_Metric->SetScaleGradient(m_Temp);
261 m_Metric=MetricType1::New();
262 m_Metric->SetScaleGradient(m_Temp);
265 m_Metric=MetricType2::New();
266 m_Metric->SetScaleGradient(m_Temp);
270 m_Metric->SetScaleGradient(m_Temp);
274 m_Metric->SetScaleGradient(m_Temp);
277 m_Metric=MetricType5::New();
278 m_Metric->SetScaleGradient(m_Temp);
281 m_Metric=MetricType0::New();
282 m_Metric->SetScaleGradient(m_Temp);
294 typename MetricType3::Pointer m=MetricType3::New();
295 typename MetricType4::Pointer ma=MetricType4::New();
297 unsigned int whichmetric=(
unsigned int) which;
298 m_WhichMetric=(
unsigned int)which;
303 m_Metric=MetricType0::New();
306 m_Metric=MetricType1::New();
309 m_Metric=MetricType2::New();
318 m_Metric=MetricType5::New();
321 m_Metric=MetricType0::New();
325 m_Metric->SetGradientStep( m_Gamma[m_CurrentLevel] );
326 if ( m_Temp == 1.0 ) m_Metric->SetNormalizeGradient(
true);
327 else m_Metric->SetNormalizeGradient(
false);
331 template<
class TMovingImage,
class TFixedImage>
337 char buffer[4096] = {
'\0'};
339 unsigned int ibuf = 0;
342 std::cout <<
"Reading config file..." << fname << std::endl;
347 this->DoMultiRes(
true);
351 this->m_NumLevels = (
unsigned int) ibuf;
355 this->m_MaxLevel = ibuf;
359 for (jj=0; jj<ImageDimension; jj++)
362 m_ImageScaling[jj] = ibuf;
365 this->m_MeshPixelsPerElementAtEachResolution.set_size(m_NumLevels);
367 for (jj=0; jj<this->m_NumLevels; jj++)
370 this->m_MeshPixelsPerElementAtEachResolution(jj) = ibuf;
374 this->m_E.set_size(m_NumLevels);
375 for (jj=0; jj<this->m_NumLevels; jj++)
378 this->SetElasticity(fbuf,jj);
382 this->m_Rho.set_size(m_NumLevels);
383 for (jj=0; jj<this->m_NumLevels; jj++)
386 this->SetRho(fbuf,jj);
390 this->m_Gamma.set_size(m_NumLevels);
391 for (jj=0; jj<this->m_NumLevels; jj++)
394 this->SetGamma(fbuf,jj);
398 this->m_NumberOfIntegrationPoints.set_size(m_NumLevels);
399 for(jj=0; jj< m_NumLevels; jj++)
402 this->SetNumberOfIntegrationPoints(ibuf,jj);
406 this->m_MetricWidth.set_size(m_NumLevels);
407 for(jj=0; jj< m_NumLevels; jj++)
410 this->SetWidthOfMetricRegion(ibuf,jj);
414 this->m_Maxiters.set_size(m_NumLevels);
415 for (jj=0; jj<this->m_NumLevels; jj++)
418 this->SetMaximumIterations(ibuf,jj);
426 this->ChooseMetric(fbuf);
436 this->SetDescentDirectionMinimize();
440 this->SetDescentDirectionMaximize();
445 this->DoLineSearch(ibuf);
449 this->SetTimeStep(fbuf);
453 this->SetEnergyReductionFactor(fbuf);
457 m_EmployRegridding = (
unsigned int) ibuf;
461 this->m_FullImageSize[0] = ibuf;
465 this->m_FullImageSize[1] = ibuf;
471 if (dim == 3) this->m_FullImageSize[2] = ibuf;
475 this->SetMovingFile(buffer);
479 this->SetFixedFile(buffer);
488 this->UseLandmarks(
true);
489 this->SetLandmarkFile(buffer);
493 this->UseLandmarks(
false);
498 this->SetResultsFile(buffer);
507 this->SetWriteDisplacements(
true);
508 this->SetDisplacementsFile(buffer);
512 this->SetWriteDisplacements(
false);
522 this->m_ReadMeshFile=
true;
523 this->m_MeshFileName=buffer;
527 this->m_ReadMeshFile=
false;
531 std::cout <<
"Example configured. E " << m_E <<
" rho " << m_Rho << std::endl;
536 std::cout <<
"No configuration file specified...quitting.\n";
541 template<
class TMovingImage,
class TFixedImage>
546 std::cout <<
"Writing multi-component displacement vector field...";
549 typename FieldWriterType::Pointer fieldWriter = FieldWriterType::New();
551 fieldWriter->SetInput( m_Field );
552 fieldWriter->SetFileName(
"VectorDeformationField.mhd");
555 fieldWriter->Update();
559 std::cerr <<
"Error while saving the displacement vector field" << std::endl;
560 std::cerr << excp << std::endl;
563 std::cout <<
"done" << std::endl;
567 template<
class TMovingImage,
class TFixedImage>
573 fieldCaster->SetInput( m_Field );
574 fieldCaster->SetIndex( index );
578 fieldCaster->Update();
579 fieldImage = fieldCaster->GetOutput();
582 std::string outfile=m_DisplacementsFileName+
static_cast<char>(
'x'+index)+std::string(
"vec.mhd");
583 std::cout <<
"Writing displacements to " << outfile;
588 typename WriterType::Pointer writer = WriterType::New();
589 writer->SetInput(fieldImage);
590 writer->SetFileName(outfile.c_str());
593 std::cout <<
" ...done" << std::endl;
597 template<
class TMovingImage,
class TFixedImage>
601 std::cout <<
"Warping image" << std::endl;
613 typename InterpolatorType1::Pointer interpolator = InterpolatorType1::New();
615 warper = WarperType::New();
616 warper->SetInput( ImageToWarp );
617 warper->SetDeformationField( m_Field );
618 warper->SetInterpolator( interpolator );
619 warper->SetOutputOrigin( m_FixedImage->GetOrigin() );
620 warper->SetOutputSpacing( m_FixedImage->GetSpacing() );
621 warper->SetOutputDirection( m_FixedImage->GetDirection() );
622 typename FixedImageType::PixelType padValue = 0;
623 warper->SetEdgePaddingValue( padValue );
626 m_WarpedImage=warper->GetOutput();
631 template<
class TMovingImage,
class TFixedImage>
640 for (
unsigned int i=0; i<ImageDimension; i++)
642 MeshSizeV[i]=(double)imagesize[i];
644 MeshOriginV[i]=(double)m_ImageOrigin[i];
645 ImageSizeV[i]=(double) imagesize[i]+1;
646 ElementsPerDim[i]=MeshSizeV[i]/PixelsPerElement;
650 std::cout <<
" ElementsPerDim " << ElementsPerDim << std::endl;
654 std::ifstream meshstream;
655 meshstream.open(m_MeshFileName.c_str());
658 std::cout<<
"File "<<m_MeshFileName<<
" not found!\n";
662 mySolver.
Read(meshstream);
668 m->
E=this->GetElasticity(m_CurrentLevel);
673 Node::ArrayType::iterator node=nodes->begin();
674 m_Element=( *((*node)->m_elements.begin()));
675 for(node=nodes->begin(); node != nodes->end(); node++)
677 coord = (*node)->GetCoordinates();
678 for (
unsigned int ii = 0; ii < ImageDimension; ii++)
680 coord[ii] = coord[ii]/(float)m_CurrentImageScaling[ii];
682 (*node)->SetCoordinates(coord);
685 else if (ImageDimension == 2 && dynamic_cast<Element2DC0LinearQuadrilateral*>(m_Element) !=
NULL)
687 m_Material->E = this->GetElasticity(m_CurrentLevel);
691 std::cout <<
" init interpolation grid : im sz " << ImageSizeV <<
" MeshSize " << MeshSizeV << std::endl;
693 std::cout <<
" done initializing interpolation grid " << std::endl;
695 else if ( ImageDimension == 3 && dynamic_cast<Element3DC0LinearHexahedron*>(m_Element) !=
NULL)
697 m_Material->E = this->GetElasticity(m_CurrentLevel);
699 std::cout <<
" generating regular mesh " << std::endl;
702 std::cout <<
" generating regular mesh done " << std::endl;
704 std::cout <<
" DO NOT init interpolation grid : im sz " << ImageSizeV <<
" MeshSize " << MeshSizeV << std::endl;
719 template<
class TMovingImage,
class TFixedImage>
724 m_Load->SetMovingImage(movingimg);
725 m_Load->SetFixedImage(fixedimg);
726 if (!m_Field) this->InitializeField();
727 #ifndef USEIMAGEMETRIC
728 m_Load->SetDeformationField(this->GetDeformationField());
730 m_Load->SetMetric(m_Metric);
731 m_Load->InitializeMetric();
732 m_Load->SetTemp(m_Temp);
733 m_Load->SetGamma(m_Gamma[m_CurrentLevel]);
735 for (
unsigned int dd = 0; dd < ImageDimension; dd++)
737 r[dd] = m_MetricWidth[m_CurrentLevel];
739 m_Load->SetMetricRadius(r);
740 m_Load->SetNumberOfIntegrationPoints(m_NumberOfIntegrationPoints[m_CurrentLevel]);
741 m_Load->GN = mySolver.
load.size()+1;
742 m_Load->SetSign((
Float)m_DescentDirection);
748 template<
class TMovingImage,
class TFixedImage>
755 std::cout <<
" applying loads " << std::endl;
763 LoadArray::iterator loaditerator;
766 if ( this->m_LandmarkArray.empty() )
770 std::cout << m_LandmarkFileName << std::endl;
771 f.open(m_LandmarkFileName.c_str());
775 std::cout <<
"Try loading landmarks..." << std::endl;
776 std::cout <<
"Try loading landmarks..." << std::endl;
779 mySolver.
load.clear();
784 std::cerr <<
"Exception: cannot read load landmark FEMRegistrationFilter.txx " << err;
788 m_LandmarkArray.resize(mySolver.
load.size());
790 for(loaditerator = mySolver.
load.begin(); loaditerator != mySolver.
load.end(); loaditerator++)
792 if ((l3 = dynamic_cast<LoadLandmark*>( &(*(*loaditerator)) )) != 0 )
795 m_LandmarkArray[ct] = l4;
800 mySolver.
load.clear();
804 std::cout <<
"no landmark file specified." << std::endl;
812 std::cout <<
" num of LM loads " << m_LandmarkArray.size() << std::endl;
816 if ( !m_LandmarkArray.empty())
818 for(
unsigned int lmind = 0; lmind<m_LandmarkArray.size(); lmind++)
821 m_LandmarkArray[lmind]->el[0] =
NULL;
822 bool isFound =
false;
823 std::cout <<
" prescale Pt " << m_LandmarkArray[lmind]->GetTarget() << std::endl;
826 m_LandmarkArray[lmind]->ScalePointAndForce(scaling,m_EnergyReductionFactor);
827 std::cout <<
" postscale Pt " << m_LandmarkArray[lmind]->GetTarget() <<
" scale " << scaling[0] << std::endl;
830 pu = m_LandmarkArray[lmind]->GetSource();
831 pd = m_LandmarkArray[lmind]->GetPoint();
833 for (Element::ArrayType::const_iterator n = mySolver.
el.begin();
834 n != mySolver.
el.end() && !isFound; n++)
836 if ( (*n)->GetLocalFromGlobalCoordinates(pu, pd ) )
839 m_LandmarkArray[lmind]->SetPoint(pd);
840 m_LandmarkArray[lmind]->el[0] = ( ( &**n ) );
844 m_LandmarkArray[lmind]->GN = lmind;
849 std::cout <<
" landmarks done" << std::endl;
856 unsigned int CornerCounter,ii,EdgeCounter = 0;
859 Node::ArrayType::iterator node = nodes->begin();
861 unsigned int nodect = 0;
862 while(node != nodes->end() && EdgeCounter < ImageDimension )
864 coord = (*node)->GetCoordinates();
866 for (ii = 0; ii < ImageDimension; ii++)
868 if (coord[ii] == m_ImageOrigin[ii] || coord[ii] == ImgSz[ii]-1 ) CornerCounter++;
870 if (CornerCounter == ImageDimension)
872 unsigned int ndofpernode=(*((*node)->m_elements.begin()))->GetNumberOfDegreesOfFreedomPerNode();
873 unsigned int numnodesperelt=(*((*node)->m_elements.begin()))->GetNumberOfNodes();
874 unsigned int whichnode;
876 unsigned int maxnode=numnodesperelt-1;
879 for( NodeEltSetType::iterator elt = (*node)->m_elements.begin();
880 elt != (*node)->m_elements.end(); elt++)
882 for (whichnode=0; whichnode<=maxnode; whichnode++)
884 coord=(*elt)->GetNode(whichnode)->GetCoordinates();
887 for (ii=0; ii < ImageDimension; ii++)
889 if (coord[ii] == m_ImageOrigin[ii] || coord[ii] == ImgSz[ii]-1 )
894 if (CornerCounter == ImageDimension - 1)
904 for (
unsigned int jj=0; jj<ndofpernode; jj++)
906 std::cout <<
" which node " << whichnode << std::endl;
907 std::cout <<
" edge coord " << coord << std::endl;
912 l1->m_element= (*elt);
914 unsigned int localdof=whichnode*ndofpernode+jj;
926 std::cout <<
" node " << nodect << std::endl;
932 template<
class TMovingImage,
class TFixedImage>
937 std::cout <<
" m_Load not initialized " << std::endl;
942 unsigned int iters=0;
945 while ( !Done && iters < m_Maxiters[m_CurrentLevel] )
947 const Float lastdeltE=deltE;
948 const unsigned int DLS=m_DoLineSearchOnImageEnergy;
951 Float LastE=m_Load->GetCurrentEnergy();
952 m_Load->SetCurrentEnergy(0.0);
953 m_Load->InitializeMetric();
957 std::cout <<
" Big Error -- Field is NULL ";
962 if( m_UseMassMatrix )
971 m_Load->PrintCurrentEnergy();
984 #ifndef USEIMAGEMETRIC
985 if (m_DescentDirection == 1)
987 deltE=(LastE - m_Load->GetCurrentEnergy());
991 deltE=(m_Load->GetCurrentEnergy() - LastE );
994 if (m_DescentDirection == 1)
996 deltE=(m_Load->GetCurrentEnergy() - LastE );
1000 deltE=(LastE - m_Load->GetCurrentEnergy());
1004 if ( DLS==2 && deltE < 0.0 )
1006 std::cout <<
" line search ";
1007 const float tol = 1.0;
1008 LastE=this->GoldenSection(mySolver,tol,m_LineSearchMaximumIterations);
1009 deltE=(m_MinE-LastE);
1010 std::cout <<
" line search done " << std::endl;
1017 std::cout <<
" no change in energy " << std::endl;
1020 if ( (DLS == 0) && ( iters >= m_Maxiters[m_CurrentLevel] ) )
1024 else if ((DLS > 0) &&
1025 ( iters >= m_Maxiters[m_CurrentLevel] || (deltE < 0.0 && iters > 5 && lastdeltE < 0.0)))
1034 Float mint= m_Gamma[m_CurrentLevel]/curmaxsol;
1047 InterpolateVectorField(mySolver);
1050 if (m_EmployRegridding != 0)
1052 if ( iters % m_EmployRegridding == 0 )
1054 this->EnforceDiffeomorphism(1.0, mySolver,
true);
1064 std::cout <<
" min E " << m_MinE <<
" delt E " << deltE <<
" iter " << iters << std::endl;
1065 m_TotalIterations++;
1069 template<
class TMovingImage,
class TFixedImage>
1074 std::cout <<
" allocating deformation field " << std::endl;
1076 m_Field = FieldType::New();
1078 m_FieldRegion.SetSize(m_CurrentLevelImageSize );
1079 m_Field->SetOrigin( m_FixedImage->GetOrigin() );
1080 m_Field->SetSpacing( m_FixedImage->GetSpacing() );
1081 m_Field->SetDirection( m_FixedImage->GetDirection() );
1082 m_Field->SetLargestPossibleRegion( m_FieldRegion );
1083 m_Field->SetBufferedRegion( m_FieldRegion );
1084 m_Field->SetLargestPossibleRegion( m_FieldRegion );
1085 m_Field->Allocate();
1088 for (
unsigned int t=0; t<ImageDimension; t++)
1094 for(; !fieldIter.
IsAtEnd(); ++fieldIter )
1096 fieldIter.
Set(disp);
1100 template<
class TMovingImage,
class TFixedImage>
1109 this->InitializeField();
1111 m_FieldSize=field->GetLargestPossibleRegion().GetSize();
1113 std::cout <<
" interpolating vector field of size " << m_FieldSize;
1115 Float rstep,sstep,tstep;
1123 for (
unsigned int t=0; t<ImageDimension; t++)
1127 FieldIterator fieldIter( field, field->GetLargestPossibleRegion() );
1130 typename FixedImageType::IndexType rindex = fieldIter.GetIndex();
1132 Sol.set_size(ImageDimension);
1133 Gpt.set_size(ImageDimension);
1135 if (ImageDimension == 2)
1139 for(; !fieldIter.IsAtEnd(); ++fieldIter )
1142 rindex = fieldIter.GetIndex();
1143 for(
unsigned int d=0; d<ImageDimension; d++)
1145 Gpt[d]=(double)rindex[d];
1156 for(
unsigned int f=0; f<ImageDimension; f++)
1159 for(
unsigned int n=0; n<Nnodes; n++)
1165 disp[f] =(
Float) 1.0*Sol[f];
1167 field->SetPixel(rindex, disp );
1172 if (ImageDimension==3)
1175 rstep=1.25/((double)m_MeshPixelsPerElementAtEachResolution[m_CurrentLevel]);
1176 sstep=1.25/((double)m_MeshPixelsPerElementAtEachResolution[m_CurrentLevel]);
1177 tstep=1.25/((double)m_MeshPixelsPerElementAtEachResolution[m_CurrentLevel]);
1180 Pos.set_size(ImageDimension);
1181 for( Element::ArrayType::iterator elt=mySolver.
el.begin(); elt != mySolver.
el.end(); elt++)
1183 for (
double r=-1.0; r <= 1.0; r=r+rstep )
1185 for (
double s=-1.0; s <= 1.0; s=s+sstep )
1187 for (
double t=-1.0; t <= 1.0; t=t+tstep )
1193 unsigned int Nnodes= (*elt)->GetNumberOfNodes();
1199 shapef[0] = (1 - r) * (1 - s) * (1 - t) * 0.125;
1200 shapef[1] = (1 + r) * (1 - s) * (1 - t) * 0.125;
1201 shapef[2] = (1 + r) * (1 + s) * (1 - t) * 0.125;
1202 shapef[3] = (1 - r) * (1 + s) * (1 - t) * 0.125;
1203 shapef[4] = (1 - r) * (1 - s) * (1 + t) * 0.125;
1204 shapef[5] = (1 + r) * (1 - s) * (1 + t) * 0.125;
1205 shapef[6] = (1 + r) * (1 + s) * (1 + t) * 0.125;
1206 shapef[7] = (1 - r) * (1 + s) * (1 + t) * 0.125;
1208 shapef = (*elt)->ShapeFunctions(Pos);
1211 Float solval,posval;
1216 for(
unsigned int f=0; f<ImageDimension; f++)
1220 for(
unsigned int n=0; n<Nnodes; n++)
1222 posval += shapef[n]*(((*elt)->GetNodeCoordinates(n))[f]);
1231 if (x != 0) temp=(
long int) ((x)+0.5);
else temp=0;
1233 disp[f] =(
Float) 1.0*Sol[f];
1234 if ( temp < 0 || temp > (
long int) m_FieldSize[f]-1) inimage=
false;
1237 if (inimage) field->SetPixel(rindex, disp );
1247 std::cout <<
" interpolation done " << std::endl;
1250 template<
class TMovingImage,
class TFixedImage>
1266 if ( !m_FloatImage && jproduct)
1268 std::cout <<
" allocating m_FloatImage " << std::endl;
1269 m_FloatImage = FloatImageType::New();
1272 m_FloatImage->Allocate();
1276 for(; !wimIter.IsAtEnd(); ++wimIter )
1283 jMatrix.set_size(ImageDimension,ImageDimension);
1286 typename FixedImageType::IndexType rindex;
1287 typename FixedImageType::IndexType ddrindex;
1288 typename FixedImageType::IndexType ddlindex;
1290 typename FixedImageType::IndexType difIndex[ImageDimension][2];
1292 std:: cout <<
" get jacobian " << std::endl;
1295 unsigned int posoff=1;
1306 for( fieldIter.GoToBegin(); !fieldIter.IsAtEnd(); ++fieldIter )
1310 bool oktosample=
true;
1313 for(row=0; row< ImageDimension;row++)
1315 difIndex[row][0]=rindex;
1316 difIndex[row][1]=rindex;
1320 static_cast<typename FixedImageType::IndexType::IndexValueType>(m_FieldSize[row]-2) )
1322 difIndex[row][0][row]=rindex[row]+posoff;
1323 ddrindex[row]=rindex[row]+posoff*2;
1324 }
else oktosample=
false;
1325 if (rindex[row] > 1 )
1327 difIndex[row][1][row]=rindex[row]-1;
1328 ddlindex[row]=rindex[row]-2;
1329 }
else oktosample=
false;
1334 rpix = field->
GetPixel(difIndex[row][1]);
1335 rpix = rpix*h+cpix*(1.-h);
1336 lpix = field->
GetPixel(difIndex[row][0]);
1337 lpix = lpix*h+cpix*(1.-h);
1338 dPix = ( rpix - lpix)*sign*space/(2.0);
1339 for(col=0; col< ImageDimension;col++)
1342 if (row == col) val=dPix[col]+1.0;
1343 else val = dPix[col];
1344 jMatrix.put(row,col,val);
1349 det = (float) vnl_determinant(jMatrix);
1350 if (det < 0.) det=0.0;
1351 if ( jproduct && oktosample )
1352 m_FloatImage->SetPixel(rindex, m_FloatImage->GetPixel(rindex)*det );
1355 if (det < m_MinJacobian) m_MinJacobian=det;
1358 std::cout <<
" min Jacobian " << m_MinJacobian << std::endl;
1360 if (jproduct && m_FloatImage && smooth > 0)
1364 typename DGF::Pointer filter = DGF::New();
1365 filter->SetVariance(smooth);
1366 filter->SetMaximumError(.01f);
1367 filter->SetInput(m_FloatImage);
1369 m_FloatImage=filter->GetOutput();
1374 template<
class TMovingImage,
class TFixedImage>
1376 SolverType& mySolver ,
bool onlywriteimages )
1381 std::cout <<
" Checking Jacobian ";
1382 this->ComputeJacobian(1.,
NULL);
1383 if (m_MinJacobian < thresh)
1385 std::cout <<
" Enforcing diffeomorphism " << std::endl;
1390 for (
unsigned int ef=0; ef<ImageDimension; ef++)
1393 ((
float) m_FullImageSize[ef]/(float)m_CurrentLevelImageSize[ef]);
1394 expandFactors[ef]=factor;
1395 if (factor != 1.) resize=
true;
1398 fullField=ExpandVectorField(expandFactors,m_Field);
1399 else fullField=m_Field;
1413 typename InterpolatorType1::Pointer interpolator = InterpolatorType1::New();
1419 std::cout <<
" warping landmarks " << m_LandmarkArray.size() << std::endl;
1421 if(!m_LandmarkArray.empty())
1423 for(
unsigned int lmind=0; lmind<m_LandmarkArray.size(); lmind++)
1425 std::cout <<
" old source " << m_LandmarkArray[lmind]->GetSource() <<
" target " << m_LandmarkArray[lmind]->GetTarget() << std::endl;
1428 m_LandmarkArray[lmind]->GetSource()=m_LandmarkArray[lmind]->GetSource()+
1430 std::cout <<
" new source " << m_LandmarkArray[lmind]->GetSource() <<
" target " << m_LandmarkArray[lmind]->GetTarget() << std::endl;
1436 std::cout <<
" warping landmarks done " << std::endl;
1437 }
else std::cout <<
" landmark array empty " << std::endl;
1441 if (!m_TotalField && !onlywriteimages)
1443 std::cout <<
" allocating total deformation field " << std::endl;
1445 m_TotalField = FieldType::New();
1447 m_FieldRegion.SetSize(fullField->GetLargestPossibleRegion().GetSize() );
1448 m_TotalField->SetLargestPossibleRegion( m_FieldRegion );
1449 m_TotalField->SetBufferedRegion( m_FieldRegion );
1450 m_TotalField->SetLargestPossibleRegion( m_FieldRegion );
1451 m_TotalField->Allocate();
1454 for (
unsigned int t=0; t<ImageDimension; t++)
1460 for(; !fieldIter.
IsAtEnd(); ++fieldIter )
1462 fieldIter.
Set(disp);
1466 if (onlywriteimages)
1468 warper = WarperType::New();
1469 warper->SetInput( m_OriginalMovingImage );
1470 warper->SetDeformationField( fullField );
1471 warper->SetInterpolator( interpolator );
1472 warper->SetOutputOrigin( m_FixedImage->GetOrigin() );
1473 warper->SetOutputSpacing( m_FixedImage->GetSpacing() );
1474 warper->SetOutputDirection( m_FixedImage->GetDirection() );
1475 typename MovingImageType::PixelType padValue = 0;
1476 warper->SetEdgePaddingValue( padValue );
1478 m_WarpedImage=warper->GetOutput();
1480 else if (m_TotalField)
1487 InterpolatedType interpolatedValue;
1489 m_Interpolator->SetInputImage(fullField);
1491 typename FixedImageType::IndexType index;
1492 FieldIterator totalFieldIter( m_TotalField, m_TotalField->GetLargestPossibleRegion() );
1495 float pathsteplength=0;
1496 while( !totalFieldIter.IsAtEnd() )
1498 index=totalFieldIter.GetIndex();
1499 for (jj=0; jj<ImageDimension; jj++)
1501 inputIndex[jj]=(WarperCoordRepType) index[jj];
1502 interpolatedValue[jj]=0.0;
1504 if( m_Interpolator->IsInsideBuffer( inputIndex ) )
1508 m_Interpolator->EvaluateAtContinuousIndex( inputIndex );
1513 for (jj = 0; jj < ImageDimension; jj++)
1515 interped[jj] = interpolatedValue[jj];
1516 temp += interped[jj]*interped[jj];
1518 pathsteplength += vcl_sqrt(temp);
1519 m_TotalField->SetPixel(index,m_TotalField->GetPixel(index)+interped);
1522 std::cout <<
" incremental path length " << pathsteplength << std::endl;
1528 FieldIterator fieldIter( m_Field, m_Field->GetLargestPossibleRegion() );
1530 while( !fieldIter.IsAtEnd() )
1534 fieldIter.Set(disp);
1541 for( Node::ArrayType::iterator node=nodes->begin(); node != nodes->end(); node++)
1544 for (ii=0; ii < ImageDimension; ii++)
1554 warper = WarperType::New();
1555 warper->SetInput( m_OriginalMovingImage );
1556 warper->SetDeformationField( m_TotalField );
1557 warper->SetInterpolator( interpolator );
1558 warper->SetOutputOrigin( m_FixedImage->GetOrigin() );
1559 warper->SetOutputSpacing( m_FixedImage->GetSpacing() );
1560 warper->SetOutputDirection( m_FixedImage->GetDirection() );
1561 typename FixedImageType::PixelType padValue = 0;
1562 warper->SetEdgePaddingValue( padValue );
1567 this->SetMovingImage( warper->GetOutput() );
1569 m_WarpedImage=m_MovingImage;
1576 std::cout <<
" re-doing pyramid " << std::endl;
1578 m_MovingPyramid =
NULL;
1579 m_MovingPyramid = FixedPyramidType::New();
1580 m_MovingPyramid->SetInput( m_MovingImage);
1581 m_MovingPyramid->SetNumberOfLevels( 1 );
1583 ScheduleType SizeReductionMoving=m_MovingPyramid->GetSchedule();
1586 for (jj=0; jj<ImageDimension; jj++)
1588 unsigned int scale=m_ImageScaling[jj]/(
unsigned int)vcl_pow(2.0,(
double)ii);
1589 if (scale < 1) scale=1;
1590 SizeReductionMoving[0][jj]=scale;
1593 m_MovingPyramid->SetSchedule(SizeReductionMoving);
1594 m_MovingPyramid->GetOutput( 0 )->Update();
1595 m_Load->SetMovingImage(m_MovingPyramid->GetOutput(0));
1597 std::cout <<
" re-doing pyramid done " << std::endl;
1601 m_Load->SetMovingImage(this->GetMovingImage( ));
1604 std::cout <<
" Enforcing diffeomorphism done " << std::endl;
1608 template<
class TMovingImage,
class TFixedImage>
1614 std::string exte=
".mhd";
1618 buf<<(m_FileCount+10);
1619 fnum=std::string(buf.str().c_str());
1621 std::string fullfname=(fname+fnum+exte);
1623 if (!m_WarpedImage)
return;
1626 typename MinMaxFilterType::Pointer minMaxFilter = MinMaxFilterType::New();
1627 minMaxFilter->SetInput( m_WarpedImage );
1628 minMaxFilter->Update();
1629 float min = minMaxFilter->GetMinimum();
1630 double shift = -1.0 *
static_cast<double>( min );
1631 double scale =
static_cast<double>( minMaxFilter->GetMaximum() );
1633 scale = 255.0 / scale;
1636 filter->SetInput( m_WarpedImage );
1637 filter->SetShift( shift );
1638 filter->SetScale( scale );
1642 typedef unsigned char PIX;
1645 typename CasterType1::Pointer caster1 = CasterType1::New();
1646 caster1->SetInput(filter->GetOutput());
1650 writer->SetFileName(fullfname.c_str());
1651 writer->SetInput(caster1->GetOutput() );
1658 template<
class TMovingImage,
class TFixedImage>
1663 if (!field) field=m_Field;
1666 <<
" expand factors ";
1668 for (
unsigned int i=0; i< ImageDimension; i++)
1671 std::cout << expandFactors[i] <<
" ";
1673 std::cout << std::endl;
1675 m_FieldExpander->SetInput(field);
1676 m_FieldExpander->SetExpandFactors( expandFactors );
1678 m_FieldExpander->SetEdgePaddingValue( pad );
1679 m_FieldExpander->UpdateLargestPossibleRegion();
1681 m_FieldSize=m_FieldExpander->GetOutput()->GetLargestPossibleRegion().GetSize();
1683 return m_FieldExpander->GetOutput();
1686 template<
class TMovingImage,
class TFixedImage>
1697 m_Interpolator->SetInputImage(m_Field);
1699 for( Node::ArrayType::iterator node=nodes->begin(); node != nodes->end(); node++)
1701 coord=(*node)->GetCoordinates();
1704 InterpolatedType interpolatedValue;
1707 for (
unsigned int jj=0; jj<ImageDimension; jj++)
1710 interpolatedValue[jj]=0.0;
1712 if( m_Interpolator->IsInsideBuffer( inputIndex ) )
1715 m_Interpolator->EvaluateAtContinuousIndex( inputIndex );
1718 for (
unsigned int jj=0; jj<ImageDimension; jj++)
1720 SolutionAtNode[jj]=interpolatedValue[jj];
1724 for (ii=0; ii < ImageDimension; ii++)
1726 Float Sol=SolutionAtNode[ii];
1736 template<
class TMovingImage,
class TFixedImage>
1739 FieldIterator fieldIter( m_Field, m_Field->GetLargestPossibleRegion() );
1744 while( !fieldIter.IsAtEnd() )
1747 if ((ct % modnum) == 0) std::cout <<
" field pix " << fieldIter.Get() << std::endl;
1748 for (
unsigned int i=0; i<ImageDimension;i++)
1750 if (vcl_fabs(disp[i]) > max )
1752 max=vcl_fabs(disp[i]);
1759 std::cout <<
" max vec " << max << std::endl;
1762 template<
class TMovingImage,
class TFixedImage>
1771 for (m_CurrentLevel=0; m_CurrentLevel<m_MaxLevel; m_CurrentLevel++)
1773 std::cout <<
" beginning level " << m_CurrentLevel << std::endl;
1777 typename FixedImageType::SizeType nextLevelSize;
1778 nextLevelSize.Fill( 0 );
1779 typename FixedImageType::SizeType lastLevelSize;
1781 if (m_Maxiters[m_CurrentLevel] > 0)
1786 m_MovingPyramid = FixedPyramidType::New();
1787 m_FixedPyramid = FixedPyramidType::New();
1789 m_MovingPyramid->SetInput( m_MovingImage);
1790 m_FixedPyramid->SetInput( m_FixedImage);
1793 m_MovingPyramid->SetNumberOfLevels( 1 );
1794 m_FixedPyramid->SetNumberOfLevels( 1 );
1796 ScheduleType SizeReductionMoving=m_MovingPyramid->GetSchedule();
1797 ScheduleType SizeReductionFixed=m_FixedPyramid->GetSchedule();
1799 unsigned int ii=m_CurrentLevel;
1800 for (
unsigned int jj=0; jj<ImageDimension; jj++)
1802 unsigned int scale=m_ImageScaling[jj]/(
unsigned int)vcl_pow(2.0,(
double)ii);
1803 unsigned int nextscale = m_ImageScaling[jj]/(
unsigned int)vcl_pow(2.0,(
double)(ii+1));
1804 if (scale < 1) scale=1;
1805 if (nextscale < 1) nextscale=1;
1806 SizeReductionMoving[0][jj]=scale;
1807 SizeReductionFixed[0][jj]=scale;
1808 nextLevelSize[jj]=(
long int) ( (
float) m_FullImageSize[jj] / (float) nextscale );
1811 m_MovingPyramid->SetSchedule(SizeReductionMoving);
1812 m_FixedPyramid->SetSchedule(SizeReductionFixed);
1813 m_MovingPyramid->GetOutput( 0 )->Update();
1814 m_FixedPyramid->GetOutput( 0 )->Update();
1816 lastLevelSize=m_CurrentLevelImageSize;
1817 m_CurrentLevelImageSize=m_FixedPyramid->GetOutput( 0 )->GetLargestPossibleRegion().GetSize();
1818 if (m_CurrentLevel == m_MaxLevel-1) nextLevelSize=m_CurrentLevelImageSize;
1820 double scaling[ImageDimension];
1821 for (
unsigned int d=0; d < ImageDimension; d++)
1823 m_CurrentImageScaling[d]=SizeReductionMoving[0][d];
1824 if (m_CurrentLevel == 0) scaling[d]=(double)SizeReductionMoving[0][d];
1825 else scaling[d]=(double) lastLevelSize[d]/(
double) m_CurrentLevelImageSize[d];
1826 std::cout <<
" scaling " << scaling[d] << std::endl;
1828 double MeshResolution=(double)this->m_MeshPixelsPerElementAtEachResolution(m_CurrentLevel);
1831 SSS.
SetRho(m_Rho[m_CurrentLevel]);
1834 CreateMesh(MeshResolution,SSS,m_CurrentLevelImageSize);
1835 ApplyLoads(SSS,m_CurrentLevelImageSize,scaling);
1836 ApplyImageLoads(SSS,m_MovingPyramid->GetOutput(0),
1837 m_FixedPyramid->GetOutput(0));
1839 m_MovingPyramid = FixedPyramidType::New();
1840 m_FixedPyramid = FixedPyramidType::New();
1844 unsigned int ndofpernode=(m_Element)->GetNumberOfDegreesOfFreedomPerNode();
1845 unsigned int numnodesperelt=(m_Element)->GetNumberOfNodes()+1;
1847 unsigned int nzelts;
1848 if (!m_ReadMeshFile) nzelts=numnodesperelt*ndofpernode*ndof;
1849 else nzelts=((2*numnodesperelt*ndofpernode*ndof > 25*ndof) ? 2*numnodesperelt*ndofpernode*ndof : 25*ndof);
1859 if( m_UseMassMatrix )
1868 if (m_CurrentLevel > 0)
1870 this->SampleVectorFieldAtNodes(SSS);
1872 this->IterativeSolve(SSS);
1876 if ( m_CurrentLevel == m_MaxLevel-1 && m_Field)
1878 PrintVectorField(900000);
1879 std:: cout <<
" field size " << m_Field->GetLargestPossibleRegion().GetSize() << std::endl;
1882 else if (m_CurrentLevel < m_MaxLevel-1 && m_Field)
1885 for (
unsigned int ef=0; ef<ImageDimension; ef++)
1888 ((
float) nextLevelSize[ef]/(float)m_CurrentLevelImageSize[ef]);
1890 m_Field=ExpandVectorField(expandFactors,m_Field);
1892 PrintVectorField(900000);
1893 std:: cout <<
" field size " << m_Field->GetLargestPossibleRegion().GetSize() << std::endl;
1897 std::cout <<
" end level " << m_CurrentLevel;
1904 std::cout <<
" copy field " << m_TotalField->GetLargestPossibleRegion().GetSize()
1905 <<
" to " << m_Field->GetLargestPossibleRegion().GetSize() << std::endl;
1906 FieldIterator fieldIter( m_TotalField, m_TotalField->GetLargestPossibleRegion() );
1908 for(; !fieldIter.IsAtEnd(); ++fieldIter )
1910 typename FixedImageType::IndexType index = fieldIter.GetIndex();
1911 m_TotalField->SetPixel(index,m_TotalField->GetPixel(index)
1912 + m_Field->GetPixel(index));
1918 template<
class TMovingImage,
class TFixedImage>
1921 Float SimE=m_Load->EvaluateMetricGivenSolution(&(mySolver.
el),t);
1924 for (
unsigned int i=0; i< ImageDimension; i++)
1926 maxsim *= (
Float)m_FullImageSize[i];
1928 if ( m_WhichMetric != 0)
1932 return vcl_fabs(static_cast<double>(SimE));
1935 template<
class TMovingImage,
class TFixedImage>
1940 const Float Gold=1.618034;
1941 const Float Glimit=100.0;
1942 const Float Tiny=1.e-20;
1945 Float fa=vcl_fabs(EvaluateResidual(mySolver, ax));
1946 Float fb=vcl_fabs(EvaluateResidual(mySolver, bx));
1951 dum=ax; ax=bx; bx=dum;
1952 dum=fb; fb=fa; fa=dum;
1955 Float cx=bx+Gold*(bx-ax);
1956 Float fc=vcl_fabs(EvaluateResidual(mySolver, cx));
1958 Float ulim,u,r,q,fu;
1965 u=(bx)-((bx-cx)*q-(bx-ax)*r)/denom;
1966 ulim=bx + Glimit*(cx-bx);
1967 if ((bx-u)*(u-cx) > 0.0)
1969 fu=vcl_fabs(EvaluateResidual(mySolver, u));
1974 *a=ax; *b=bx; *c=cx;
1980 *a=ax; *b=bx; *c=cx;
1985 fu=vcl_fabs(EvaluateResidual(mySolver, u));
1988 else if ( (cx-u)*(u-ulim) > 0.0)
1990 fu=vcl_fabs(EvaluateResidual(mySolver, u));
1993 bx=cx; cx=u; u=cx+Gold*(cx-bx);
1994 fb=fc; fc=fu; fu=vcl_fabs(EvaluateResidual(mySolver, u));
1998 else if ( (u-ulim)*(ulim-cx) >= 0.0)
2001 fu=vcl_fabs(EvaluateResidual(mySolver, u));
2006 fu=vcl_fabs(EvaluateResidual(mySolver, u));
2010 fa=fb; fb=fc; fc=fu;
2014 if ( vcl_fabs(ax) > 1.e3 || vcl_fabs(bx) > 1.e3 || vcl_fabs(cx) > 1.e3)
2016 ax=-2.0; bx=1.0; cx=2.0;
2019 *a=ax; *b=bx; *c=cx;
2024 template<
class TMovingImage,
class TFixedImage>
2030 FindBracketingTriplet(mySolver,&ax, &bx, &cx);
2032 const Float R=0.6180339;
2033 const Float C=(1.0-R);
2039 if (vcl_fabs(cx-bx) > vcl_fabs(bx-ax))
2050 Float f1=vcl_fabs(EvaluateResidual(mySolver, x1));
2051 Float f2=vcl_fabs(EvaluateResidual(mySolver, x2));
2052 unsigned int iters=0;
2053 while (vcl_fabs(x3-x0) > tol*(vcl_fabs(x1)+vcl_fabs(x2)) && iters < MaxIters)
2058 x0=x1; x1=x2; x2=R*x1+C*x3;
2059 f1=f2; f2=vcl_fabs(EvaluateResidual(mySolver, x2));
2063 x3=x2; x2=x1; x1=R*x2+C*x0;
2064 f2=f1; f1=vcl_fabs(EvaluateResidual(mySolver, x1));
2080 std:: cout <<
" emin " << fmin <<
" at xmin " << xmin << std::endl;
2081 return vcl_fabs(static_cast<double>(fmin));
2084 template<
class TMovingImage,
class TFixedImage>
2088 Superclass::PrintSelf( os, indent );
2092 os << indent <<
"Load = " << m_Load;
2096 os << indent <<
"Load = " <<
"(None)" << std::endl;
2100 os << indent <<
"Interpolator = " << m_Interpolator;
2104 os << indent <<
"Interpolator = " <<
"(None)" << std::endl;