ClassifierKMeansStrategy.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/rp/ClassifierKMeansStrategy.cpp
22 
23  \brief KMeans strategy for image classification.
24 */
25 
26 // TerraLib
27 #include "../classification/KMeans.h"
28 #include "../common/progress/TaskProgress.h"
29 #include "../geometry/Envelope.h"
30 #include "../raster/Grid.h"
31 #include "../raster/PositionIterator.h"
32 #include "../raster/RasterIterator.h"
33 #include "../raster/Utils.h"
35 #include "Macros.h"
36 #include "Functions.h"
37 
38 // STL
39 #include <iostream>
40 #include <stdlib.h>
41 
42 namespace
43 {
44  static te::rp::ClassifierKMeansStrategyFactory classifierKMeansStrategyFactoryInstance;
45 }
46 
48 {
49  reset();
50 }
51 
53 
55 {
56  reset();
57 
58  m_K = rhs.m_K;
61  m_epsilon = rhs.m_epsilon;
62 
63  return *this;
64 }
65 
67 {
68  m_K = 0;
69  m_maxIterations = 0;
70  m_maxInputPoints = 0;
71  m_epsilon = 0.0;
72 }
73 
75 {
77 }
78 
80 {
81  m_isInitialized = false;
82 }
83 
85 
86 bool te::rp::ClassifierKMeansStrategy::initialize(te::rp::ClassifierStrategyParameters const* const strategyParams) throw(te::rp::Exception)
87 {
88  m_isInitialized = false;
89 
90  te::rp::ClassifierKMeansStrategy::Parameters const* paramsPtr = dynamic_cast<te::rp::ClassifierKMeansStrategy::Parameters const*>(strategyParams);
91 
92  if(!paramsPtr)
93  return false;
94 
95  m_parameters = *(paramsPtr);
96 
97  TERP_INSTANCE_TRUE_OR_RETURN_FALSE(m_parameters.m_K > 1, TE_TR("The value of K (number of clusters) must be at least 2."))
98  TERP_INSTANCE_TRUE_OR_RETURN_FALSE(m_parameters.m_maxIterations > 0, TE_TR("The number of iterations must be at least 1."))
99  TERP_INSTANCE_TRUE_OR_RETURN_FALSE(m_parameters.m_epsilon > 0, TE_TR("The stop criteria must be higher than 0."))
100 
103 
104  m_isInitialized = true;
105 
106  return true;
107 }
108 
110 {
111  TERP_INSTANCE_TRUE_OR_RETURN_FALSE(m_isInitialized, TE_TR("Instance not initialized"))
112 
113  // Creating the output raster
114 
115  std::vector< int > dt;
116  dt.push_back( te::dt::UINT32_TYPE );
117 
118  std::vector< double > noDataValues;
119  noDataValues.push_back( (double)( m_parameters.m_K + 2 ) ) ;
120 
122  "Output raster creation error" );
123 
125  "Output raster palette creation error" );
126 
127 
128 // defining classification parameters
130  classifierParameters.m_K = m_parameters.m_K;
131  classifierParameters.m_maxIterations = m_parameters.m_maxIterations;
132  classifierParameters.m_epsilon = m_parameters.m_epsilon;
133  std::vector<unsigned int> classification;
134 
135 // define point set iterators for training
136  std::vector<te::gm::Point*> randomPoints = te::rst::GetRandomPointsInRaster(
139  ( te::rst::Raster* )m_inputRasterPtr, randomPoints);
141  ( te::rst::Raster* )m_inputRasterPtr, randomPoints);
142 
143 // define raster iterators for classification
148 
149 // execute the algorithm
151 
152  if(!classifier.initialize(classifierParameters))
153  throw;
154  if(!classifier.train(pit, pitend, m_inputRasterBands, std::vector<unsigned int>(), true))
155  throw;
156  if(!classifier.classify(rit, ritend, m_inputRasterBands, classification, true))
157  throw;
158 
159 // classifying image
160 
161  const te::rst::Band& inBand0 = *m_inputRasterPtr->getBand( m_inputRasterBands[ 0 ] );
162  te::rst::Band& outBand0 = *m_outputRasterPtr->getBand( 0 );
163 
164  const double outNoDataValue = outBand0.getProperty()->m_noDataValue;
165  const double inNoDataValue = inBand0.getProperty()->m_noDataValue;
166 
169  task.setMessage(TE_TR("KMeans algorithm - classifying image"));
170  task.setCurrentStep(0);
171  unsigned int i = 0;
172  unsigned int col = 0;
173  unsigned int row = 0;
174  double inputValue = 0;
175 
176  while (rit != ritend)
177  {
178  col = rit.getColumn();
179  row = rit.getRow();
180 
181  inBand0.getValue( col, row, inputValue );
182 
183  if( inputValue == inNoDataValue )
184  {
185  outBand0.setValue( col, row, outNoDataValue );
186  }
187  else
188  {
189  m_outputRasterPtr->setValue( col, row, classification[i], 0);
190  }
191 
192  ++i;
193  ++rit;
194  task.pulse();
195  }
196 
197  return true;
198 }
199 
201  : te::rp::ClassifierStrategyFactory("kmeans")
202 {
203 }
204 
206  default;
207 
209 {
211 }
ClassifierKMeansStrategy::Parameters m_parameters
Internal execution parameters.
Raster KMeans Classifier strategy factory.
void setMessage(const std::string &message)
Set the task message.
bool initialize(const Parameters &params)
Definition: KMeans.h:175
unsigned int getRow() const
Returns the current row in iterator.
KMeans strategy for image classification.
Base exception class for plugin module.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
bool createOutputRaster(const std::vector< int > &bandsDataTypes, const std::vector< double > &noDataValues)
Create the output raster using the EXPANSIBLE driver.
This class implements and iterator to "navigate" over a raster, with a predefined number of bands...
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
bool classify(TCLASSIFY &itBegin, TCLASSIFY &itEnd, const std::vector< unsigned int > &attributesIndices, std::vector< unsigned int > &classification, const bool enableProgressInterface)
Definition: KMeans.h:304
static PointSetIterator end(const te::rst::Raster *r, const std::vector< te::gm::Point * > p)
Returns an iterator referring to after the end of the iterator.
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
unsigned int m_maxInputPoints
The maximum number of points used to estimate the clusters (default = 1000).
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
bool execute()
Executes the classification strategy.
This class implements the strategy to iterate with spatial restriction, the iteration occurs inside a...
std::vector< unsigned int > m_inputRasterBands
Input raster bands.
void setTotalSteps(int value)
Set the task total stepes.
te::rp::ClassifierStrategy * build()
Concrete factories (derived from this one) must implement this method in order to create objects...
Raster classifier strategy factory base class.
unsigned int m_K
The number of clusters (means) to detect in image.
const Parameters & operator=(const Parameters &params)
An abstract class for raster data strucutures.
static RasterIterator begin(Raster *r, const std::vector< unsigned int > &bands)
Returns an iterator referring to the first value.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
BandProperty * getProperty()
Returns the band property.
URI C++ Library.
Definition: Attributes.h:37
static te::dt::TimeDuration dt(20, 30, 50, 11)
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
A raster band description.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
double m_epsilon
The stop criteria. When the clusters change in a value smaller then epsilon, the convergence is achie...
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
std::unique_ptr< te::rst::Raster > m_outputRasterPtr
A pointer to the output raster.
bool m_isInitialized
True if this instance is initialized.
KMeans strategy for classification. Step-by-step:
Definition: KMeans.h:62
Abstract parameters base interface.
te::rst::Raster const * m_inputRasterPtr
A pointer to the input raster.
void setCurrentStep(int value)
Set the task current step.
Raster classifier strategy base class.
TERASTEREXPORT std::vector< te::gm::Point * > GetRandomPointsInRaster(const te::rst::Raster &inputRaster, unsigned int numberOfPoints=1000)
Creates a vector of random positions (points) inside the raster.
unsigned int m_maxIterations
The maximum of iterations to perform if convergence is not achieved.
static RasterIterator end(Raster *r, const std::vector< unsigned int > &bands)
Returns an iterator referring to after the end of the iterator.
unsigned int getColumn() const
Returns the current column in iterator.
Raster Processing functions.
AbstractParameters * clone() const
Create a clone copy of this instance.
#define TERP_INSTANCE_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged, the current instance erro...
Definition: Macros.h:200
bool setOutputRasterPalette(const unsigned int size)
Create and set the output raster palette folowing the current internal settings.
unsigned int col
bool initialize(ClassifierStrategyParameters const *const strategyParams)
Initialize the classification strategy.
static PointSetIterator begin(const te::rst::Raster *r, const std::vector< te::gm::Point * > p)
Returns an iterator referring to the first value of the band.
KMeans strategy for image classification. Step-by-step:
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
bool train(TTRAIN &itBegin, TTRAIN &itEnd, const std::vector< unsigned int > &attributesIndices, const std::vector< unsigned int > &labels, const bool enableProgressInterface)
Definition: KMeans.h:198