cmtkFunctionalAffine2D.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 2004-2010 SRI International
00004 //
00005 //  Copyright 1997-2009 Torsten Rohlfing
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2398 $
00026 //
00027 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include "cmtkFunctionalAffine2D.h"
00034 
00035 #include <System/cmtkConsole.h>
00036 
00037 #include <Base/cmtkScalarImage.h>
00038 #include <Base/cmtkMathUtil.h>
00039 
00040 #include <Registration/cmtkTypedArraySimilarity.h>
00041 #include <Registration/cmtkScalarImageSimilarity.h>
00042 
00043 #include <IO/cmtkPGM.h>
00044 
00045 namespace
00046 cmtk
00047 {
00048 
00051 
00052 FunctionalAffine2D::FunctionalAffine2D
00053 ( ScalarImage::SmartPtr& refImage, ScalarImage::SmartPtr& fltImage, const ScalarImage::RegionType* fltROI ) 
00054   : m_NumberDOFs( 6 ),
00055     m_SimilarityMeasure( ScalarImageSimilarity::MI ),
00056     m_HistogramEqualization( false ),
00057     Parameters( 8 )
00058 {
00059   RefImages.push_back( refImage );
00060   FltImages.push_back( fltImage );
00061 
00062   if ( fltROI ) 
00063     {
00064     this->FltImagesROI.push_back( ScalarImage::SmartPtr( new ScalarImage( *(this->FltImages[0]), *fltROI ) ) );
00065     } 
00066   else 
00067     {
00068     this->FltImagesROI.push_back( fltImage );
00069     }
00070   
00071   // initialize transformation
00072   this->Parameters[0] = (fltROI) ? fltROI->From()[0] * this->FltImages[0]->GetPixelSize(0) : 0;
00073   this->Parameters[1] = (fltROI) ? fltROI->From()[1] * this->FltImages[0]->GetPixelSize(1) : 0;
00074 
00075   // no rotation
00076   this->Parameters[2] = 0.0;
00077 
00078   // no scale
00079   this->Parameters[3] = this->Parameters[4] = 1.0;
00080 
00081   // no shear
00082   this->Parameters[5] = 0.0;
00083 
00084   // center is center of ROI floating image.
00085   this->Parameters[6] = 0.5 * this->FltImagesROI[0]->GetPixelSize( 0 ) * ( this->FltImagesROI[0]->GetDims()[0]-1 );
00086   this->Parameters[7] = 0.5 * this->FltImagesROI[0]->GetPixelSize( 0 ) * ( this->FltImagesROI[0]->GetDims()[1]-1 );
00087   
00088   this->Transformation.Compose( this->Parameters.Elements );
00089 }
00090 
00091 FunctionalAffine2D::FunctionalAffine2D
00092 ( std::vector<ScalarImage::SmartPtr>& refImages, 
00093   std::vector<ScalarImage::SmartPtr>& fltImages,
00094   const ScalarImage::RegionType* fltROI ) 
00095   : m_NumberDOFs( 6 ),
00096     m_SimilarityMeasure( ScalarImageSimilarity::MI ),
00097     m_HistogramEqualization( false ),
00098     RefImages( refImages ),
00099     FltImages( fltImages ),
00100     FltImagesROI( fltImages.size() ),
00101     Parameters( 8 )
00102 {
00103   if ( fltROI ) 
00104     {
00105     for ( size_t i = 0; i < this->FltImages.size(); ++i )
00106       {
00107       this->FltImagesROI[i] = ScalarImage::SmartPtr( new ScalarImage( *(this->FltImages[i]), *fltROI ) );
00108       } 
00109     }
00110   else 
00111     {
00112     for ( size_t i = 0; i < this->FltImages.size(); ++i )
00113       {
00114       this->FltImagesROI[i] = this->FltImages[i];
00115       }
00116     }
00117   
00118   // initialize transformation
00119   this->Parameters[0] = (fltROI) ? fltROI->From()[0] * this->FltImages[0]->GetPixelSize(0) : 0;
00120   this->Parameters[1] = (fltROI) ? fltROI->From()[1] * this->FltImages[0]->GetPixelSize(1) : 0;
00121   
00122   // no rotation
00123   this->Parameters[2] = 0.0;
00124   
00125   // no scale
00126   this->Parameters[3] = this->Parameters[4] = 1.0;
00127 
00128   // no shear
00129   this->Parameters[5] = 0.0;
00130 
00131   // center is center of ROI floating image.
00132   this->Parameters[6] = 0.5 * this->FltImagesROI[0]->GetPixelSize( 0 ) * ( this->FltImagesROI[0]->GetDims()[0]-1 );
00133   this->Parameters[7] = 0.5 * this->FltImagesROI[0]->GetPixelSize( 0 ) * ( this->FltImagesROI[0]->GetDims()[1]-1 );
00134   
00135   this->Transformation.Compose( this->Parameters.Elements );
00136 }
00137 
00138 void
00139 FunctionalAffine2D::SetNumberOfBins
00140 ( const size_t minBins, const size_t maxBins )
00141 {
00142   ImageSimilarityMemory.SetMinNumBins( minBins );
00143   if ( maxBins )
00144     ImageSimilarityMemory.SetMaxNumBins( maxBins );
00145   else
00146     ImageSimilarityMemory.SetMaxNumBins( minBins );
00147 }
00148 
00149 Types::Coordinate
00150 FunctionalAffine2D::GetParamStep 
00151 ( const size_t idx, const Types::Coordinate mmStep ) const
00152 {
00153   switch ( idx ) 
00154     {
00155     default:
00156     case 0:
00157     case 1:
00158       // translation
00159       return mmStep;
00160     case 2: 
00161     {
00162     // rotation
00163     const Types::Coordinate minSize = 
00164       std::min( FltImagesROI[0]->GetDims()[AXIS_X] * FltImagesROI[0]->GetPixelSize( AXIS_X ), FltImagesROI[0]->GetDims()[AXIS_Y] * FltImagesROI[0]->GetPixelSize( AXIS_Y ) );
00165     return Units::Degrees( MathUtil::ArcTan( 2 * mmStep / minSize ) ).Value();
00166     }
00167     case 3: 
00168     {
00169     // scale x
00170     const Types::Coordinate size = FltImagesROI[0]->GetDims()[AXIS_X] * FltImagesROI[0]->GetPixelSize( AXIS_X );
00171     return 2 * mmStep / size;
00172     }
00173     case 4: 
00174     {
00175     // scale y
00176     const Types::Coordinate size = FltImagesROI[0]->GetDims()[AXIS_Y] * FltImagesROI[0]->GetPixelSize( AXIS_Y );
00177     return 2 * mmStep / size;
00178     }
00179     case 5:
00180     {
00181     // shear
00182     const Types::Coordinate sizeYX = 2.0 / (FltImagesROI[0]->GetDims()[AXIS_X] * FltImagesROI[0]->GetPixelSize( AXIS_X ));
00183     return sizeYX;
00184     }
00185     }
00186   
00187   return 0;
00188 }
00189 
00190 void
00191 FunctionalAffine2D::SetParamVector( CoordinateVector& v ) 
00192 {
00193   Parameters = v;
00194   Transformation.Compose( Parameters.Elements );
00195 }
00196 
00197 void
00198 FunctionalAffine2D::GetParamVector( CoordinateVector& v ) 
00199 {
00200   v = Parameters;
00201 }
00202 
00203 FunctionalAffine2D::ReturnType
00204 FunctionalAffine2D::EvaluateAt( CoordinateVector& v ) 
00205 {
00206   this->SetParamVector( v );
00207   return this->Evaluate();
00208 }
00209   
00210 FunctionalAffine2D::ReturnType
00211 FunctionalAffine2D::Evaluate() 
00212 {
00213         Self::ReturnType result = 0;
00214   if ( (this->FltImagesROI.size() > 1) || (this->RefImages.size() > 1) )
00215     {
00216     std::vector<ScalarImage::SmartPtr> refImageROISmart( this->RefImages.size() );
00217     std::vector<const ScalarImage*> refImageROI( this->RefImages.size() );
00218     std::vector<const ScalarImage*> fltImageROI( this->FltImagesROI.size() );
00219 
00220     for ( size_t i = 0; i < RefImages.size(); ++i )
00221       {
00222       refImageROISmart[i] = ScalarImage::SmartPtr( this->RefImages[i]->InterpolateFrom( this->FltImagesROI[i], &this->Transformation ) );
00223       refImageROI[i] = refImageROISmart[i];
00224       fltImageROI[i] = this->FltImagesROI[i];
00225       }
00226     result = this->GetSimilarity( refImageROI, fltImageROI );
00227     }
00228   else
00229     {
00230     ScalarImage::SmartPtr refImageROI( this->RefImages[0]->InterpolateFrom( this->FltImagesROI[0], &this->Transformation ) );
00231     result = this->GetSimilarity( refImageROI, this->FltImagesROI[0] );
00232     }
00233 
00234   return result;
00235 }
00236 
00237 FunctionalAffine2D::ReturnType
00238 FunctionalAffine2D::GetSimilarity
00239 ( const ScalarImage* img0,  const ScalarImage* img1 ) const
00240 {
00241   switch ( this->m_SimilarityMeasure ) 
00242     {
00243     case ScalarImageSimilarity::MI :
00244       return ScalarImageSimilarity::GetMutualInformation( img0, img1, &this->ImageSimilarityMemory );
00245     case ScalarImageSimilarity::NMI :
00246       return ScalarImageSimilarity::GetNormalizedMutualInformation( img0, img1, &this->ImageSimilarityMemory );
00247     case ScalarImageSimilarity::RMI :
00248       return ScalarImageSimilarity::GetRegionalMutualInformation( img0, img1 );
00249     case ScalarImageSimilarity::RNMI :
00250       return ScalarImageSimilarity::GetRegionalMutualInformation( img0, img1, true /*NMI*/ );
00251     case ScalarImageSimilarity::CR :
00252       return ScalarImageSimilarity::GetCorrelationRatio( img0, img1 );
00253     case ScalarImageSimilarity::CC :
00254       return ScalarImageSimilarity::GetCrossCorrelation( img0, img1 );
00255     case ScalarImageSimilarity::MSD :
00256       return ScalarImageSimilarity::GetMinusMeanSquaredDifference( img0, img1 );
00257     case ScalarImageSimilarity::DAE :
00258       return ScalarImageSimilarity::GetDifferenceImageEntropy( img0, img1 );
00259     case ScalarImageSimilarity::GradientCorrelation :
00260       return ScalarImageSimilarity::GetGradientCorrelation( img0, img1 );
00261     case ScalarImageSimilarity::PatternIntensity :
00262       return ScalarImageSimilarity::GetPatternIntensity( img0, img1 );
00263     default:
00264       return 0;
00265     }
00266 }
00267 
00268 FunctionalAffine2D::ReturnType
00269 FunctionalAffine2D::GetSimilarity
00270   ( std::vector<const ScalarImage*>& imgs0,  
00271     std::vector<const ScalarImage*>& imgs1 ) const
00272 {
00273   switch ( this->m_SimilarityMeasure ) 
00274     {
00275     case ScalarImageSimilarity::RMI :
00276       return ScalarImageSimilarity::GetMutualInformation( imgs0, imgs1 );
00277     case ScalarImageSimilarity::RNMI :
00278       return ScalarImageSimilarity::GetNormalizedMutualInformation( imgs0, imgs1 ); 
00279     default:
00280     {
00281     assert( imgs0.size() == imgs1.size() );
00282     Self::ReturnType similarity = 0;
00283     std::vector<const ScalarImage*>::const_iterator it0, it1;
00284     it0 = imgs0.begin();
00285     it1 = imgs1.begin();
00286     while ( (it0 != imgs0.end()) && (it1 != imgs1.end()) )
00287       {
00288       similarity += this->GetSimilarity( *it0, *it1 );
00289       ++it0;
00290       ++it1;
00291       }
00292     return similarity;
00293     }
00294     }
00295 }
00296 
00297 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines