30 #include "../raster/Band.h"
31 #include "../common/MatrixUtils.h"
64 m_trainSamplesPtr.reset();
65 m_prioriProbs.clear();
66 m_prioriCalcSampleStep = 2;
103 "Invalid classes samples pointer" )
105 "Invalid classes samples number" )
107 "Invalid classes samples number" )
112 castParamsPtr->
m_trainSamplesPtr->size(),
"Invalid classes priory probabilities" );
113 for( std::vector< double >::size_type pIdx = 0 ; pIdx <
119 "Invalid classes priory probabilities" );
124 "Invalid sample step" );
130 const unsigned int dimsNumber = (
unsigned int)
134 Parameters::MClassesSamplesCT::const_iterator classesIt =
136 const Parameters::MClassesSamplesCT::const_iterator classesItE =
139 while( classesIt != classesItE )
145 "Invalid class samples number" );
149 unsigned int dimIdx = 0;
151 for( dimIdx = 0 ; dimIdx < dimsNumber ; ++dimIdx )
153 double& dimMean = classMeans[ dimIdx ];
156 Parameters::ClassSamplesContainerT::const_iterator samplesIt =
157 classSamples.begin();
158 const Parameters::ClassSamplesContainerT::const_iterator samplesItE =
161 while( samplesIt != samplesItE )
164 "Sample size mismatch" )
165 dimMean += samplesIt->operator[]( dimIdx );
170 dimMean /= (double)( classSamples.size() );
185 Parameters::MClassesSamplesCT::const_iterator classesIt =
187 const Parameters::MClassesSamplesCT::const_iterator classesItE =
189 unsigned int classIdx = 0;
191 while( classesIt != classesItE )
195 "Invalid class samples number" );
197 const std::vector< double >& classMeans =
m_classesMeans[ classIdx ];
199 boost::numeric::ublas::matrix< double > classCovarianceMatrix( dimsNumber, dimsNumber );
201 unsigned int dimIdx1 = 0;
202 unsigned int dimIdx2 = 0;
204 for( dimIdx1 = 0 ; dimIdx1 < dimsNumber ; ++dimIdx1 )
206 const double& dimMean1 = classMeans[ dimIdx1 ];
208 for( dimIdx2 = 0 ; dimIdx2 < dimsNumber ; ++dimIdx2 )
210 const double& dimMean2 = classMeans[ dimIdx2 ];
212 double& covariance = classCovarianceMatrix( dimIdx1, dimIdx2 );
215 Parameters::ClassSamplesContainerT::const_iterator samplesIt =
216 classSamples.begin();
217 const Parameters::ClassSamplesContainerT::const_iterator samplesItE =
220 while( samplesIt != samplesItE )
224 ( samplesIt->operator[]( dimIdx1 ) - dimMean1 )
226 ( samplesIt->operator[]( dimIdx2 ) - dimMean2 )
232 covariance /= (double)( classSamples.size() );
238 double classCovarianceMatrixDet = 0;
240 classCovarianceMatrixDet ),
"Determinant matrix error" );
241 if( classCovarianceMatrixDet > 0.0 )
244 classCovarianceMatrixDet ) );
251 boost::numeric::ublas::matrix< double > classCovarianceInvMatrix;
253 classCovarianceInvMatrix ),
"Inverse matrix calcule error" );
270 const std::vector<unsigned int>& inputRasterBands,
272 const unsigned int outputRasterBand,
273 const bool enableProgressInterface)
throw(te::rp::Exception)
276 "Classification strategy not initialized" );
279 "Invalid input bands" );
281 "Invalid output band" );
283 outputRaster.getNumberOfColumns(),
"Rasters dims mismatch" );
285 outputRaster.getNumberOfRows(),
"Rasters dims mismatch" );
289 std::auto_ptr< te::common::TaskProgress > progressPtr;
290 if( enableProgressInterface )
295 progressPtr->setTotalSteps( inputRaster.getNumberOfRows() +
298 progressPtr->setTotalSteps( inputRaster.getNumberOfRows() );
300 progressPtr->setMessage(
"Classifying" );
305 std::vector< double > logPrioriProbs;
310 inputRasterBands, progressPtr.get(), logPrioriProbs ),
"Priori probabilities calcule error" );
312 for(
unsigned int pIdx = 0 ; pIdx < logPrioriProbs.size() ; ++pIdx )
313 logPrioriProbs[ pIdx ] = ( logPrioriProbs[ pIdx ] > 0.0 ) ?
314 std::log( logPrioriProbs[ pIdx ] ) : 0.0;
325 const unsigned int classesNumber = (
unsigned int)
m_classesMeans.size();
326 const unsigned int nRows = (
unsigned int)inputRaster.getNumberOfRows();
327 const unsigned int nCols = (
unsigned int)inputRaster.getNumberOfColumns();
328 const unsigned int nDims = (
unsigned int)inputRasterBands.size();
329 unsigned int col = 0;
330 unsigned int dim = 0;
331 boost::numeric::ublas::matrix< double > sample( nDims, 1 );
332 boost::numeric::ublas::matrix< double > sampleMinusMean( nDims, 1 );
333 boost::numeric::ublas::matrix< double > sampleMinusMeanT( 1, nDims );
334 boost::numeric::ublas::matrix< double > auxMatrix;
335 boost::numeric::ublas::matrix< double > mahalanobisDistanceMatrix;
336 unsigned int bandIdx = 0;
337 unsigned int classIdx = 0;
338 double discriminantFunctionValue = 0;
339 double closestClassdiscriminantFunctionValue = 0;
340 unsigned int closestClassIdx = 0;
342 for(
unsigned int row = 0 ; row < nRows ; ++row )
344 for( col = 0 ; col < nCols ; ++col )
348 for( dim = 0 ; dim < nDims ; ++dim )
350 bandIdx = inputRasterBands[ dim ];
352 "Invalid band index" );
354 inputRaster.getValue( col, row, sample( dim, 0 ), bandIdx );
359 closestClassdiscriminantFunctionValue = -1.0 * DBL_MAX;
361 for( classIdx = 0 ; classIdx < classesNumber ; ++classIdx )
365 for( dim = 0 ; dim < nDims ; ++dim )
367 sampleMinusMean( dim, 0 ) = sampleMinusMeanT( 0, dim ) =
368 ( sample( dim, 0 ) - classMeans[ dim ] );
372 auxMatrix = boost::numeric::ublas::prod( sampleMinusMeanT,
374 mahalanobisDistanceMatrix = boost::numeric::ublas::prod( auxMatrix, sampleMinusMean );
378 discriminantFunctionValue = logPrioriProbs[ classIdx ]
380 - ( 0.5 * mahalanobisDistanceMatrix( 0, 0 ) );
382 if( discriminantFunctionValue > closestClassdiscriminantFunctionValue )
384 closestClassdiscriminantFunctionValue = discriminantFunctionValue;
385 closestClassIdx = classIdx;
392 if( enableProgressInterface )
394 progressPtr->pulse();
395 if( ! progressPtr->isActive() )
return false;
404 const std::vector<unsigned int>& inputRasterBands,
406 std::vector< double >& prioriProbabilities )
const
409 "Classification strategy not initialized" );
412 "Invalid input bands" );
414 prioriProbabilities.clear();
418 const unsigned int classesNumber = (
unsigned int)
m_classesMeans.size();
419 const unsigned int nRows = (
unsigned int)inputRaster.
getNumberOfRows();
421 const unsigned int nDims = (
unsigned int)inputRasterBands.size();
422 const double initialPrioriProbLog = std::log( 1.0 / ( (
double)classesNumber ) );
423 unsigned int col = 0;
424 unsigned int dim = 0;
425 boost::numeric::ublas::matrix< double > sample( nDims, 1 );
426 boost::numeric::ublas::matrix< double > sampleMinusMean( nDims, 1 );
427 boost::numeric::ublas::matrix< double > sampleMinusMeanT( 1, nDims );
428 boost::numeric::ublas::matrix< double > auxMatrix;
429 boost::numeric::ublas::matrix< double > mahalanobisDistanceMatrix;
430 unsigned int bandIdx = 0;
431 unsigned int classIdx = 0;
432 double discriminantFunctionValue = 0;
433 double closestClassdiscriminantFunctionValue = 0;
434 unsigned int closestClassIdx = 0;
435 std::vector< unsigned long int > elementsNumberByClass( classesNumber, 0 );
436 unsigned int totalSamplesNumber = 0;
444 for( dim = 0 ; dim < nDims ; ++dim )
446 bandIdx = inputRasterBands[ dim ];
448 "Invalid band index" );
450 inputRaster.
getValue( col, row, sample( dim, 0 ), bandIdx );
455 closestClassdiscriminantFunctionValue = -1.0 * DBL_MAX;
457 for( classIdx = 0 ; classIdx < classesNumber ; ++classIdx )
461 for( dim = 0 ; dim < nDims ; ++dim )
463 sampleMinusMean( dim, 0 ) = sampleMinusMeanT( 0, dim ) =
464 ( sample( dim, 0 ) - classMeans[ dim ] );
468 auxMatrix = boost::numeric::ublas::prod( sampleMinusMeanT,
470 mahalanobisDistanceMatrix = boost::numeric::ublas::prod( auxMatrix, sampleMinusMean );
474 discriminantFunctionValue = initialPrioriProbLog
476 - ( 0.5 * mahalanobisDistanceMatrix( 0, 0 ) );
478 if( discriminantFunctionValue > closestClassdiscriminantFunctionValue )
480 closestClassdiscriminantFunctionValue = discriminantFunctionValue;
481 closestClassIdx = classIdx;
485 ++( elementsNumberByClass[ closestClassIdx ] );
486 ++totalSamplesNumber;
491 progressPtr->
pulse();
492 if( ! progressPtr->
isActive() )
return false;
496 if( totalSamplesNumber )
498 for( classIdx = 0 ; classIdx < classesNumber ; ++classIdx )
500 prioriProbabilities.push_back( ( (
double)elementsNumberByClass[ classIdx ] ) /
501 ( (
double)( totalSamplesNumber ) ) );
ClassifierMAPStrategy::Parameters m_initParams
Initialization parameters.
std::vector< Parameters::ClassIDT > m_classesIndex2ID
An class index ordered vector of classes IDs;.
MClassesSamplesCTPtr m_trainSamplesPtr
A shared pointer to a always-valid structure where trainning samples are stored.
Maximum a posteriori probability strategy factory.
bool execute(const te::rst::Raster &inputRaster, const std::vector< unsigned int > &inputRasterBands, const std::vector< te::gm::Polygon * > &inputPolygons, te::rst::Raster &outputRaster, const unsigned int outputRasterBand, const bool enableProgressInterface)
Executes the classification strategy.
ClassifierMAPStrategyFactory()
unsigned int m_prioriCalcSampleStep
A positive non-zero sample step used when calculating piori probabilities (default:2 - half of sample...
Maximum a posteriori probability strategy.
std::vector< std::vector< double > > m_classesMeans
Classes means;.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
std::vector< double > m_classesOptizedMAPDiscriminantTerm
An optimized portion of the MAP discriminant function.
const Parameters & operator=(const Parameters ¶ms)
This class can be used to inform the progress of a task.
unsigned int ClassIDT
Class ID type definition (zero means invalid ID).
bool isActive() const
Verify if the task is active.
std::vector< double > m_prioriProbs
Priori probabilities, one for each class. Values from 0 to 1 (use an empty vector to allow internal c...
#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...
Raster classifier strategy factory base class.
std::vector< boost::numeric::ublas::matrix< double > > m_classesCovarianceInvMatrixes
Classes covariance inverse matrixes.
bool GetDeterminant(const boost::numeric::ublas::matrix< T > &inputMatrix, double &determinant)
Get the Matrix determinant value.
std::vector< double > ClassSampleT
Class sample type definition.
An abstract class for raster data strucutures.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
Raster strategy parameters base class.
bool m_isInitialized
Is this instance initialized?
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
virtual void getValue(unsigned int c, unsigned int r, double &value, std::size_t b=0) const
Returns the attribute value of a band of a cell.
Maximum a posteriori probability strategy.
Abstract parameters base interface.
te::rp::ClassifierStrategy * build()
Concrete factories (derived from this one) must implement this method in order to create objects...
AbstractParameters * clone() const
Create a clone copy of this instance.
bool initialize(StrategyParameters const *const strategyParams)
Initialize the classification strategy.
Raster classifier strategy base class.
bool GetInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Matrix inversion.
~ClassifierMAPStrategyFactory()
bool getPrioriProbabilities(const te::rst::Raster &inputRaster, const std::vector< unsigned int > &inputRasterBands, te::common::TaskProgress *const progressPtr, std::vector< double > &prioriProbabilities) const
Calcule of priori probabilities following the current internal state.
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
std::vector< ClassSampleT > ClassSamplesContainerT
Class samples container type definition.
std::vector< boost::numeric::ublas::matrix< double > > m_classesCovarianceMatrixes
Classes covariance matrixes.