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 <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
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
00061
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
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
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
00103 for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00104 {
00105 this->m_AddCorrectionAdd[i] /= foregroundNumberOfPixels;
00106 }
00107
00108 for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00109 {
00110 this->m_AddCorrectionMul[i] /= totalImageEnergy;
00111 }
00112
00113
00114
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
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
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
00153 for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00154 {
00155
00156 this->m_MulCorrectionAdd[i] = foregroundNumberOfPixels / this->m_MulCorrectionAdd[i];
00157 this->m_StepSizeAdd[i] = 0.0;
00158 }
00159
00160 for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00161 {
00162
00163 this->m_MulCorrectionMul[i] = foregroundNumberOfPixels / this->m_MulCorrectionMul[i];
00164 this->m_StepSizeMul[i] = 0.0;
00165 }
00166
00167
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
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
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
00206 for ( unsigned int i = 0; i < PolynomialTypeAdd::NumberOfMonomials; ++i )
00207 {
00208
00209 this->m_StepSizeAdd[i] = foregroundNumberOfPixels / this->m_StepSizeAdd[i];
00210 }
00211
00212 for ( unsigned int i = 0; i < PolynomialTypeMul::NumberOfMonomials; ++i )
00213 {
00214
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
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
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
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
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
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
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