27 #include "../common/MatrixUtils.h" 
   28 #include "../common/progress/TaskProgress.h" 
   29 #include "../raster/Grid.h" 
   30 #include "../raster/Utils.h" 
   37 #include <boost/numeric/ublas/io.hpp> 
   38 #include <boost/numeric/ublas/matrix.hpp> 
   40 bool gaussElimination(boost::numeric::ublas::matrix<double>& Z, std::vector<int>& row, 
unsigned int nComponents);
 
   41 bool fowardBackSubstitution(boost::numeric::ublas::matrix<double>& Z, std::vector<double>& y, 
unsigned int ys, std::vector<int>& row, 
unsigned int rows, std::vector<double>& x, 
unsigned int xs);
 
  101                                               const std::vector<std::string>& inputSensorBands, 
const std::map<std::string, std::vector<double> >& components,
 
  102                                               te::rst::Raster& outputRaster, 
const bool enableProgressInterface) 
throw(te::rp::Exception)
 
  107   const unsigned int nComponents = components.size();
 
  108   const unsigned int nBands = inputSensorBands.size();
 
  110   bool computeErrorRasters = 
false;
 
  111   if (nComponents < outputRaster.getNumberOfBands())
 
  112     computeErrorRasters = 
true;
 
  115   unsigned int i, j, k, m;
 
  117   std::vector<double> Qmax;
 
  118   for (i = 0; i < inputSensorBands.size(); i++)
 
  122   boost::numeric::ublas::matrix<double> SpectralBandsComponents(nBands, nComponents);
 
  123   std::map<std::string, std::vector<double> >::const_iterator it;
 
  124   for(i = 0; i < nBands; i++)
 
  125     for (j = 0, it = components.begin(); it != components.end(); j++, it++)
 
  126       SpectralBandsComponents(i, j) = it->second[i] / Qmax[i];
 
  131   boost::numeric::ublas::matrix<double> SpectralBandsComponentsTransposed(nComponents, nBands);
 
  134   SpectralBandsComponentsTransposed = boost::numeric::ublas::trans(SpectralBandsComponents);
 
  138   std::vector<double> componentsMean(nBands, 0.0);
 
  139   std::vector<double> componentsMeanAfter(nBands, 0.0);
 
  141   for (j = 0; j < nBands; j++)
 
  144     componentsMean[j] = 0;
 
  145     for(i = 0; i < nComponents; i++)
 
  146       componentsMean[j] = componentsMean[j] + SpectralBandsComponentsTransposed(i, j);
 
  147     componentsMean[j] = componentsMean[j] / (double) nComponents;
 
  150     componentsMeanAfter[j] = 0;
 
  151     for(i = 0; i < nComponents; i++)
 
  153       SpectralBandsComponentsTransposed(i, j) = SpectralBandsComponentsTransposed(i, j) - componentsMean[j];
 
  154       componentsMeanAfter[j] = componentsMeanAfter[j] + SpectralBandsComponentsTransposed(i, j);
 
  156     componentsMeanAfter[j] = componentsMeanAfter[j] / (double) nComponents;
 
  160   std::vector<double> covarianceVector(nBands * nBands, 0.0);
 
  161   for(k = 0; k < nBands * nBands; k++)
 
  162     covarianceVector[k] = 0;
 
  165   for(j = 0; j < nBands; j++)
 
  166     for(m = 0; m < j + 1; m++)
 
  168       for(i = 0; i < nComponents; i++)
 
  169         covarianceVector[k] = covarianceVector[k] + (SpectralBandsComponentsTransposed(i, j) - componentsMeanAfter[j]) *
 
  170                                                     (SpectralBandsComponentsTransposed(i, m) - componentsMeanAfter[m]);
 
  171       covarianceVector[k] = covarianceVector[k] / (double) nComponents;
 
  177   boost::numeric::ublas::matrix<double> covarianceMatrix(nBands, nBands);
 
  178   for (i = 0; i < nBands; i++)
 
  179     for (j = 0; j <= i; j++)
 
  180       covarianceMatrix(i, j) = covarianceVector[k++];
 
  183   boost::numeric::ublas::matrix<double> auxMatrix(covarianceMatrix);
 
  184   boost::numeric::ublas::matrix<double> tmpMatrix;
 
  190   boost::numeric::ublas::matrix<double> eigenReduced(nBands, nComponents - 1);
 
  191   for (j = 0; j < nBands; j++)
 
  192     for (i = 0; i < nComponents - 1; i++)
 
  193       eigenReduced(j, i) = auxMatrix(j, i);
 
  196   boost::numeric::ublas::matrix<double> SpectralBandsComponentsPCA(SpectralBandsComponentsTransposed.size1(), eigenReduced.size2()); 
 
  197   SpectralBandsComponentsPCA = boost::numeric::ublas::prod(SpectralBandsComponentsTransposed, eigenReduced);
 
  200   auxMatrix.resize(SpectralBandsComponentsPCA.size1(), SpectralBandsComponentsPCA.size2() + 1); 
 
  203   for (j = 0; j < SpectralBandsComponentsPCA.size1(); j++) 
 
  205     for (i = 0; i < SpectralBandsComponentsPCA.size2(); i++) 
 
  206       auxMatrix(j, i) = SpectralBandsComponentsPCA(j, i);
 
  208     auxMatrix(j, SpectralBandsComponentsPCA.size2()) = 1.0;
 
  212   SpectralBandsComponentsPCA.clear();
 
  213   SpectralBandsComponentsPCA = boost::numeric::ublas::trans(auxMatrix);
 
  216   std::vector<int> rows(nComponents, 0);
 
  224   auxMatrix.resize(1, nBands);
 
  226   boost::numeric::ublas::matrix<double> ymat(nComponents - 1, nComponents - 1);
 
  229   std::vector<double> x(nComponents, 0.0);
 
  230   std::vector<double> y(nComponents, 0.0);
 
  233   std::vector<unsigned int> rowsIn(nBands, 0);
 
  234   std::vector<unsigned int> columnIn(nBands, 0);
 
  235   std::vector<unsigned int> columnsIn(nBands, 0);
 
  236   std::vector<double> spectralBandsError(nBands, 0.0);
 
  238   boost::numeric::ublas::matrix<double> rasterRowsIn(nBands, inputRaster.getNumberOfColumns());
 
  239   boost::numeric::ublas::matrix<double> rasterRowsOut(nComponents, inputRaster.getNumberOfColumns());
 
  243   for (
unsigned int rowout = 0; rowout < inputRaster.getNumberOfRows(); rowout++)
 
  246     for (i = 0; i < nBands; i++)
 
  248       for (j = 0; j < inputRaster.getNumberOfColumns(); j++)
 
  250         inputRaster.getValue(j, rowsIn[i], value, inputRasterBands[i]);
 
  251         rasterRowsIn(i, j) = value;
 
  258       columnIn[i] = columnsIn[i];
 
  262     for (
unsigned int colout = 0; colout < inputRaster.getNumberOfColumns(); colout++)
 
  265       for (i = 0; i < nBands; i++)
 
  266         auxMatrix(0, i) = (double) (rasterRowsIn(i, columnIn[i])) / 255.0 - componentsMean[i];
 
  268       ymat = boost::numeric::ublas::prod(auxMatrix, eigenReduced);
 
  270       for (i = 0; i < nComponents - 1; i++)
 
  274       if (!
fowardBackSubstitution(SpectralBandsComponentsPCA, y, nComponents, rows, nComponents, x, nComponents))
 
  278       for (i = 0; i < nComponents; i++)
 
  280         prop = (short) (x[i] * 100 + 100);
 
  281         rasterRowsOut(i, colout) = (
unsigned char) prop;
 
  288       if (computeErrorRasters)
 
  290         for (i = 0; i < nBands; i++)
 
  294           for (j = 0; j < nComponents; j++)
 
  295             aux += x[j] * SpectralBandsComponents(i, j);
 
  298           error = (long) (rasterRowsIn(i, columnIn[i])) / 255.0 - aux;
 
  302           if (computeErrorRasters)
 
  303             rasterRowsIn(i, colout) = error * 255.0;
 
  308       for (i = 0; i < nBands; i++)
 
  314     for (i = 0; i < nComponents; i++)
 
  315       for (j = 0; j < inputRaster.getNumberOfColumns(); j++)
 
  316         outputRaster.setValue(j, rowout, rasterRowsOut(i, j), i);
 
  319     if (computeErrorRasters)
 
  321       for (i = 0; i < nComponents; i++)
 
  322         for (j = 0; j < inputRaster.getNumberOfColumns(); j++)
 
  323           outputRaster.setValue(j, rowout, rasterRowsIn(i, j), i + nComponents); 
 
  345 bool gaussElimination(boost::numeric::ublas::matrix<double>& Z, std::vector<int>& row, 
unsigned int nComponents)
 
  348   assert(Z.size1() >= Z.size2());
 
  349   unsigned int nrows = Z.size1(); 
 
  350   assert(nComponents >= nrows);
 
  360   for (i = 0; i < nrows; i++)
 
  364   for (k = 0; k < nrows; k++)
 
  367     while (Z(i, k) == 0.0)
 
  383       for (j=0; j < nrows; j ++)
 
  392     for (i = k + 1; i < nrows; i++)
 
  396       for (j = k + 1; j < nrows; j++)
 
  397         Z (i, j) = Z (i, j) - m * Z(k, j);
 
  402   if (Z(nrows - 1, nrows - 1) == 0.0)
 
  408 bool fowardBackSubstitution(boost::numeric::ublas::matrix<double>& Z, std::vector<double>& y, 
unsigned int ys, std::vector<int>& row, 
unsigned int rows, std::vector<double>& x, 
unsigned int xs)
 
  411   assert(Z.size1() >= Z.size2());
 
  412   unsigned int nrows = Z.size1(); 
 
  414   if (((rows < nrows) || (ys < nrows) || (xs < nrows)))
 
  419   std::vector<double> F(nrows, 0.0);
 
  422   for (k = 0; k < (int) nrows; k++)
 
  425     for (j = 0; j <= k - 1; j++)
 
  426       aux = aux + Z(k, j) * F[j];
 
  428     F[k] = y[row[k]] - aux;
 
  432   for (k = ((
int) nrows) - 1; k >= 0; k--)
 
  435     for (j = k + 1; j < (int) nrows; j++)
 
  436       aux = aux + Z(k, j) * x[j];
 
  438     x[k] = (F[k] - aux) / Z(k, k);
 
