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 std::vector<te::rst::Raster*>& outputRaster,
const bool normalize,
const bool enableProgressInterface)
throw(te::rp::Exception)
107 const unsigned int nComponents = (
unsigned int)components.size();
108 const unsigned int nBands = (
unsigned int)inputSensorBands.size();
110 double dummy = outputRaster[0]->getBand(0)->getProperty()->m_noDataValue;
112 bool computeErrorRasters =
false;
113 if (nComponents < outputRaster[0]->getNumberOfBands())
114 computeErrorRasters =
true;
117 unsigned int i, j, k, m;
119 std::vector<double> Qmax;
120 std::vector<double> Qmin;
121 for (i = 0; i < inputSensorBands.size(); i++)
129 std::vector<te::rst::BandProperty*> tmpbandsProperties;
130 for (
unsigned i = 0; i < outputRaster[0]->getNumberOfBands(); i++)
135 tmpbandsProperties.push_back(bprop);
137 std::unique_ptr<te::rst::Raster> tmpRaster(
te::rst::RasterFactory::make(
"MEM", tmpgrid, tmpbandsProperties, std::map<std::string, std::string>()));
140 std::vector<double> tmp_min;
141 std::vector<double> tmp_max;
142 for (
unsigned i = 0; i < outputRaster[0]->getNumberOfBands(); i++)
144 tmp_min.push_back(std::numeric_limits< double >::max());
145 tmp_max.push_back(-std::numeric_limits< double >::max());
149 m_max.push_back(255);
153 m_min.push_back(std::numeric_limits< double >::max());
154 m_max.push_back(-std::numeric_limits< double >::max());
156 m_minerror.push_back(std::numeric_limits< double >::max());
157 m_maxerror.push_back(-std::numeric_limits< double >::max());
167 boost::numeric::ublas::matrix<double> SpectralBandsComponentsTransposed(nComponents, nBands);
170 SpectralBandsComponentsTransposed = boost::numeric::ublas::trans(
m_transfMatrix);
174 std::vector<double> componentsMean(nBands, 0.0);
175 std::vector<double> componentsMeanAfter(nBands, 0.0);
177 for (j = 0; j < nBands; j++)
180 componentsMean[j] = 0;
181 for(i = 0; i < nComponents; i++)
182 componentsMean[j] = componentsMean[j] + SpectralBandsComponentsTransposed(i, j);
183 componentsMean[j] = componentsMean[j] / (double) nComponents;
186 componentsMeanAfter[j] = 0;
187 for(i = 0; i < nComponents; i++)
189 SpectralBandsComponentsTransposed(i, j) = SpectralBandsComponentsTransposed(i, j) - componentsMean[j];
190 componentsMeanAfter[j] = componentsMeanAfter[j] + SpectralBandsComponentsTransposed(i, j);
192 componentsMeanAfter[j] = componentsMeanAfter[j] / (double) nComponents;
196 std::vector<double> covarianceVector(nBands * nBands, 0.0);
197 for(k = 0; k < nBands * nBands; k++)
198 covarianceVector[k] = 0;
201 for(j = 0; j < nBands; j++)
202 for(m = 0; m < j + 1; m++)
204 for(i = 0; i < nComponents; i++)
205 covarianceVector[k] = covarianceVector[k] + (SpectralBandsComponentsTransposed(i, j) - componentsMeanAfter[j]) *
206 (SpectralBandsComponentsTransposed(i, m) - componentsMeanAfter[m]);
207 covarianceVector[k] = covarianceVector[k] / (double) nComponents;
213 boost::numeric::ublas::matrix<double> covarianceMatrix(nBands, nBands);
214 for (i = 0; i < nBands; i++)
215 for (j = 0; j <= i; j++)
216 covarianceMatrix(i, j) = covarianceVector[k++];
219 boost::numeric::ublas::matrix<double> auxMatrix(covarianceMatrix);
220 boost::numeric::ublas::matrix<double> tmpMatrix;
226 boost::numeric::ublas::matrix<double> eigenReduced(nBands, nComponents - 1);
227 for (j = 0; j < nBands; j++)
228 for (i = 0; i < nComponents - 1; i++)
229 eigenReduced(j, i) = auxMatrix(j, i);
232 boost::numeric::ublas::matrix<double> SpectralBandsComponentsPCA(SpectralBandsComponentsTransposed.size1(), eigenReduced.size2());
233 SpectralBandsComponentsPCA = boost::numeric::ublas::prod(SpectralBandsComponentsTransposed, eigenReduced);
236 auxMatrix.resize(SpectralBandsComponentsPCA.size1(), SpectralBandsComponentsPCA.size2() + 1);
239 for (j = 0; j < SpectralBandsComponentsPCA.size1(); j++)
241 for (i = 0; i < SpectralBandsComponentsPCA.size2(); i++)
242 auxMatrix(j, i) = SpectralBandsComponentsPCA(j, i);
244 auxMatrix(j, SpectralBandsComponentsPCA.size2()) = 1.0;
248 SpectralBandsComponentsPCA.clear();
249 SpectralBandsComponentsPCA = boost::numeric::ublas::trans(auxMatrix);
252 std::vector<int> rows(nComponents, 0);
260 auxMatrix.resize(1, nBands);
262 boost::numeric::ublas::matrix<double> ymat(nComponents - 1, nComponents - 1);
265 std::vector<double> x(nComponents, 0.0);
266 std::vector<double> y(nComponents, 0.0);
269 std::vector<unsigned int> rowsIn(nBands, 0);
270 std::vector<unsigned int> columnIn(nBands, 0);
271 std::vector<unsigned int> columnsIn(nBands, 0);
272 std::vector<double> spectralBandsError(nBands, 0.0);
274 boost::numeric::ublas::matrix<double> rasterRowsIn(nBands, inputRaster.getNumberOfColumns());
275 boost::numeric::ublas::matrix<double> rasterRowsOut(nComponents, inputRaster.getNumberOfColumns());
279 for (
unsigned int rowout = 0; rowout < inputRaster.getNumberOfRows(); rowout++)
282 for (i = 0; i < nBands; i++)
284 for (j = 0; j < inputRaster.getNumberOfColumns(); j++)
286 inputRaster.getValue(j, rowsIn[i], value, inputRasterBands[i]);
287 rasterRowsIn(i, j) = value;
294 columnIn[i] = columnsIn[i];
298 for (
unsigned int colout = 0; colout < inputRaster.getNumberOfColumns(); colout++)
301 for (i = 0; i < nBands; i++)
302 auxMatrix(0, i) = (double) (rasterRowsIn(i, columnIn[i])) / Qmax[i] - componentsMean[i];
304 ymat = boost::numeric::ublas::prod(auxMatrix, eigenReduced);
306 for (i = 0; i < nComponents - 1; i++)
310 if (!
fowardBackSubstitution(SpectralBandsComponentsPCA, y, nComponents, rows, nComponents, x, nComponents))
313 bool hasdummy =
false;
314 for (i = 0; i < nBands; i++)
316 if (((rasterRowsIn(i, colout) == dummy)))
322 for (i = 0; i < nComponents; i++)
324 rasterRowsOut(i, colout) = dummy;
332 for (i = 0; i < nComponents; i++)
334 prop = (x[i] * 100 + 100);
335 prop = prop >= Qmax[i] ? Qmax[i] - 1 : prop <= Qmin[i] ? Qmin[i] : prop;
336 rasterRowsOut(i, colout) = prop;
343 if (computeErrorRasters)
345 for (
unsigned int ii = 0; ii < nBands; ii++)
349 for (j = 0; j < nComponents; j++)
353 error = (long) (rasterRowsIn(ii, columnIn[ii])) / Qmax[ii] - aux;
357 if (computeErrorRasters)
358 rasterRowsIn(ii, colout) = error;
363 for (i = 0; i < nBands; i++)
368 for (i = 0; i < nComponents; i++)
369 for (j = 0; j < inputRaster.getNumberOfColumns(); j++)
371 value = rasterRowsOut(i, j);
372 tmpRaster->setValue(j, rowout, value, i);
375 tmp_min[i] = value < tmp_min[i] ? value : tmp_min[i];
376 tmp_max[i] = value > tmp_max[i] ? value : tmp_max[i];
381 if (outputRaster.size() > 1)
383 for (i = 0; i < nComponents; i++)
384 for (j = 0; j < inputRaster.getNumberOfColumns(); j++)
386 value = rasterRowsIn(i, j);
387 outputRaster[1]->setValue(j, rowout, value, i);
397 for (
unsigned r = 0; r < tmpRaster->getNumberOfRows(); r++)
399 for (
unsigned c = 0; c < tmpRaster->getNumberOfColumns(); c++)
401 for (
unsigned b = 0;
b < nComponents;
b++)
403 tmpRaster->getValue(c, r, value,
b);
406 value = 255 * (value - tmp_min[
b]) / (tmp_max[
b] - tmp_min[
b]);
408 value = (Qmax[
b] - Qmin[
b]) * (value - tmp_min[b]) / (tmp_max[
b] - tmp_min[
b]);
410 outputRaster[0]->setValue(c, r, value, b);
421 boost::numeric::ublas::matrix<double>& matrix )
const 434 const std::map<std::string, std::vector<double> >& components)
436 const unsigned int nComponents = (
unsigned int)components.size();
437 const unsigned int nBands = (
unsigned int)inputSensorBands.size();
442 std::vector<double> Qmax;
443 for (i = 0; i < inputSensorBands.size(); i++)
447 boost::numeric::ublas::matrix<double> SpectralBandsComponents(nBands, nComponents);
448 std::map<std::string, std::vector<double> >::const_iterator it;
449 for (i = 0; i < nBands; i++)
450 for (j = 0, it = components.begin(); it != components.end(); j++, it++)
451 SpectralBandsComponents(i, j) = it->second[i] / Qmax[i];
486 bool gaussElimination(boost::numeric::ublas::matrix<double>& Z, std::vector<int>& row,
unsigned int nComponents)
489 assert(Z.size1() >= Z.size2());
490 unsigned int nrows = (
unsigned int)Z.size1();
491 assert(nComponents >= nrows);
501 for (i = 0; i < nrows; i++)
505 for (k = 0; k < nrows; k++)
508 while (Z(i, k) == 0.0)
524 for (j=0; j < nrows; j ++)
533 for (i = k + 1; i < nrows; i++)
537 for (j = k + 1; j < nrows; j++)
538 Z (i, j) = Z (i, j) - m * Z(k, j);
543 if (Z(nrows - 1, nrows - 1) == 0.0)
549 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)
552 assert(Z.size1() >= Z.size2());
553 unsigned int nrows = (
unsigned int)Z.size1();
555 if (((rows < nrows) || (ys < nrows) || (xs < nrows)))
560 std::vector<double>
F(nrows, 0.0);
563 for (k = 0; k < (
int) nrows; k++)
566 for (j = 0; j <= k - 1; j++)
567 aux = aux + Z(k, j) * F[j];
569 F[k] = y[row[k]] - aux;
573 for (k = ((
int) nrows) - 1; k >= 0; k--)
576 for (j = k + 1; j < (
int) nrows; j++)
577 aux = aux + Z(k, j) * x[j];
579 x[k] = (F[k] - aux) / Z(k, k);
double GetDigitalNumberBandMax(std::string bandName)
Returns the maximum digital number of a given sensor/band.
Raster Mixture model strategy factory base class.
MixtureModelPCAStrategyFactory()
Index into a lookup table.
A raster band description.
Base exception class for plugin module.
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)
std::vector< double > m_maxerror
Maximum error value.
bool initialize(StrategyParameters const *const strategyParams)
Initialize the segmentation strategy.
This class can be used to inform the progress of a task.
bool getTransformMatrix(boost::numeric::ublas::matrix< double > &matrix) const
Returns the used transformation matrix (when applicable).
MixtureModelPCAStrategy()
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
std::vector< double > m_max
Maximum value.
int m_type
The data type of the elements in the band ( See te::dt namespace basic data types for reference )...
std::vector< double > m_minerror
Minimun error value.
#define TE_TR(message)
It marks a string in order to get translated.
~MixtureModelPCAStrategyFactory()
double GetDigitalNumberBandMin(std::string bandName)
Returns the minimum digital number of a given sensor/band.
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...
bool setTransformMatrix(boost::numeric::ublas::matrix< double > &matrix)
Sets the used transformation matrix.
Raster mixture model strategy base class.
An abstract class for raster data strucutures.
bool getMinMax(std::vector< double > &, std::vector< double > &) const
const Parameters & operator=(const Parameters ¶ms)
Raster strategy parameters base class.
Raster PCA mixture model strategy factory.
~MixtureModelPCAStrategy()
std::vector< double > m_min
Transformation matrix;.
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.
Abstract parameters base interface.
bool gaussElimination(boost::numeric::ublas::matrix< double > &Z, std::vector< int > &row, unsigned int nComponents)
AbstractParameters * clone() const
Create a clone copy of this instance.
bool generateTransformMatrix(const std::vector< unsigned int > &inputRasterBands, const std::vector< std::string > &inputSensorBands, const std::map< std::string, std::vector< double > > &components)
Generates the used transformation matrix (when applicable).
boost::numeric::ublas::matrix< double > m_transfMatrix
bool m_isInitialized
True if this instance is initialized.
bool getMinMaxError(std::vector< double > &, std::vector< double > &) const
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, std::vector< te::rst::Raster * > &outputRaster, const bool normalize, const bool enableProgressInterface)
Executes the segmentation strategy.
static Raster * make()
It creates and returns an empty raster with default raster driver.
Raster Processing functions.
PCA (Principal Component Analysis) strategy for mixture model.
te::rp::MixtureModelStrategy * build()
Concrete factories (derived from this one) must implement this method in order to create objects...
A rectified grid is the spatial support for raster data.
ColorInterp m_colorInterp
The color interpretation.