Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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
00076 this->Parameters[2] = 0.0;
00077
00078
00079 this->Parameters[3] = this->Parameters[4] = 1.0;
00080
00081
00082 this->Parameters[5] = 0.0;
00083
00084
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
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
00123 this->Parameters[2] = 0.0;
00124
00125
00126 this->Parameters[3] = this->Parameters[4] = 1.0;
00127
00128
00129 this->Parameters[5] = 0.0;
00130
00131
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
00159 return mmStep;
00160 case 2:
00161 {
00162
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
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
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
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 );
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 }