30 #include "../raster/Band.h" 
   31 #include "../common/MatrixUtils.h" 
   64   m_trainSamplesPtr = 0;
 
   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 ) ) );
 
bool isActive() const 
Verify if the task is active. 
 
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not. 
 
unsigned int m_prioriCalcSampleStep
A positive non-zero sample step used when calculating piori probabilities (default:2 - half of sample...
 
unsigned int getNumberOfRows() const 
Returns the raster number of rows. 
 
Raster strategy parameters base class. 
 
std::vector< double > m_classesOptizedMAPDiscriminantTerm
An optimized portion of the MAP discriminant function. 
 
std::vector< double > ClassSampleT
Class sample type definition. 
 
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster. 
 
te::rp::ClassifierStrategy * build()
Concrete factories (derived from this one) must implement this method in order to create objects...
 
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. 
 
bool m_isInitialized
Is this instance initialized? 
 
#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. 
 
std::vector< boost::numeric::ublas::matrix< double > > m_classesCovarianceMatrixes
Classes covariance matrixes. 
 
Maximum a posteriori probability strategy factory. 
 
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1. 
 
~ClassifierMAPStrategyFactory()
 
unsigned int ClassIDT
Class ID type definition (zero means invalid ID). 
 
std::vector< double > m_prioriProbs
Priori probabilities, one for each class. Values from 0 to 1 (use an empty vector to allow internal c...
 
Raster classifier strategy factory base class. 
 
ClassifierMAPStrategy::Parameters m_initParams
Initialization parameters. 
 
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. 
 
bool getInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Matrix inversion. 
 
unsigned int getNumberOfColumns() const 
Returns the raster number of columns. 
 
bool GetDeterminant(const boost::numeric::ublas::matrix< T > &inputMatrix, double &determinant)
Get the Matrix determinant value. 
 
Maximum a posteriori probability strategy. 
 
std::vector< ClassSampleT > ClassSamplesContainerT
Class samples container type definition. 
 
const Parameters & operator=(const Parameters ¶ms)
 
bool initialize(StrategyParameters const *const strategyParams)
Initialize the classification strategy. 
 
An abstract class for raster data strucutures. 
 
This class can be used to inform the progress of a task. 
 
std::vector< std::vector< double > > m_classesMeans
Classes means;. 
 
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. 
 
Maximum a posteriori probability strategy. 
 
AbstractParameters * clone() const 
Create a clone copy of this instance. 
 
MClassesSamplesCT const * m_trainSamplesPtr
A pointer to a always-valid structure where trainning samples are stored. 
 
std::vector< boost::numeric::ublas::matrix< double > > m_classesCovarianceInvMatrixes
Classes covariance inverse matrixes. 
 
Raster classifier strategy base class. 
 
std::vector< Parameters::ClassIDT > m_classesIndex2ID
An class index ordered vector of classes IDs;. 
 
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
 
ClassifierMAPStrategyFactory()