22 #ifndef otbVCAImageFilter_hxx
23 #define otbVCAImageFilter_hxx
31 template <
class TImage>
36 template <
class TImage>
41 template <
class TImage>
45 Superclass::GenerateOutputInformation();
48 typename VectorImageType::ConstPointer inputPtr = this->GetInput();
49 typename VectorImageType::Pointer outputPtr = this->GetOutput();
51 if (!inputPtr || !outputPtr)
56 const unsigned int numberOfBands = inputPtr->GetNumberOfComponentsPerPixel();
62 outputSize[0] = m_NumberOfEndmembers;
64 outputRegion.SetIndex(outputOrigin);
65 outputRegion.SetSize(outputSize);
67 outputPtr->SetLargestPossibleRegion(outputRegion);
68 outputPtr->SetNumberOfComponentsPerPixel(numberOfBands);
71 template <
class TImage>
77 const unsigned int nbBands = this->GetInput()->GetNumberOfComponentsPerPixel();
81 StreamingStatisticsVectorImageFilterType::New();
83 statsInput->SetInput(input);
84 statsInput->SetEnableMinMax(
false);
88 vnl_matrix<PrecisionType> Ud;
92 vnl_matrix<PrecisionType> R = statsInput->GetCorrelation().GetVnlMatrix();
93 vnl_svd<PrecisionType> svd(R);
94 vnl_matrix<PrecisionType> U = svd.U();
95 Ud = U.get_n_columns(0, m_NumberOfEndmembers);
96 vnl_matrix<PrecisionType> Udt = Ud.transpose();
99 typename NormalizeFilterType::Pointer normalize = NormalizeFilterType::New();
100 normalize->SetInput(input);
101 normalize->SetMean(statsInput->GetMean());
102 normalize->SetUseMean(
true);
103 normalize->SetUseStdDev(
false);
106 mulUd->MatrixByVectorOn();
107 mulUd->SetInput(normalize->GetOutput());
108 mulUd->SetMatrix(Udt);
109 mulUd->UpdateOutputInformation();
113 transformedStats->SetInput(mulUd->GetOutput());
114 transformedStats->SetEnableMinMax(
false);
115 transformedStats->Update();
117 double P_R = nbBands * statsInput->GetComponentCorrelation();
118 double P_Rp = m_NumberOfEndmembers * transformedStats->GetComponentCorrelation() + statsInput->GetMean().GetSquaredNorm();
120 SNR = std::abs(10 * std::log10((P_Rp - (m_NumberOfEndmembers / nbBands) * P_R) / (P_R - P_Rp)));
123 SNRth = 15.0 + 10.0 * std::log(
static_cast<double>(m_NumberOfEndmembers)) + 8.0;
125 typename VectorImageType::Pointer Xd;
126 typename VectorImageType::Pointer Y;
128 std::vector<itk::ProcessObject::Pointer> refHolder;
130 typename NormalizeFilterType::Pointer normalize = NormalizeFilterType::New();
134 otbMsgDevMacro(
"Using projective projection for dimensionnality reduction")
138 vnl_matrix<PrecisionType>
139 R = statsInput->GetCorrelation().GetVnlMatrix();
142 vnl_svd<PrecisionType> svd(R);
143 vnl_matrix<PrecisionType> U = svd.U();
144 Ud = U.get_n_columns(0, m_NumberOfEndmembers);
145 vnl_matrix<PrecisionType> UdT = Ud.transpose();
150 mulUd->MatrixByVectorOn();
151 mulUd->SetInput(this->GetInput());
152 mulUd->SetMatrix(UdT);
153 mulUd->UpdateOutputInformation();
154 refHolder.push_back(mulUd.GetPointer());
156 Xd = mulUd->GetOutput();
160 statsXd->SetEnableSecondOrderStats(
false);
161 statsXd->SetInput(Xd);
164 typename VectorImageType::PixelType Xdmean = statsXd->GetMean();
171 proj->GetModifiableFunctor().SetProjectionDirection(Xdmean);
172 refHolder.push_back(proj.GetPointer());
174 Xd = proj->GetOutput();
181 normalize->SetInput(input);
182 normalize->SetMean(statsInput->GetMean());
183 normalize->SetUseMean(
true);
184 normalize->SetUseStdDev(
false);
187 vnl_matrix<PrecisionType> R = statsInput->GetCovariance().GetVnlMatrix();
190 vnl_svd<PrecisionType> svd(R);
191 vnl_matrix<PrecisionType> U = svd.U();
192 Ud = U.get_n_columns(0, m_NumberOfEndmembers - 1);
193 vnl_matrix<PrecisionType> UdT = Ud.transpose();
196 mulUd->MatrixByVectorOn();
197 mulUd->SetInput(normalize->GetOutput());
198 mulUd->SetMatrix(UdT);
199 mulUd->UpdateOutputInformation();
200 refHolder.push_back(mulUd.GetPointer());
202 Xd = mulUd->GetOutput();
205 normComputer->SetInput(Xd);
208 maxNormComputer->SetInput(normComputer->GetOutput());
209 maxNormComputer->Update();
214 concat->SetInput(Xd);
215 concat->SetScalarValue(maxNorm);
216 refHolder.push_back(concat.GetPointer());
218 Y = concat->GetOutput();
219 Y->UpdateOutputInformation();
223 vnl_matrix<PrecisionType> E(nbBands, m_NumberOfEndmembers);
227 vnl_matrix<PrecisionType> A(m_NumberOfEndmembers, m_NumberOfEndmembers);
229 A(m_NumberOfEndmembers - 1, 0) = 1;
230 typename RandomVariateGeneratorType::Pointer randomGen = RandomVariateGeneratorType::GetInstance();
232 for (
unsigned int i = 0; i < m_NumberOfEndmembers; ++i)
237 otbMsgDevMacro(
"Random vector generation ") vnl_vector<PrecisionType>
238 w(m_NumberOfEndmembers);
239 for (
unsigned int j = 0; j < w.size(); ++j)
241 w(j) = randomGen->GetVariateWithOpenRange();
245 otbMsgDevMacro(
"f = ((I - A*pinv(A))*w) /(norm(I - A*pinv(A))*w))") vnl_matrix<PrecisionType> tmpMat(m_NumberOfEndmembers, m_NumberOfEndmembers);
246 tmpMat.set_identity();
247 otbMsgDevMacro(
"A" << std::endl << A) vnl_svd<PrecisionType> Asvd(A);
248 tmpMat -= A * Asvd.inverse();
250 vnl_vector<PrecisionType> tmpNumerator = tmpMat * w;
251 vnl_vector<PrecisionType> f = tmpNumerator / tmpNumerator.two_norm();
259 typename VectorImageType::PixelType fV(f.data_block(), f.size());
260 dotfY->GetModifiableFunctor().SetVector(
typename VectorImageType::PixelType(fV));
265 typename AbsImageFilterType::Pointer absVFilter = AbsImageFilterType::New();
266 absVFilter->SetInput(v);
271 maxAbs->SetInput(absVFilter->GetOutput());
280 region.SetIndex(maxIdx);
283 region.SetSize(size);
284 Y->SetRequestedRegion(region);
289 otbMsgDevMacro(
"A(:, i) = Y(:, k)")
typename VectorImageType::PixelType e = Y->GetPixel(maxIdx);
296 vnl_vector<PrecisionType>
301 otbMsgDevMacro(
"u = Ud * Xd(:, k)") Xd->SetRequestedRegion(region);
303 typename VectorImageType::PixelType xd = Xd->GetPixel(maxIdx);
304 vnl_vector<PrecisionType> xdV(xd.GetDataPointer(), xd.GetSize());
310 otbMsgDevMacro(
"u = Ud * Xd(:, k)") Xd->SetRequestedRegion(region);
312 typename VectorImageType::PixelType xd = Xd->GetPixel(maxIdx);
313 vnl_vector<PrecisionType> xdV(xd.GetDataPointer(), xd.GetSize());
316 vnl_vector<PrecisionType>
mean(statsInput->GetMean().GetDataPointer(), statsInput->GetMean().GetSize());
324 typename VectorImageType::Pointer output = this->GetOutput();
325 output->SetRegions(output->GetLargestPossibleRegion());
329 itk::ImageRegionIteratorWithIndex<VectorImageType> it(output, output->GetLargestPossibleRegion());
331 for (it.GoToBegin(), i = 0; !it.IsAtEnd(); ++it, ++i)
333 vnl_vector<PrecisionType> e = E.get_column(i);
334 typename VectorImageType::PixelType pixel(input->GetNumberOfComponentsPerPixel());
335 for (
unsigned int j = 0; j < e.size(); ++j)
346 template <
class TImage>
349 Superclass::PrintSelf(os, indent);