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 "cmtkScalarImageSimilarity.h"
00034
00035 #include <Base/cmtkHistogram.h>
00036
00037 #include <vector>
00038
00039 namespace
00040 cmtk
00041 {
00042
00045
00046 ScalarImageSimilarity::ReturnType
00047 ScalarImageSimilarity::GetMutualInformation
00048 ( const ScalarImage* image0, const ScalarImage* image1,
00049 ScalarImageSimilarityMemory *const memory )
00050 {
00051 if ( ! CheckImageDimensions( image0, image1 ) )
00052 return MathUtil::GetFloatNaN();
00053
00054 const TypedArray *data0 = image0->GetPixelData();
00055 const TypedArray *data1 = image1->GetPixelData();
00056
00057 return TypedArraySimilarity::GetMutualInformation( data0, data1, memory );
00058 }
00059
00060 ScalarImageSimilarity::ReturnType
00061 ScalarImageSimilarity::GetNormalizedMutualInformation
00062 ( const ScalarImage* image0, const ScalarImage* image1, ScalarImageSimilarityMemory *const )
00063 {
00064 if ( ! CheckImageDimensions( image0, image1 ) )
00065 return MathUtil::GetFloatNaN();
00066
00067 const TypedArray *data0 = image0->GetPixelData();
00068 const TypedArray *data1 = image1->GetPixelData();
00069
00070 return TypedArraySimilarity::GetNormalizedMutualInformation( data0, data1 );
00071 }
00072
00073 ScalarImageSimilarity::ReturnType
00074 ScalarImageSimilarity::GetMinusMeanSquaredDifference
00075 ( const ScalarImage* image0, const ScalarImage* image1 )
00076 {
00077 if ( ! CheckImageDimensions( image0, image1 ) )
00078 return MathUtil::GetFloatNaN();
00079
00080 const TypedArray *data0 = image0->GetPixelData();
00081 const TypedArray *data1 = image1->GetPixelData();
00082
00083 return TypedArraySimilarity::GetMinusMeanSquaredDifference( data0, data1 );
00084 }
00085
00086 ScalarImageSimilarity::ReturnType
00087 ScalarImageSimilarity::GetCrossCorrelation
00088 ( const ScalarImage* image0, const ScalarImage* image1 )
00089 {
00090 if ( ! CheckImageDimensions( image0, image1 ) )
00091 return MathUtil::GetFloatNaN();
00092
00093 const TypedArray *data0 = image0->GetPixelData();
00094 const TypedArray *data1 = image1->GetPixelData();
00095
00096 return TypedArraySimilarity::GetCrossCorrelation( data0, data1 );
00097 }
00098
00099 ScalarImageSimilarity::ReturnType
00100 ScalarImageSimilarity::GetGradientCorrelation
00101 ( const ScalarImage* image0, const ScalarImage* image1 )
00102 {
00103 if ( ! CheckImageDimensions( image0, image1 ) )
00104 return MathUtil::GetFloatNaN();
00105
00106 TypedArray::SmartPtr gradientX0( image0->GetSobelFiltered( CMTK_SCALARIMAGE_HORIZONTAL ) );
00107 TypedArray::SmartPtr gradientX1( image1->GetSobelFiltered( CMTK_SCALARIMAGE_HORIZONTAL ) );
00108
00109 TypedArray::SmartPtr gradientY0( image0->GetSobelFiltered( CMTK_SCALARIMAGE_VERTICAL ) );
00110 TypedArray::SmartPtr gradientY1( image1->GetSobelFiltered( CMTK_SCALARIMAGE_VERTICAL ) );
00111
00112 return TypedArraySimilarity::GetCrossCorrelation( gradientX0, gradientX1 ) + TypedArraySimilarity::GetCrossCorrelation( gradientY0, gradientY1 );
00113 }
00114
00115 ScalarImageSimilarity::ReturnType
00116 ScalarImageSimilarity::GetGradientDifference
00117 ( const ScalarImage* image0, const ScalarImage* image1, const ScalarImageSimilarity::ReturnType Ax, const ScalarImageSimilarity::ReturnType Ay )
00118 {
00119 if ( ! CheckImageDimensions( image0, image1 ) )
00120 return MathUtil::GetFloatNaN();
00121
00122 TypedArray::SmartPtr gradientX0( image0->GetSobelFiltered( CMTK_SCALARIMAGE_HORIZONTAL ) );
00123 TypedArray::SmartPtr gradientX1( image1->GetSobelFiltered( CMTK_SCALARIMAGE_HORIZONTAL ) );
00124
00125 TypedArray::SmartPtr gradientY0( image0->GetSobelFiltered( CMTK_SCALARIMAGE_VERTICAL ) );
00126 TypedArray::SmartPtr gradientY1( image1->GetSobelFiltered( CMTK_SCALARIMAGE_VERTICAL ) );
00127
00128
00129
00130 Types::DataItem mean, var;
00131 gradientX0->GetStatistics( mean, var );
00132 ScalarImageSimilarity::ReturnType absAx = Ax * var;
00133 gradientY0->GetStatistics( mean, var );
00134 ScalarImageSimilarity::ReturnType absAy = Ay * var;
00135
00136 Types::DataItem scaleFactor = 0;
00137 TypedArray::SmartPtr diffX( TypedArraySimilarity::GetDifferenceArray( gradientX0, gradientX1, scaleFactor ) );
00138 TypedArray::SmartPtr diffY( TypedArraySimilarity::GetDifferenceArray( gradientY0, gradientY1, scaleFactor ) );
00139 ScalarImageSimilarity::ReturnType resultX = 0, resultY = 0;
00140
00141 unsigned int numberOfPixels = image0->GetNumberOfPixels();
00142 for ( unsigned int offset = 0; offset < numberOfPixels; ++offset )
00143 {
00144 Types::DataItem value;
00145 diffX->Get( value, offset );
00146 resultX += 1.0 / ( absAx + MathUtil::Square( value ) );
00147 diffY->Get( value, offset );
00148 resultY += 1.0 / ( absAy + MathUtil::Square( value ) );
00149 }
00150
00151 return absAx * resultX + absAy * resultY;
00152 }
00153
00154 ScalarImageSimilarity::ReturnType
00155 ScalarImageSimilarity::GetPatternIntensity
00156 ( const ScalarImage* image0, const ScalarImage* image1, const ScalarImageSimilarity::ReturnType sigma, const int radius )
00157 {
00158 if ( ! CheckImageDimensions( image0, image1 ) )
00159 return MathUtil::GetFloatNaN();
00160
00161 ScalarImageSimilarity::ReturnType PI = 0;
00162
00163 const int r2 = MathUtil::Square( radius );
00164 const ScalarImageSimilarity::ReturnType sigma2 = MathUtil::Square( sigma );
00165
00166
00167 static std::vector<int> rows;
00168 static std::vector<int> cols;
00169
00170 static int lastRadius = 0;
00171
00172 if ( radius != lastRadius )
00173 {
00174 lastRadius = radius;
00175
00176 rows.clear();
00177 cols.clear();
00178
00179 for ( int jj = -radius; jj <= (int)radius; ++jj )
00180 {
00181 for ( int ii = -radius; ii <= (int)radius; ++ii )
00182 {
00183
00184 if ( ( MathUtil::Square(ii) + MathUtil::Square(jj) ) <= r2 )
00185 {
00186 rows.push_back(jj);
00187 cols.push_back(ii);
00188 }
00189 }
00190 }
00191 }
00192
00193
00194 Types::DataItem scaleFactor = 0;
00195 TypedArray::SmartPtr diff( TypedArraySimilarity::GetDifferenceArray( image0->GetPixelData(), image1->GetPixelData(), scaleFactor ) );
00196
00197
00198 const int dimsX = image0->GetDims()[AXIS_X];
00199 const int dimsY = image0->GetDims()[AXIS_Y];
00200
00201 size_t offset = 0;
00202 for ( int j = 0; j < dimsY; ++j )
00203 {
00204 for ( int i = 0; i < dimsX; ++i, ++offset )
00205 {
00206
00207 Types::DataItem centerValue;
00208 if ( diff->Get( centerValue, offset ) )
00209 {
00210
00211
00212 for ( size_t rc=0; rc<rows.size(); rc++ )
00213 {
00214 const int jj = rows[rc];
00215 const int ii = cols[rc];
00216
00217 Types::DataItem VOIvalue;
00218
00219
00220
00221
00222
00223 if ( (i+ii)>=0 && (i+ii)<dimsX && (j+jj)>=0 && (j+jj)<dimsY )
00224 {
00225 diff->Get( VOIvalue, offset + ii + dimsX * jj );
00226
00227
00228 PI += 1.0 / ( sigma2 + MathUtil::Square( centerValue - VOIvalue ) );
00229 }
00230 }
00231 }
00232 }
00233 }
00234
00235
00236 PI *= sigma2;
00237
00238 return PI;
00239 }
00240
00241 ScalarImageSimilarity::ReturnType
00242 ScalarImageSimilarity::GetDifferenceImageEntropy
00243 ( const ScalarImage* image0, const ScalarImage* image1 )
00244 {
00245 Types::DataItem dummy;
00246 return GetDifferenceImageEntropy( image0, image1, dummy );
00247 }
00248
00249 ScalarImageSimilarity::ReturnType
00250 ScalarImageSimilarity::GetDifferenceImageEntropy
00251 ( const ScalarImage* image0, const ScalarImage* image1, Types::DataItem &scaleFactor )
00252 {
00253 if ( ! CheckImageDimensions( image0, image1 ) )
00254 return MathUtil::GetFloatNaN();
00255
00256 const TypedArray *data0 = image0->GetPixelData();
00257 const TypedArray *data1 = image1->GetPixelData();
00258
00259 return TypedArraySimilarity::GetDifferenceArrayEntropy( data0, data1, scaleFactor );
00260 }
00261
00262 ScalarImageSimilarity::ReturnType
00263 ScalarImageSimilarity::GetCorrelationRatio
00264 ( const ScalarImage* image0, const ScalarImage* image1 )
00265 {
00266 if ( ! CheckImageDimensions( image0, image1 ) )
00267 return MathUtil::GetFloatNaN();
00268
00269 const TypedArray *data0 = image0->GetPixelData();
00270 const TypedArray *data1 = image1->GetPixelData();
00271
00272 return TypedArraySimilarity::GetCorrelationRatio( data0, data1 );
00273 }
00274
00275 bool
00276 ScalarImageSimilarity::CheckImageDimensions
00277 ( const ScalarImage* image0, const ScalarImage* image1 )
00278 {
00279 if ( !image0 || !image1 ) return false;
00280
00281 if ( !image0->GetPixelData() || !image1->GetPixelData() ) return false;
00282
00283 return ( ( image0->GetDims()[0] == image1->GetDims()[0] ) && ( image0->GetDims()[1] == image1->GetDims()[1] ) );
00284 }
00285
00286 }