bool execute(const te::rst::Raster &inputRaster, const std::vector< unsigned int > &inputRasterBands, const std::vector< std::string > &inputSensorBands, const std::map< std::string, std::vector< double > > &components, te::rst::Raster &outputRaster, const bool enableProgressInterface)
Executes the segmentation strategy. 
 
~MixtureModelPCAStrategyFactory()
 
MixtureModelPCAStrategy()
 
Raster strategy parameters base class. 
 
Raster Processing functions. 
 
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
 
Raster mixture model strategy base class. 
 
bool m_isInitialized
True if this instance is initialized. 
 
double GetDigitalNumberBandMax(std::string bandName)
Returns the maximum digital number of a given sensor/band. 
 
bool gaussElimination(boost::numeric::ublas::matrix< double > &Z, std::vector< int > &row, unsigned int nComponents)
 
#define TR_RP(message)
It marks a string in order to get translated. This is a special mark used in the Raster Processing mo...
 
MixtureModelPCAStrategy::Parameters m_parameters
Internal execution parameters. 
 
#define TERP_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged and a return of context wi...
 
Abstract parameters base interface. 
 
Raster PCA mixture model strategy factory. 
 
~MixtureModelPCAStrategy()
 
te::rp::MixtureModelStrategy * build()
Concrete factories (derived from this one) must implement this method in order to create objects...
 
const Parameters & operator=(const Parameters ¶ms)
 
AbstractParameters * clone() const 
Create a clone copy of this instance. 
 
An abstract class for raster data strucutures. 
 
This class can be used to inform the progress of a task. 
 
bool initialize(StrategyParameters const *const strategyParams)
Initialize the segmentation strategy. 
 
bool fowardBackSubstitution(boost::numeric::ublas::matrix< double > &Z, std::vector< double > &y, unsigned int ys, std::vector< int > &row, unsigned int rows, std::vector< double > &x, unsigned int xs)
 
Raster Mixture model strategy factory base class. 
 
PCA (Principal Component Analysis) strategy for mixture model. 
 
bool EigenVectors(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &eigenVectorsMatrix, boost::numeric::ublas::matrix< T > &eigenValuesMatrix)
Computes the eigenvectors of a given matrix. 
 
MixtureModelPCAStrategyFactory()