cmtkEntropyMinimizationIntensityCorrectionFunctional.txx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
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 <System/cmtkThreads.h>
00034 #include <System/cmtkMemory.h>
00035 
00036 #pragma GCC diagnostic ignored "-Wtype-limits"
00037 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00038 void
00039 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00040 ::UpdateCorrectionFactors()
00041 {
00042   const DataGrid::IndexType& dims = this->m_InputImage->GetDims();
00043 
00044   // All equation numbers refer to paper by Likar et al., IEEE-TMI 20(12):1398--1410, 2001.
00045   for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00046     {
00047     this->m_AddCorrectionAdd[i] = 0;
00048     this->m_MulCorrectionAdd[i] = 0;
00049     }
00050 
00051   for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00052     {
00053     this->m_AddCorrectionMul[i] = 0;
00054     this->m_MulCorrectionMul[i] = 0;
00055     }
00056 
00057   double totalImageEnergy = 0.0;
00058   size_t foregroundNumberOfPixels = 0;
00059 
00060   // first, compute additive correction factors according to
00061   // Eqs. (A8) and (A12).
00062   size_t ofs = 0;
00063   for ( int z = 0; z < dims[2]; ++z )
00064     {
00065     const Types::Coordinate Z = 2.0*(z-dims[2]/2) / dims[2];
00066 
00067     for ( int y = 0; y < dims[1]; ++y )
00068       {
00069       const Types::Coordinate Y = 2.0*(y-dims[1]/2) / dims[1];
00070 
00071       for ( int x = 0; x < dims[0]; ++x, ++ofs )
00072         {
00073         const Types::Coordinate X = 2.0*(x-dims[0]/2) / dims[0];
00074 
00075         if ( this->m_ForegroundMask[ofs] )
00076           {
00077           ++foregroundNumberOfPixels;
00078           Types::DataItem value;
00079           if ( this->m_InputImage->GetDataAt( value, x, y, z ) )
00080             totalImageEnergy += value;
00081           else
00082             value = 0.0;
00083 
00084           // Eq. (A8)
00085           PolynomialTypeAdd::EvaluateAllMonomials( this->m_MonomialsVec, X, Y, Z );
00086           for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00087             {
00088             this->m_AddCorrectionAdd[i] += this->m_MonomialsVec[i];
00089             }
00090 
00091           // Eq. (A12)
00092           PolynomialTypeMul::EvaluateAllMonomials( this->m_MonomialsVec, X, Y, Z );
00093           for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00094             {
00095             this->m_AddCorrectionMul[i] += value * this->m_MonomialsVec[i];
00096             }
00097           }
00098         }
00099       }
00100     }
00101 
00102   // Normalization according to (A8)
00103   for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00104     {
00105     this->m_AddCorrectionAdd[i] /= foregroundNumberOfPixels;
00106     }
00107   // Normalization according to (A12)
00108   for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00109     {
00110     this->m_AddCorrectionMul[i] /= totalImageEnergy;
00111     }
00112 
00113   // Now, compute multiplicative correction factors according to
00114   // Eqs. (A14) and (A16).
00115   ofs = 0;
00116   for ( int z = 0; z < dims[2]; ++z )
00117     {
00118     const Types::Coordinate Z = 2.0*(z-dims[2]/2) / dims[2];
00119 
00120     for ( int y = 0; y < dims[1]; ++y )
00121       {
00122       const Types::Coordinate Y = 2.0*(y-dims[1]/2) / dims[1];
00123 
00124       for ( int x = 0; x < dims[0]; ++x, ++ofs )
00125         {
00126         const Types::Coordinate X = 2.0*(x-dims[0]/2) / dims[0];
00127 
00128         if ( this->m_ForegroundMask[ofs] )
00129           {
00130           Types::DataItem value;
00131           if ( !this->m_InputImage->GetDataAt( value, x, y, z ) )
00132             value = 0.0;
00133 
00134           // Eq. (A8)
00135           PolynomialTypeAdd::EvaluateAllMonomials( this->m_MonomialsVec, X, Y, Z );
00136           for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00137             {
00138             this->m_MulCorrectionAdd[i] += fabs( this->m_MonomialsVec[i] - this->m_AddCorrectionAdd[i] );
00139             }
00140 
00141           // Eq. (A12)
00142           PolynomialTypeMul::EvaluateAllMonomials( this->m_MonomialsVec, X, Y, Z );
00143           for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00144             {
00145             this->m_MulCorrectionMul[i] += value * fabs( this->m_MonomialsVec[i] - this->m_AddCorrectionMul[i] );
00146             }
00147           }
00148         }
00149       }
00150     }
00151 
00152   // Normalization according to (A14)
00153   for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00154     {
00155     // invert for speedup of application
00156     this->m_MulCorrectionAdd[i] = foregroundNumberOfPixels / this->m_MulCorrectionAdd[i];
00157     this->m_StepSizeAdd[i] = 0.0;
00158     }
00159   // Normalization according to (A16)
00160   for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00161     {
00162     // invert for speedup of application
00163     this->m_MulCorrectionMul[i] = foregroundNumberOfPixels / this->m_MulCorrectionMul[i];
00164     this->m_StepSizeMul[i] = 0.0;
00165     }
00166 
00167   // Finally, compute step scale factors according to Eq. (11).
00168   ofs = 0;
00169   for ( int z = 0; z < dims[2]; ++z )
00170     {
00171     const Types::Coordinate Z = 2.0*(z-dims[2]/2) / dims[2];
00172 
00173     for ( int y = 0; y < dims[1]; ++y )
00174       {
00175       const Types::Coordinate Y = 2.0*(y-dims[1]/2) / dims[1];
00176 
00177       for ( int x = 0; x < dims[0]; ++x, ++ofs )
00178         {
00179         const Types::Coordinate X = 2.0*(x-dims[0]/2) / dims[0];
00180 
00181         if ( this->m_ForegroundMask[ofs] )
00182           {
00183           Types::DataItem value;
00184           if ( !this->m_InputImage->GetDataAt( value, x, y, z ) )
00185             value = 0.0;
00186 
00187           // Eq. (A8)
00188           PolynomialTypeAdd::EvaluateAllMonomials( this->m_MonomialsVec, X, Y, Z );
00189           for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00190             {
00191             this->m_StepSizeAdd[i] += fabs( this->m_MulCorrectionAdd[i] * ( this->m_MonomialsVec[i] - this->m_AddCorrectionAdd[i] ) );
00192             }
00193 
00194           // Eq. (A12)
00195           PolynomialTypeMul::EvaluateAllMonomials( this->m_MonomialsVec, X, Y, Z );
00196           for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00197             {
00198             this->m_StepSizeMul[i] += fabs( value * this->m_MulCorrectionMul[i] * ( this->m_MonomialsVec[i] - this->m_AddCorrectionMul[i] ) );
00199             }
00200           }
00201         }
00202       }
00203     }
00204   
00205   // Normalization according to (11)
00206   for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00207     {
00208     // invert for speedup of application
00209     this->m_StepSizeAdd[i] = foregroundNumberOfPixels / this->m_StepSizeAdd[i];
00210     }
00211   // Normalization according to (11)
00212   for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00213     {
00214     // invert for speedup of application
00215     this->m_StepSizeMul[i] = foregroundNumberOfPixels / this->m_StepSizeMul[i];
00216     }
00217 }
00218 
00219 #pragma GCC diagnostic ignored "-Wtype-limits"
00220 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00221 typename cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>::ReturnType
00222 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00223 ::EvaluateWithGradient
00224 ( CoordinateVector& v, CoordinateVector& g, const Types::Coordinate step )
00225 { 
00226   const typename Self::ReturnType baseValue = this->EvaluateAt( v );
00227   
00228   for ( size_t dim = 0; dim < this->VariableParamVectorDim(); ++dim ) 
00229     {
00230     const Types::Coordinate stepScale = this->GetParamStep( dim, step );
00231     if ( stepScale <= 0 ) 
00232       {
00233       g[dim] = 0;
00234       } 
00235     else
00236       {
00237       const Types::Coordinate v0 = v[dim];
00238       
00239       v[dim] += stepScale;
00240       this->SetParamVector( v );
00241       if ( dim < PolynomialTypeAdd::NumberOfMonomials )
00242         this->UpdateBiasFieldAdd();
00243       else
00244         this->UpdateBiasFieldMul();
00245       this->UpdateOutputImage();
00246       const typename Self::ReturnType upper = this->Evaluate();
00247       
00248       v[dim] = v0 - stepScale;
00249       this->SetParamVector( v );
00250       if ( dim < PolynomialTypeAdd::NumberOfMonomials )
00251         this->UpdateBiasFieldAdd();
00252       else
00253         this->UpdateBiasFieldMul();
00254       this->UpdateOutputImage();
00255       const  typename Self::ReturnType lower = this->Evaluate();
00256       
00257       v[dim] = v0;
00258       
00259       if ( (upper > baseValue) || (lower > baseValue) ) 
00260         {
00261         g[dim] = upper-lower;
00262         } 
00263       else 
00264         {
00265         g[dim] = 0;
00266         }
00267       }
00268     }  
00269 
00270   return baseValue;
00271 }
00272 
00273 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00274 void
00275 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00276 ::UpdateBiasFields( bool foregroundOnly )
00277 { 
00278   ThreadPool& threadPool = ThreadPool::GetGlobalThreadPool();
00279   const size_t numberOfTasks = 4 * threadPool.GetNumberOfThreads() - 3;
00280 
00281   std::vector< ThreadParameters<Self> > taskParameters( numberOfTasks );
00282   for ( size_t task = 0; task < numberOfTasks; ++task )
00283     {
00284     taskParameters[task].thisObject = this;
00285     }
00286  
00287   if ( foregroundOnly )
00288     threadPool.Run( UpdateBiasFieldsThreadFunc, taskParameters );
00289   else
00290     threadPool.Run( UpdateBiasFieldsAllThreadFunc, taskParameters );
00291 }
00292 
00293 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00294 void
00295 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00296 ::UpdateBiasFieldsThreadFunc( void *args, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t )
00297 {
00298   ThreadParameters<Self>* threadParameters = static_cast<ThreadParameters<Self>*>( args );
00299   
00300   Self* This = threadParameters->thisObject;
00301   const Self* ThisConst = threadParameters->thisObject;
00302 
00303   const DataGrid::IndexType& dims = ThisConst->m_InputImage->GetDims();
00304   const UniformVolume* inputImage = ThisConst->m_InputImage;
00305 
00306   float* biasFieldPtrAdd = This->m_BiasFieldAdd->GetDataPtrTemplate();
00307   float* biasFieldPtrMul = This->m_BiasFieldMul->GetDataPtrTemplate();
00308 
00309   Types::Coordinate* monomialsVec = This->m_MonomialsVec + (threadIdx * ThisConst->m_MonomialsPerThread);
00310 
00311   const int zFrom = taskIdx * (dims[2] / taskCnt);
00312   const int zTo = std::max<int>( (taskIdx+1) * (dims[2] / taskCnt), dims[2] );
00313   
00314   Types::DataItem value;
00315   size_t ofs = zFrom * dims[0] * dims[1];
00316   for ( int z = zFrom; z < zTo; ++z )
00317     {
00318     const Types::Coordinate Z = 2.0*(z-dims[2]/2) / dims[2];
00319 
00320     for ( int y = 0; y < dims[1]; ++y )
00321       {
00322       const Types::Coordinate Y = 2.0*(y-dims[1]/2) / dims[1];
00323 
00324       for ( int x = 0; x < dims[0]; ++x, ++ofs )
00325         {
00326         const Types::Coordinate X = 2.0*(x-dims[0]/2) / dims[0];
00327 
00328         Types::Coordinate normMul = 1.0;
00329         Types::Coordinate normAdd = 0.0;
00330         if ( This->m_ForegroundMask[ofs] )
00331           {
00332           if ( inputImage->GetDataAt( value, ofs ) )
00333             {
00334             // Normalization according to Eq (13)
00335             PolynomialTypeMul::EvaluateAllMonomials( monomialsVec, X, Y, Z );
00336             for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00337               {
00338               normMul += ThisConst->m_CoefficientsMul[i] * ( monomialsVec[i] - ThisConst->m_AddCorrectionMul[i] );
00339               }
00340             PolynomialTypeAdd::EvaluateAllMonomials( monomialsVec, X, Y, Z );
00341             for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00342               {
00343               normAdd += ThisConst->m_CoefficientsAdd[i] * ( monomialsVec[i] - ThisConst->m_AddCorrectionAdd[i] );
00344               }
00345             }
00346           }
00347         biasFieldPtrAdd[ofs] = static_cast<float>( normAdd );
00348         biasFieldPtrMul[ofs] = static_cast<float>( normMul );
00349         }
00350       }
00351     }
00352 }
00353 
00354 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00355 void
00356 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00357 ::UpdateBiasFieldsAllThreadFunc( void *args, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t )
00358 {
00359   ThreadParameters<Self>* threadParameters = static_cast<ThreadParameters<Self>*>( args );
00360   
00361   Self* This = threadParameters->thisObject;
00362   const Self* ThisConst = threadParameters->thisObject;
00363 
00364   const DataGrid::IndexType& dims = ThisConst->m_InputImage->GetDims();
00365   const UniformVolume* inputImage = ThisConst->m_InputImage;
00366 
00367   float* biasFieldPtrAdd = This->m_BiasFieldAdd->GetDataPtrTemplate();
00368   float* biasFieldPtrMul = This->m_BiasFieldMul->GetDataPtrTemplate();
00369 
00370   Types::Coordinate* monomialsVec = This->m_MonomialsVec + (threadIdx * ThisConst->m_MonomialsPerThread);
00371 
00372   const int zFrom = taskIdx * (dims[2] / taskCnt);
00373   const int zTo = std::max<int>( (taskIdx+1) * (dims[2] / taskCnt), dims[2] );
00374 
00375   Types::DataItem value;
00376   size_t ofs = zFrom * dims[0] * dims[1];
00377   for ( int z = zFrom; z < zTo; ++z )
00378     {
00379     const Types::Coordinate Z = 2.0*(z-dims[2]/2) / dims[2];
00380 
00381     for ( int y = 0; y < dims[1]; ++y )
00382       {
00383       const Types::Coordinate Y = 2.0*(y-dims[1]/2) / dims[1];
00384 
00385       for ( int x = 0; x < dims[0]; ++x, ++ofs )
00386         {
00387         const Types::Coordinate X = 2.0*(x-dims[0]/2) / dims[0];
00388 
00389         Types::Coordinate normMul = 1.0;
00390         Types::Coordinate normAdd = 0.0;
00391 
00392         if ( inputImage->GetDataAt( value, ofs ) )
00393           {
00394           // Normalization according to Eq (13)
00395           PolynomialTypeMul::EvaluateAllMonomials( monomialsVec, X, Y, Z );
00396           for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00397             {
00398             normMul += ThisConst->m_CoefficientsMul[i] * ( monomialsVec[i] - ThisConst->m_AddCorrectionMul[i] );
00399             }
00400           PolynomialTypeAdd::EvaluateAllMonomials( monomialsVec, X, Y, Z );
00401           for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00402             {
00403             normAdd += ThisConst->m_CoefficientsAdd[i] * ( monomialsVec[i] - ThisConst->m_AddCorrectionAdd[i] );
00404             }
00405           }
00406         biasFieldPtrAdd[ofs] = static_cast<float>( normAdd );
00407         biasFieldPtrMul[ofs] = static_cast<float>( normMul );
00408         }
00409       }
00410     }
00411 }
00412 
00413 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00414 void
00415 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00416 ::UpdateBiasFieldAdd( const bool foregroundOnly )
00417 {
00418   ThreadPool& threadPool = ThreadPool::GetGlobalThreadPool();
00419   const size_t numberOfTasks = 4 * threadPool.GetNumberOfThreads() - 3;
00420 
00421   std::vector< ThreadParameters<Self> > taskParameters( numberOfTasks );
00422   for ( size_t task = 0; task < numberOfTasks; ++task )
00423     {
00424     taskParameters[task].thisObject = this;
00425     }
00426 
00427   if ( foregroundOnly )
00428     threadPool.Run( UpdateBiasFieldAddThreadFunc, taskParameters );
00429   else
00430     threadPool.Run( UpdateBiasFieldAddAllThreadFunc, taskParameters );
00431 }
00432 
00433 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00434 void
00435 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00436 ::UpdateBiasFieldAddThreadFunc( void *args, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t )
00437 {
00438   ThreadParameters<Self>* threadParameters = static_cast<ThreadParameters<Self>*>( args );
00439   
00440   Self* This = threadParameters->thisObject;
00441   const Self* ThisConst = threadParameters->thisObject;
00442 
00443   const DataGrid::IndexType& dims = ThisConst->m_InputImage->GetDims();
00444   const UniformVolume* inputImage = ThisConst->m_InputImage;
00445 
00446   float* biasFieldPtrAdd = This->m_BiasFieldAdd->GetDataPtrTemplate();
00447 
00448   Types::Coordinate* monomialsVec = This->m_MonomialsVec + (threadIdx * ThisConst->m_MonomialsPerThread);
00449 
00450   const int zFrom = taskIdx * (dims[2] / taskCnt);
00451   const int zTo = std::max<int>( (taskIdx+1) * (dims[2] / taskCnt), dims[2] );
00452   
00453   size_t ofs = zFrom * dims[0] * dims[1];
00454   for ( int z = zFrom; z < zTo; ++z )
00455     {
00456     const Types::Coordinate Z = 2.0*(z-dims[2]/2) / dims[2];
00457 
00458     for ( int y = 0; y < dims[1]; ++y )
00459       {
00460       const Types::Coordinate Y = 2.0*(y-dims[1]/2) / dims[1];
00461 
00462       for ( int x = 0; x < dims[0]; ++x, ++ofs )
00463         {
00464         const Types::Coordinate X = 2.0*(x-dims[0]/2) / dims[0];
00465 
00466         Types::Coordinate normAdd = 0.0;
00467         if ( This->m_ForegroundMask[ofs] )
00468           {
00469           Types::DataItem value;
00470           if ( inputImage->GetDataAt( value, ofs ) )
00471             {
00472             // Normalization according to Eq (13)
00473             PolynomialTypeAdd::EvaluateAllMonomials( monomialsVec, X, Y, Z );
00474             for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00475               {
00476               normAdd += ThisConst->m_CoefficientsAdd[i] * ( monomialsVec[i] - ThisConst->m_AddCorrectionAdd[i] );
00477               }
00478             }
00479           }
00480         biasFieldPtrAdd[ofs] = static_cast<float>( normAdd );
00481         }
00482       }
00483     }
00484 }
00485 
00486 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00487 void
00488 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00489 ::UpdateBiasFieldAddAllThreadFunc( void *args, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t )
00490 {
00491   ThreadParameters<Self>* threadParameters = static_cast<ThreadParameters<Self>*>( args );
00492   
00493   Self* This = threadParameters->thisObject;
00494   const Self* ThisConst = threadParameters->thisObject;
00495 
00496   const DataGrid::IndexType& dims = ThisConst->m_InputImage->GetDims();
00497   const UniformVolume* inputImage = ThisConst->m_InputImage;
00498 
00499   float* biasFieldPtrAdd = This->m_BiasFieldAdd->GetDataPtrTemplate();
00500 
00501   Types::Coordinate* monomialsVec = This->m_MonomialsVec + (threadIdx * ThisConst->m_MonomialsPerThread);
00502 
00503   const int zFrom = taskIdx * (dims[2] / taskCnt);
00504   const int zTo = std::max<int>( (taskIdx+1) * (dims[2] / taskCnt), dims[2] );
00505 
00506   size_t ofs = zFrom * dims[0] * dims[1];
00507   for ( int z = zFrom; z < zTo; ++z )
00508     {
00509     const Types::Coordinate Z = 2.0*(z-dims[2]/2) / dims[2];
00510 
00511     for ( int y = 0; y < dims[1]; ++y )
00512       {
00513       const Types::Coordinate Y = 2.0*(y-dims[1]/2) / dims[1];
00514 
00515       for ( int x = 0; x < dims[0]; ++x, ++ofs )
00516         {
00517         const Types::Coordinate X = 2.0*(x-dims[0]/2) / dims[0];
00518 
00519         Types::Coordinate normAdd = 0.0;
00520         Types::DataItem value;
00521         if ( inputImage->GetDataAt( value, ofs ) )
00522           {
00523           // Normalization according to Eq (13)
00524           PolynomialTypeAdd::EvaluateAllMonomials( monomialsVec, X, Y, Z );
00525           for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00526             {
00527             normAdd += ThisConst->m_CoefficientsAdd[i] * ( monomialsVec[i] - ThisConst->m_AddCorrectionAdd[i] );
00528             }
00529           }
00530         biasFieldPtrAdd[ofs] = static_cast<float>( normAdd );
00531         }
00532       }
00533     }
00534 }
00535 
00536 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00537 void
00538 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00539 ::UpdateBiasFieldMul( const bool foregroundOnly )
00540 {
00541   ThreadPool& threadPool = ThreadPool::GetGlobalThreadPool();
00542   const size_t numberOfTasks = 4 * threadPool.GetNumberOfThreads() - 3;
00543 
00544   std::vector< ThreadParameters<Self> > taskParameters( numberOfTasks );
00545   for ( size_t task = 0; task < numberOfTasks; ++task )
00546     {
00547     taskParameters[task].thisObject = this;
00548     }
00549 
00550   if ( foregroundOnly )
00551     threadPool.Run( UpdateBiasFieldMulThreadFunc, taskParameters );
00552   else
00553     threadPool.Run( UpdateBiasFieldMulAllThreadFunc, taskParameters );
00554 }
00555 
00556 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00557 void
00558 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00559 ::UpdateBiasFieldMulThreadFunc( void *args, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t )
00560 {
00561   ThreadParameters<Self>* threadParameters = static_cast<ThreadParameters<Self>*>( args );
00562   
00563   Self* This = threadParameters->thisObject;
00564   const Self* ThisConst = threadParameters->thisObject;
00565 
00566   const DataGrid::IndexType& dims = ThisConst->m_InputImage->GetDims();
00567   const UniformVolume* inputImage = ThisConst->m_InputImage;
00568 
00569   float* biasFieldPtrMul = This->m_BiasFieldMul->GetDataPtrTemplate();
00570 
00571   Types::Coordinate* monomialsVec = This->m_MonomialsVec + (threadIdx * ThisConst->m_MonomialsPerThread);
00572 
00573   const int zFrom = taskIdx * (dims[2] / taskCnt);
00574   const int zTo = std::max<int>( (taskIdx+1) * (dims[2] / taskCnt), dims[2] );
00575 
00576   size_t ofs = zFrom * dims[0] * dims[1];
00577   for ( int z = zFrom; z < zTo; ++z )
00578     {
00579     const Types::Coordinate Z = 2.0*(z-dims[2]/2) / dims[2];
00580 
00581     for ( int y = 0; y < dims[1]; ++y )
00582       {
00583       const Types::Coordinate Y = 2.0*(y-dims[1]/2) / dims[1];
00584 
00585       for ( int x = 0; x < dims[0]; ++x, ++ofs )
00586         {
00587         const Types::Coordinate X = 2.0*(x-dims[0]/2) / dims[0];
00588 
00589         Types::Coordinate normMul = 1.0;
00590         if ( This->m_ForegroundMask[ofs] )
00591           {
00592           Types::DataItem value;
00593           if ( inputImage->GetDataAt( value, ofs ) )
00594             {
00595             // Normalization according to Eq (13)
00596             PolynomialTypeMul::EvaluateAllMonomials( monomialsVec, X, Y, Z );
00597             for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00598               {
00599               normMul += ThisConst->m_CoefficientsMul[i] * ( monomialsVec[i] - ThisConst->m_AddCorrectionMul[i] );
00600               }
00601             }
00602           }
00603         biasFieldPtrMul[ofs] = static_cast<float>( normMul );
00604         }
00605       }
00606     }
00607 }
00608 
00609 template<unsigned int NOrderAdd,unsigned int NOrderMul>
00610 void
00611 cmtk::EntropyMinimizationIntensityCorrectionFunctional<NOrderAdd,NOrderMul>
00612 ::UpdateBiasFieldMulAllThreadFunc( void *args, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t )
00613 {
00614   ThreadParameters<Self>* threadParameters = static_cast<ThreadParameters<Self>*>( args );
00615   
00616   Self* This = threadParameters->thisObject;
00617   const Self* ThisConst = threadParameters->thisObject;
00618 
00619   const DataGrid::IndexType& dims = ThisConst->m_InputImage->GetDims();
00620   const UniformVolume* inputImage = ThisConst->m_InputImage;
00621 
00622   float* biasFieldPtrMul = This->m_BiasFieldMul->GetDataPtrTemplate();
00623 
00624   Types::Coordinate* monomialsVec = This->m_MonomialsVec + (threadIdx * ThisConst->m_MonomialsPerThread);
00625 
00626   const int zFrom = taskIdx * (dims[2] / taskCnt);
00627   const int zTo = std::max<int>( (taskIdx+1) * (dims[2] / taskCnt), dims[2] );
00628 
00629   size_t ofs = zFrom * dims[0] * dims[1];
00630   for ( int z = zFrom; z < zTo; ++z )
00631     {
00632     const Types::Coordinate Z = 2.0*(z-dims[2]/2) / dims[2];
00633 
00634     for ( int y = 0; y < dims[1]; ++y )
00635       {
00636       const Types::Coordinate Y = 2.0*(y-dims[1]/2) / dims[1];
00637 
00638       for ( int x = 0; x < dims[0]; ++x, ++ofs )
00639         {
00640         const Types::Coordinate X = 2.0*(x-dims[0]/2) / dims[0];
00641 
00642         Types::Coordinate normMul = 1.0;
00643         Types::DataItem value;
00644         if ( inputImage->GetDataAt( value, ofs ) )
00645           {
00646           // Normalization according to Eq (13)
00647           PolynomialTypeMul::EvaluateAllMonomials( monomialsVec, X, Y, Z );
00648           for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00649             {
00650             normMul += ThisConst->m_CoefficientsMul[i] * ( monomialsVec[i] - ThisConst->m_AddCorrectionMul[i] );
00651             }
00652           }
00653         biasFieldPtrMul[ofs] = static_cast<float>( normMul );
00654         }
00655       }
00656     }
00657 }
00658 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines