Skip to content
Snippets Groups Projects
Commit f4a1b37f authored by Cédric Traizet's avatar Cédric Traizet
Browse files

BUG: center the data by default and use the correct correlation matrix when the data is reduced

parent 89fc81cc
No related branches found
No related tags found
No related merge requests found
...@@ -96,7 +96,7 @@ private: ...@@ -96,7 +96,7 @@ private:
"\"Kernel maximum autocorrelation factor and minimum noise fraction transformations,\" IEEE Transactions on Image Processing, vol. 20, no. 3, pp. 612-624, (2011)"); "\"Kernel maximum autocorrelation factor and minimum noise fraction transformations,\" IEEE Transactions on Image Processing, vol. 20, no. 3, pp. 612-624, (2011)");
AddDocTag(Tags::Filter); AddDocTag(Tags::Filter);
AddDocTag(Tags::DimensionReduction); AddDocTag(Tags::DimensionReduction);
AddParameter(ParameterType_InputImage, "in", "Input Image"); AddParameter(ParameterType_InputImage, "in", "Input Image");
SetParameterDescription("in", "The input image to apply dimensionality reduction."); SetParameterDescription("in", "The input image to apply dimensionality reduction.");
...@@ -250,20 +250,31 @@ private: ...@@ -250,20 +250,31 @@ private:
// PCA Algorithm // PCA Algorithm
case 0: case 0:
{ {
otbAppLogINFO("Using the PCA Algorithm "); otbAppLogINFO("Using the PCA Algorithm ");
PCAForwardFilterType::Pointer filter = PCAForwardFilterType::New(); PCAForwardFilterType::Pointer filter = PCAForwardFilterType::New();
m_ForwardFilter = filter; m_ForwardFilter = filter;
PCAInverseFilterType::Pointer invFilter = PCAInverseFilterType::New(); PCAInverseFilterType::Pointer invFilter = PCAInverseFilterType::New();
m_InverseFilter = invFilter; m_InverseFilter = invFilter;
filter->SetInput(GetParameterFloatVectorImage("in")); filter->SetInput(GetParameterFloatVectorImage("in"));
filter->SetNumberOfPrincipalComponentsRequired(nbComp); filter->SetNumberOfPrincipalComponentsRequired(nbComp);
filter->SetUseNormalization(normalize);
// Center AND reduce the input data.
if (normalize)
{
filter->SetUseNormalization(true);
filter->SetUseVarianceForNormalization(true);
}
// Only center the input data.
else
{
filter->SetUseNormalization(true);
filter->SetUseVarianceForNormalization(false);
}
m_ForwardFilter->GetOutput()->UpdateOutputInformation(); m_ForwardFilter->GetOutput()->UpdateOutputInformation();
//Write transformation matrix //Write eigenvalues
std::ofstream outFile; std::ofstream outFile;
outFile.open(this->GetParameterString("method.pca.outeigenvalues")); outFile.open(this->GetParameterString("method.pca.outeigenvalues"));
if (outFile.is_open()) if (outFile.is_open())
...@@ -275,9 +286,8 @@ private: ...@@ -275,9 +286,8 @@ private:
outFile.close(); outFile.close();
} }
if (invTransform) if (invTransform)
{ {
invFilter->SetInput(m_ForwardFilter->GetOutput()); invFilter->SetInput(m_ForwardFilter->GetOutput());
if (normalize) if (normalize)
{ {
......
...@@ -160,13 +160,37 @@ PCAImageFilter< TInputImage, TOutputImage, TDirectionOfTransformation > ...@@ -160,13 +160,37 @@ PCAImageFilter< TInputImage, TOutputImage, TDirectionOfTransformation >
if ( !m_GivenStdDevValues ) if ( !m_GivenStdDevValues )
{ {
m_StdDevValues = m_Normalizer->GetFunctor().GetStdDev(); m_StdDevValues = m_Normalizer->GetFunctor().GetStdDev();
}
if ( m_UseVarianceForNormalization )
{
// Set User std value so the filter won't recompute the stats // Set User std value so the filter won't recompute the stats
m_Normalizer->SetStdDev( m_StdDevValues ); m_Normalizer->SetStdDev( m_StdDevValues );
// Compute the correlation matrix, note that GetCovarianceEstimator()->GetCorrelation()
// would give us the matrix with component E[XY], which is not what we want., we want
// the matrix defined by its component (E[XY]-E[X]E[Y])/(sigmaX*sigmaY)
m_CovarianceMatrix = m_Normalizer->GetCovarianceEstimator()->GetCovariance();
auto cov = m_Normalizer->GetCovarianceEstimator()->GetCovariance();
auto numberOfComponent = this->GetInput()->GetNumberOfComponentsPerPixel();
for (unsigned int r = 0; r < numberOfComponent; ++r)
{
for (unsigned int c = 0; c < numberOfComponent; ++c)
{
m_CovarianceMatrix(r,c) = cov(r,c) / (std::sqrt(cov(r,r)) *std::sqrt( cov(c,c)));
}
}
} }
if ( m_UseVarianceForNormalization )
m_CovarianceMatrix = m_Normalizer->GetCovarianceEstimator()->GetCorrelation();
else else
{
m_Normalizer->SetUseStdDev(false);
m_CovarianceMatrix = m_Normalizer->GetCovarianceEstimator()->GetCovariance(); m_CovarianceMatrix = m_Normalizer->GetCovarianceEstimator()->GetCovariance();
}
} }
else else
{ {
...@@ -362,6 +386,9 @@ PCAImageFilter< TInputImage, TOutputImage, TDirectionOfTransformation > ...@@ -362,6 +386,9 @@ PCAImageFilter< TInputImage, TOutputImage, TDirectionOfTransformation >
vnl_vector< double > valP = solver.D.diagonal(); vnl_vector< double > valP = solver.D.diagonal();
valP.flip(); valP.flip();
m_EigenValues.SetSize( m_NumberOfPrincipalComponentsRequired );
for ( unsigned int i = 0; i < m_NumberOfPrincipalComponentsRequired; ++i )
m_EigenValues[i] = static_cast< RealType >( valP[i] );
/* /*
* We used normalized PCA * We used normalized PCA
*/ */
...@@ -382,9 +409,6 @@ PCAImageFilter< TInputImage, TOutputImage, TDirectionOfTransformation > ...@@ -382,9 +409,6 @@ PCAImageFilter< TInputImage, TOutputImage, TDirectionOfTransformation >
m_TransformationMatrix = transf; m_TransformationMatrix = transf;
m_EigenValues.SetSize( m_NumberOfPrincipalComponentsRequired );
for ( unsigned int i = 0; i < m_NumberOfPrincipalComponentsRequired; ++i )
m_EigenValues[i] = static_cast< RealType >( valP[i] );
#else #else
InternalMatrixType transf; InternalMatrixType transf;
vnl_vector<double> vectValP; vnl_vector<double> vectValP;
...@@ -396,8 +420,8 @@ PCAImageFilter< TInputImage, TOutputImage, TDirectionOfTransformation > ...@@ -396,8 +420,8 @@ PCAImageFilter< TInputImage, TOutputImage, TDirectionOfTransformation >
m_EigenValues.SetSize( m_NumberOfPrincipalComponentsRequired ); m_EigenValues.SetSize( m_NumberOfPrincipalComponentsRequired );
for ( unsigned int i = 0; i < m_NumberOfPrincipalComponentsRequired; ++i ) for ( unsigned int i = 0; i < m_NumberOfPrincipalComponentsRequired; ++i )
m_EigenValues[i] = static_cast< RealType >( valP(i, i) ); m_EigenValues[m_NumberOfPrincipalComponentsRequired - 1 - i] = static_cast< RealType >( valP(i, i) );
/* We used normalized PCA */ /* We used normalized PCA */
for ( unsigned int i = 0; i < valP.rows(); ++i ) for ( unsigned int i = 0; i < valP.rows(); ++i )
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment