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 "cmtkScalarImageSimilarity.h"
00034
00035 #include <Base/cmtkMathUtil.h>
00036
00037 namespace
00038 cmtk
00039 {
00040
00043
00044
00045 ScalarImageSimilarity::ReturnType
00046 ScalarImageSimilarity::GetRegionalMutualInformation
00047 ( const ScalarImage* image0, const ScalarImage* image1, const int radius )
00048 {
00049
00050 const ScalarImage::IndexType& dims = image0->GetDims();
00051 int nrows = dims[1];
00052 int ncols = dims[0];
00053
00054 int d = 2*radius+1;
00055 int N = (ncols-2*radius)*(nrows-2*radius);
00056 int d2 = d*d;
00057 int dim = 2*d2;
00058
00059 Types::DataItem* pts = Memory::AllocateArray<Types::DataItem>( N*dim );
00060
00061
00062 Types::DataItem tmp1, tmp2;
00063
00064 const TypedArray *data1 = image0->GetPixelData();
00065 const TypedArray *data2 = image1->GetPixelData();
00066
00067
00068 int idx,nidx,lidx;
00069 nidx = 0; idx = 0; lidx = 0;
00070
00071
00072
00073 for (int i=radius; i<nrows-radius; i++)
00074 {
00075 for (int j=radius; j<ncols-radius; j++)
00076 {
00077 lidx = 0;
00078 for (int ii=-radius; ii<=radius; ii++)
00079 {
00080 for (int jj=-radius; jj<=radius; jj++)
00081 {
00082 idx = (i+ii)*ncols + j+jj;
00083
00084 data1->Get(tmp1,idx);
00085 data2->Get(tmp2,idx);
00086 pts[lidx*N + nidx] = tmp1;
00087 pts[(lidx+d2)*N + nidx] = tmp2;
00088 lidx++;
00089 }
00090 }
00091 nidx++;
00092 }
00093 }
00094
00095
00096
00097
00098
00099 std::vector<double> mean(dim,0.0);
00100
00101 for (int i=0; i<dim; i++)
00102 {
00103 for (int j=0; j<N; j++)
00104 {
00105 mean[i] += pts[i*N+j];
00106 }
00107 }
00108 for (int i=0; i<dim; i++)
00109 {
00110 mean[i] /= N;
00111 }
00112
00113 for (int i=0; i<dim; i++)
00114 {
00115 for (int j=0; j<N; j++)
00116 {
00117 pts[i*N+j] -= mean[i];
00118 }
00119 }
00120
00121
00122
00123
00124
00125
00126 Matrix2D<Types::DataItem> cM( dim, dim );
00127
00128 ScalarImageSimilarity::ReturnType sum;
00129 int iN, jN;
00130
00131 for (int i=0; i<dim; i++)
00132 {
00133 for (int j=i; j<dim; j++)
00134 {
00135 sum = 0.0;
00136 iN = i*N;
00137 jN = j*N;
00138
00139 for (int k=0; k<N; k++)
00140 {
00141 sum += pts[iN+k]*pts[jN+k];
00142 }
00143 cM[i][j] = sum/N;
00144 cM[j][i] = cM[i][j];
00145
00146 }
00147 }
00148 double dt3 = MathUtil::CholeskyDeterminant(cM, dim);
00149
00150
00151
00152
00153
00154
00155 Matrix2D<Types::DataItem> mcM( dim/2, dim/2 );
00156
00157
00158 for (int i=0; i<dim/2; i++)
00159 {
00160 for (int j=0; j<dim/2; j++)
00161 {
00162 mcM[i][j] = cM[i][j];
00163 }
00164 }
00165 double dt1 = MathUtil::CholeskyDeterminant(mcM, dim/2);
00166
00167
00168 for (int i=0; i<dim/2; i++)
00169 {
00170 for (int j=0; j<dim/2; j++)
00171 {
00172 mcM[i][j] = cM[i+dim/2][j+dim/2];
00173 }
00174 }
00175 double dt2 = MathUtil::CholeskyDeterminant(mcM, dim/2);
00176
00177 double alpha = 1.41893853320467;
00178
00179 double v1 = dim/2*alpha + .5*log(dt1);
00180 double v2 = dim/2*alpha + .5*log(dt2);
00181 double v3 = dim*alpha + .5*log(dt3);
00182
00183
00184
00185 return ((ScalarImageSimilarity::ReturnType) (v1+v2-v3));
00186 }
00187
00188 }