6 template <
typename TInputImage,
typename TMaskImage>
9 this->SetNthInput(0, const_cast<TMaskImage*>(mask));
12 template <
typename TInputImage,
typename TMaskImage>
15 this->SetNthInput(m_NbInputs, const_cast<TInputImage*>(image));
16 m_IndexImage1=m_NbInputs;
20 template <
typename TInputImage,
typename TMaskImage>
23 this->SetNthInput(m_NbInputs, const_cast<TInputImage*>(image));
24 m_IndexImage2=m_NbInputs;
28 template <
typename TInputImage,
typename TMaskImage>
31 this->SetNthInput(m_NbInputs, const_cast<TInputImage*>(image));
32 m_IndexImage3=m_NbInputs;
36 template <
typename TInputImage,
typename TMaskImage>
39 this->SetNthInput(m_NbInputs, const_cast<TInputImage*>(image));
40 m_IndexImage4=m_NbInputs;
44 template <
typename TInputImage,
typename TMaskImage>
47 this->SetNthInput(m_NbInputs, const_cast<TInputImage*>(image));
48 m_IndexImage5=m_NbInputs;
52 template <
typename TInputImage,
typename TMaskImage>
55 return static_cast< const TMaskImage *
> 56 ( this->itk::ProcessObject::GetInput(0) );
59 template <
typename TInputImage,
typename TMaskImage>
62 return static_cast< const TInputImage *
> 63 ( this->itk::ProcessObject::GetInput(m_IndexImage1) );
66 template <
typename TInputImage,
typename TMaskImage>
69 return static_cast< const TInputImage *
> 70 ( this->itk::ProcessObject::GetInput(m_IndexImage2) );
73 template <
typename TInputImage,
typename TMaskImage>
76 return static_cast< const TInputImage *
> 77 ( this->itk::ProcessObject::GetInput(m_IndexImage3) );
80 template <
typename TInputImage,
typename TMaskImage>
83 return static_cast< const TInputImage *
> 84 ( this->itk::ProcessObject::GetInput(m_IndexImage4) );
87 template <
typename TInputImage,
typename TMaskImage>
90 return static_cast< const TInputImage *
> 91 ( this->itk::ProcessObject::GetInput(m_IndexImage5) );
94 template <
typename TInputImage,
typename TMaskImage>
97 m_ImagesVector.clear();
98 m_JointHistogramInitial.clear();
100 if(m_IndexImage1 < m_nbMaxImages){m_ImagesVector.push_back(this->GetInputImage1());}
101 if(m_IndexImage2 < m_nbMaxImages){m_ImagesVector.push_back(this->GetInputImage2());}
102 if(m_IndexImage3 < m_nbMaxImages){m_ImagesVector.push_back(this->GetInputImage3());}
103 if(m_IndexImage4 < m_nbMaxImages){m_ImagesVector.push_back(this->GetInputImage4());}
104 if(m_IndexImage5 < m_nbMaxImages){m_ImagesVector.push_back(this->GetInputImage5());}
106 unsigned int histoDimension = m_ImagesVector.size();
107 std::vector<InputConstIteratorType> ImagesVectorIt;
108 for (
unsigned int i = 0; i < m_ImagesVector.size(); i++ )
111 ImagesVectorIt.push_back(It);
114 Histogram::iterator it;
115 while (!MaskIt.IsAtEnd())
120 for(
unsigned int m = 0; m < histoDimension; m++ )
122 if(static_cast<MeasureType>(ImagesVectorIt[m].Get()) < 0 )
124 if(static_cast<MeasureType>(ImagesVectorIt[m].Get()) > static_cast<double>(std::numeric_limits<MeasureType>::max()))
125 value[m]= std::numeric_limits<MeasureType>::max();
127 value[m] =
static_cast<MeasureType>(ImagesVectorIt[m].Get());
129 it = m_JointHistogramInitial.find(value);
130 if(it == m_JointHistogramInitial.end())
132 m_JointHistogramInitial.insert(Histogram::value_type(value,1));
139 for (
unsigned int i = 0; i < histoDimension; i++ )
147 template <
typename TInputImage,
typename TMaskImage>
150 unsigned int nbClasses = m_GaussianModel.size();
151 this->m_APosterioriProbability.clear();
154 GaussianFunctionType::CovarianceMatrixType *inverseCovariance =
new GaussianFunctionType::CovarianceMatrixType[nbClasses];
155 double *determinantCovariance =
new double[nbClasses];
156 for(
unsigned int i = 0 ; i < nbClasses; i++)
158 GaussianFunctionType::CovarianceMatrixType covar = (m_GaussianModel[i])->GetCovariance();
160 determinantCovariance[i] = vnl_determinant(covar.GetVnlMatrix());
161 if(std::abs(determinantCovariance[i]) < 1e-12)
163 if(inverseCovariance != NULL)
165 delete[] inverseCovariance;
166 inverseCovariance=NULL;
168 if(determinantCovariance != NULL)
170 delete[] determinantCovariance;
171 determinantCovariance= NULL;
175 inverseCovariance[i] = covar.GetInverse();
179 Histogram::iterator histoIt;
180 GaussianFunctionType::CovarianceMatrixType intensities(this->m_JointHistogram.begin()->first.size(),1);
181 std::vector<double> probas(nbClasses);
183 GaussianFunctionType::CovarianceMatrixType *
xi =
new GaussianFunctionType::CovarianceMatrixType[nbClasses];
184 unsigned int matrixSize = 0;
185 for(
unsigned int i = 0; i < nbClasses; i++)
187 GaussianFunctionType::MeanVectorType mu = (m_GaussianModel[i])->GetMean();
188 matrixSize = mu.Size();
189 for(
unsigned int j = 0; j < mu.Size(); j++)
191 (xi[i]).SetSize(mu.Size(),1);
192 (xi[i])(j,0) = mu[j];
196 GaussianFunctionType::CovarianceMatrixType x;
198 for(histoIt = this->m_JointHistogram.begin(); histoIt != this->m_JointHistogram.end(); ++histoIt)
201 for(
unsigned int i = 0; i < histoIt->first.size(); i++)
203 intensities(i,0) =
static_cast<double>(histoIt->first[i]);
210 double minExpoTerm = 1e10;
211 double sumProba = 0.0;
214 for(
unsigned int i = 0; i < nbClasses; i++)
216 x = intensities - xi[i];
219 for (
unsigned int j = 0; j < matrixSize; ++j)
221 result += inverseCovariance[i](j,j) * x(j,0) * x(j,0);
222 for (
unsigned int k = j+1; k < matrixSize; ++k)
223 result += 2 * inverseCovariance[i](j,k) * x(j,0) * x(k,0);
227 if( minExpoTerm > probas[i])
229 minExpoTerm = probas[i];
234 for(
unsigned int i = 0; i < probas.size(); i++)
237 probas[i] = m_Alphas[i] * ((std::exp(0.5* (minExpoTerm - probas[i])) / std::sqrt(std::fabs(determinantCovariance[i]))));
239 sumProba += probas[i];
243 for(
unsigned int i = 0; i < probas.size(); i++)
245 probas[i] /= sumProba;
249 this->m_APosterioriProbability.insert(GenericContainer::value_type(histoIt->first, probas));
252 double likelihoodValue = this->likelihood(inverseCovariance, determinantCovariance);
255 if(inverseCovariance != NULL)
257 delete[] inverseCovariance;
258 inverseCovariance = NULL;
260 if(determinantCovariance != NULL)
262 delete[] determinantCovariance;
263 determinantCovariance = NULL;
269 return likelihoodValue;
272 template <
typename TInputImage,
typename TMaskImage>
275 GenericContainer::iterator it;
276 Histogram::iterator histoIt;
278 unsigned int numberOfClasses = m_GaussianModel.size();
279 unsigned int dimensions = this->m_JointHistogram.begin()->first.size();
280 double numberOfPixels = 0;
283 double *mixedProportions =
new double[numberOfClasses];
284 double **means =
new double*[numberOfClasses];
285 for (
unsigned int i = 0; i < numberOfClasses; ++i)
287 means[i] =
new double [dimensions];
290 std::vector<GaussianFunctionType::CovarianceMatrixType> covariances(numberOfClasses, GaussianFunctionType::CovarianceMatrixType(dimensions,dimensions));
292 for(
unsigned int i = 0; i < numberOfClasses;i++)
294 mixedProportions[i] = 0.0;
295 for(
unsigned int j = 0; j < dimensions; j++)
298 for(
unsigned int k = 0; k < dimensions; k++)
299 covariances[i](j,k)=0.0;
304 for(it = this->m_APosterioriProbability.begin(),histoIt = this->m_JointHistogram.begin(); it != this->m_APosterioriProbability.end(); ++it, ++histoIt)
306 numberOfPixels +=
static_cast<double>(histoIt->second);
307 for(
unsigned int i = 0; i < numberOfClasses; i++)
309 mixedProportions[i] += it->second[i] * histoIt->second;
311 for(
unsigned int j = 0; j < dimensions; j++)
312 means[i][j] += it->second[i] * histoIt->second * histoIt->first[j];
316 for(
unsigned int i = 0; i < numberOfClasses; i++)
319 for(
unsigned int j = 0; j < dimensions; j++)
320 means[i][j] /= mixedProportions[i];
324 for(it = this->m_APosterioriProbability.begin(), histoIt = this->m_JointHistogram.begin() ; it != this->m_APosterioriProbability.end(); ++it, ++histoIt)
326 for(
unsigned int i = 0; i < numberOfClasses; i++)
327 for(
unsigned int j = 0; j < dimensions; j++)
328 for(
unsigned int k = j; k < dimensions; k++)
329 covariances[i](j,k) += it->second[i] * histoIt->second * ( histoIt->first[j] - means[i][j] ) * ( histoIt->first[k] - means[i][k] );
333 for(
unsigned int i = 0; i < numberOfClasses; i++)
335 for(
unsigned int j = 0; j < dimensions; j++)
337 mix_pro = mixedProportions[i];
338 covariances[i](j,j) /= mixedProportions[i];
339 for(
unsigned int k = j+1; k < dimensions; k++)
341 covariances[i](j,k) /= mixedProportions[i];
342 covariances[i](k,j) = covariances[i](j,k);
345 mixedProportions[i] /=
static_cast<double>(numberOfPixels);
351 int *sort =
new int[numberOfClasses];
352 for (
unsigned int i = 0; i < numberOfClasses;i++)
355 double minValue = 1e32;
356 for(
unsigned int j = 0; j < numberOfClasses;j++)
360 for(
unsigned int k = 0; k < i; k++)
362 if(j == static_cast<unsigned int>(sort[k]))
369 if(!used && means[j][0] < minValue)
371 minValue = means[j][0];
378 for (
unsigned int i = 0; i < numberOfClasses;i++)
385 GaussianFunctionType::MeanVectorType mu(dimensions);
386 for(
unsigned int j = 0; j < dimensions; j++)
388 mu[j] = means[sort[i]][j];
391 GaussianFunctionType::Pointer tmp = GaussianFunctionType::New();
393 tmp->SetCovariance(covariances[sort[i]]);
394 newAlphas.push_back(mixedProportions[sort[i]]);
395 newModel.push_back(tmp);
399 for (
unsigned int i = 0; i < numberOfClasses; ++i)
403 delete[] mixedProportions;
408 template <
typename TInputImage,
typename TMaskImage>
411 this->createJointHistogram();
412 this->m_JointHistogram = this->m_JointHistogramInitial;
413 unsigned int iter = 0;
414 double distance = 0.0;
419 m_Likelihood = this->expectation();
420 if( m_Likelihood >= 0.0 )
426 std::vector<GaussianFunctionType::Pointer> newModel;
427 std::vector<double> newAlphas;
429 if( !this->maximization(newModel,newAlphas) )
434 distance = this->computeDistance(newModel);
435 m_GaussianModel = newModel;
436 m_Alphas = newAlphas;
439 }
while((distance > this->m_ModelMinDistance) && iter < this->m_MaxIterations);
440 m_Likelihood = this->expectation();
443 template <
typename TInputImage,
typename TMaskImage>
446 double likelihoodValue = 0.0;
447 unsigned int nbClasses = m_GaussianModel.size();
448 GaussianFunctionType::CovarianceMatrixType *inverseCovariance = NULL;
449 double *determinantCovariance = NULL;
450 if(invCovariance != NULL && detCovariance !=NULL)
452 inverseCovariance = invCovariance;
453 determinantCovariance = detCovariance;
457 inverseCovariance =
new GaussianFunctionType::CovarianceMatrixType[nbClasses];
458 determinantCovariance =
new double[nbClasses];
461 for(
unsigned int i = 0 ; i < nbClasses; i++)
463 GaussianFunctionType::CovarianceMatrixType covar = (m_GaussianModel[i])->GetCovariance();
464 determinantCovariance[i] = vnl_determinant(covar.GetVnlMatrix());
465 if(std::fabs(determinantCovariance[i]) < 1e-9)
467 return likelihoodValue;
469 inverseCovariance[i] = covar.GetInverse();
474 Histogram::iterator histoIt;
475 GenericContainer::iterator it = this->m_APosterioriProbability.begin();
477 GaussianFunctionType::CovarianceMatrixType intensities(this->m_JointHistogram.begin()->first.size(),1);
479 for(histoIt = this->m_JointHistogram.begin(); histoIt != this->m_JointHistogram.end(); ++histoIt, ++it)
482 for(
unsigned int i = 0; i < histoIt->first.size(); i++)
484 intensities(i,0) =
static_cast<double> (histoIt->first[i]);
487 unsigned int maxIndex = 0;
488 double maxPostProba = 0.0;
490 for(
unsigned int i = 0; i < nbClasses; i++)
492 if(it->second[i] > maxPostProba)
494 maxPostProba = it->second[i];
499 GaussianFunctionType::CovarianceMatrixType x,xT,result;
500 GaussianFunctionType::MeanVectorType mu = (m_GaussianModel[maxIndex])->GetMean();
501 for(
unsigned int i = 0; i < mu.Size(); i++)
503 x.SetSize(mu.Size(),1);
507 xT = (x.GetTranspose());
508 result = xT * inverseCovariance[maxIndex] * x;
509 double proba = result(0,0);
511 likelihoodValue += histoIt->second * ( -proba/2.0 - std::log(std::sqrt(pow(2*M_PI,static_cast<int>(this->m_JointHistogram.begin()->first.size())) *
512 std::fabs(determinantCovariance[maxIndex])))
513 + std::log(m_Alphas[maxIndex]/maxPostProba));
517 if((invCovariance == NULL)&&(inverseCovariance!=NULL))
519 delete[] inverseCovariance;
520 inverseCovariance=NULL;
522 if((detCovariance ==NULL)&&(determinantCovariance!=NULL))
524 delete[] determinantCovariance;
525 determinantCovariance=NULL;
528 return likelihoodValue;
532 template <
typename TInputImage,
typename TMaskImage>
535 unsigned int nbClasses = m_GaussianModel.size();
537 if(newModel.size() != nbClasses)
540 double criterium = 0.0;
542 unsigned int numberOfGaussians = (newModel[0])->GetMean().Size();
544 for(
unsigned int i = 0; i < m_GaussianModel.size(); i++)
546 GaussianFunctionType::MeanVectorType newMu = (m_GaussianModel[i])->GetMean();
547 GaussianFunctionType::MeanVectorType oldMu = (newModel[i])->GetMean();
549 if(newMu.Size()!=oldMu.Size())
552 for(
unsigned int j = 0; j < numberOfGaussians; j++)
553 criterium += std::fabs( oldMu[j] - newMu[j] );
556 return criterium/(
static_cast<double>(nbClasses * numberOfGaussians));
std::vector< MeasureType > Intensities
void SetInputImage1(const TInputImage *image)
virtual double expectation()
TInputImage::ConstPointer GetInputImage1()
void SetMask(const TMaskImage *mask)
itk::ImageRegionConstIterator< MaskImageType > MaskConstIteratorType
virtual void Update() ITK_OVERRIDE
TInputImage::ConstPointer GetInputImage2()
void createJointHistogram()
void SetInputImage5(const TInputImage *image)
double likelihood(GaussianFunctionType::CovarianceMatrixType *invCovariance=NULL, double *detCovariance=NULL)
virtual bool maximization(std::vector< GaussianFunctionType::Pointer > &newModel, std::vector< double > &newAlphas)
void SetInputImage4(const TInputImage *image)
unsigned short MeasureType
itk::ImageRegionConstIterator< InputImageType > InputConstIteratorType
TInputImage::ConstPointer GetInputImage5()
TInputImage::ConstPointer GetInputImage3()
TInputImage::ConstPointer GetInputImage4()
double computeDistance(std::vector< GaussianFunctionType::Pointer > &newModel)
void SetInputImage2(const TInputImage *image)
TMaskImage::ConstPointer GetMask()
void SetInputImage3(const TInputImage *image)