All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ClassifierWizardPage.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2011-2012 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/qt/widgets/rp/ClassifierWizardPage.cpp
22 
23  \brief This file defines a class for a Classifier Wizard page.
24 */
25 
26 // TerraLib
27 #include "../../../dataaccess/dataset/DataSet.h"
28 #include "../../../dataaccess/dataset/DataSetType.h"
29 #include "../../../dataaccess/utils/Utils.h"
30 #include "../../../geometry/GeometryProperty.h"
31 #include "../../../geometry/MultiPolygon.h"
32 #include "../../../raster/Raster.h"
33 #include "../../../raster/PositionIterator.h"
34 #include "../../../rp/ClassifierEMStrategy.h"
35 #include "../../../rp/ClassifierKMeansStrategy.h"
36 #include "../../../rp/ClassifierISOSegStrategy.h"
37 #include "../classification/ROIManagerDialog.h"
38 #include "../classification/ROIManagerWidget.h"
39 #include "ClassifierWizardPage.h"
40 #include "ui_ClassifierWizardPageForm.h"
41 
42 // Qt
43 #include <QGridLayout>
44 #include <QDoubleValidator>
45 #include <QIntValidator>
46 #include <QMessageBox>
47 
48 // stl
49 #include <memory>
50 
52 
54  : QWizardPage(parent),
55  m_ui(new Ui::ClassifierWizardPageForm),
56  m_layer(0)
57 {
58 // setup controls
59  m_ui->setupUi(this);
60 
62 
63  QIntValidator* intMaxPoints = new QIntValidator(this);
64  intMaxPoints->setBottom(0);
65  m_ui->m_kMeansMaxPointsLineEdit->setValidator(intMaxPoints);
66 
67  QDoubleValidator* doubleStopCriteria = new QDoubleValidator(this);
68  doubleStopCriteria->setBottom(0.0);
69  m_ui->m_kMeansStopCriteriaLineEdit->setValidator(doubleStopCriteria);
70 
71 //configure page
72  this->setTitle(tr("Classifier"));
73  this->setSubTitle(tr("Select the type of classifier and set their specific parameters."));
74 
75  //configure roi manager
76  m_roiMngDlg.reset(new te::qt::widgets::ROIManagerDialog(this, Qt::Tool));
77 
78  //connects
79  connect(m_ui->m_acquireToolButton, SIGNAL(toggled(bool)), this, SLOT(showROIManager(bool)));
80  connect(m_ui->m_samAcquireToolButton, SIGNAL(toggled(bool)), this, SLOT(showROIManager(bool)));
81  connect(m_roiMngDlg.get(), SIGNAL(roiManagerClosed()), this, SLOT(onROIManagerClosed()));
82 
83  connect(m_roiMngDlg->getWidget(), SIGNAL(roiSetChanged(te::cl::ROISet*)), this, SLOT(onRoiSetChanged(te::cl::ROISet*)));
84 
85  m_ui->m_acquireToolButton->setIcon(QIcon::fromTheme("wand"));
86  m_ui->m_samAcquireToolButton->setIcon(QIcon::fromTheme("wand"));
87 }
88 
90 {
91 
92 }
93 
95 {
96  m_layer = layer;
97 
98  m_roiMngDlg->set(m_layer);
99 
100  listBands();
101 }
102 
103 void te::qt::widgets::ClassifierWizardPage::setList(std::list<te::map::AbstractLayerPtr>& layerList)
104 {
105  m_roiMngDlg->setList(layerList);
106 
107  m_ui->m_isosegLayersComboBox->clear();
108 
109  std::list<te::map::AbstractLayerPtr>::iterator it = layerList.begin();
110 
111  while(it != layerList.end())
112  {
114 
115  std::auto_ptr<te::da::DataSetType> dsType = l->getSchema();
116 
117  if(dsType->hasGeom())
118  m_ui->m_isosegLayersComboBox->addItem(it->get()->getTitle().c_str(), QVariant::fromValue(l));
119 
120  ++it;
121  }
122 }
123 
125 {
126  int idx = m_ui->m_classifierTypeComboBox->currentIndex();
127  int type = m_ui->m_classifierTypeComboBox->itemData(idx).toInt();
128 
129  te::rp::Classifier::InputParameters algoInputParams;
130 
131  if(type == CLASSIFIER_ISOSEG)
132  {
133  algoInputParams.m_strategyName = "isoseg";
134 
136  classifierparameters.m_acceptanceThreshold = m_ui->m_acceptanceThresholdComboBox->currentText().toDouble();
137 
138  //get layer
139  int idxLayer = m_ui->m_isosegLayersComboBox->currentIndex();
140  QVariant varLayer = m_ui->m_isosegLayersComboBox->itemData(idxLayer, Qt::UserRole);
141  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
142 
143  //get polygons
144  std::auto_ptr<te::da::DataSetType> dsType = layer->getSchema();
146 
147  if(gp && gp->getGeometryType() == te::gm::MultiPolygonType)
148  {
149  std::auto_ptr<te::da::DataSet> ds = layer->getData();
150  ds->moveBeforeFirst();
151 
152  while(ds->moveNext())
153  {
154  te::gm::MultiPolygon* mp = (te::gm::MultiPolygon*)ds->getGeometry(gp->getName()).release();
155  te::gm::Polygon* poly = (te::gm::Polygon*)mp->getGeometries()[0];
156 
157  algoInputParams.m_inputPolygons.push_back(poly);
158  }
159  }
160 
161  algoInputParams.setClassifierStrategyParams(classifierparameters);
162  }
163  else if(type == CLASSIFIER_KMEANS)
164  {
165  algoInputParams.m_strategyName = "kmeans";
166 
168  classifierparameters.m_K = m_ui->m_kMeansClusterSpinBox->value();
169  classifierparameters.m_maxIterations = m_ui->m_kMeansIterationsSpinBox->value();
170  classifierparameters.m_maxInputPoints = m_ui->m_kMeansMaxPointsLineEdit->text().toInt();
171  classifierparameters.m_epsilon = m_ui->m_kMeansStopCriteriaLineEdit->text().toDouble();
172 
173  algoInputParams.setClassifierStrategyParams(classifierparameters);
174  }
175  else if(type == CLASSIFIER_MAP)
176  {
177  algoInputParams.m_strategyName = "map";
178 
179  std::auto_ptr<te::da::DataSet> ds = m_layer->getData();
180  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
181  std::auto_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
182 
183  te::rp::ClassifierMAPStrategy::Parameters classifierparameters;
184  classifierparameters.m_trainSamplesPtr = getMAPSamples(m_roiMngDlg->getWidget()->getROISet(), inputRst.get());
185 
186  algoInputParams.setClassifierStrategyParams(classifierparameters);
187  }
188  else if(type == CLASSIFIER_EM)
189  {
190  algoInputParams.m_strategyName = "em";
191 
192  te::rp::ClassifierEMStrategy::Parameters classifierparameters;
193  classifierparameters.m_numberOfClusters = m_ui->m_emClusterSpinBox->value();
194  classifierparameters.m_maxIterations = m_ui->m_emIterationsSpinBox->value();
195  classifierparameters.m_maxInputPoints = m_ui->m_emMaxPointsLineEdit->text().toInt();
196  classifierparameters.m_epsilon = m_ui->m_emStopCriteriaLineEdit->text().toDouble();
197  classifierparameters.m_clustersMeans = std::vector<std::vector<double> >();
198 
199  algoInputParams.setClassifierStrategyParams(classifierparameters);
200  }
201  else if(type == CLASSIFIER_SAM)
202  {
203  algoInputParams.m_strategyName = "sam";
204 
205  std::auto_ptr<te::da::DataSet> ds = m_layer->getData();
206  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
207  std::auto_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
208 
209  te::rp::ClassifierSAMStrategy::Parameters classifierparameters;
210  classifierparameters.m_trainSamplesPtr = getSAMSamples(m_roiMngDlg->getWidget()->getROISet(), inputRst.get());
211 
212  //get angle values
213  for(int i = 0; i < m_ui->m_samTableWidget->rowCount(); ++i)
214  {
215  double val = ((QDoubleSpinBox*)m_ui->m_samTableWidget->cellWidget(i, 3))->value();
216 
217  classifierparameters.m_maxAngularDistances.push_back(val);
218  }
219 
220  algoInputParams.setClassifierStrategyParams(classifierparameters);
221  }
222 
223  //get bands
224  QList<QListWidgetItem*> selectedBands = m_ui->m_inputRasterBandsListWidget->selectedItems();
225 
226  QList<QListWidgetItem*>::const_iterator it = selectedBands.begin();
227  QList<QListWidgetItem*>::const_iterator itend = selectedBands.end();
228 
229  while(it != itend)
230  {
231  algoInputParams.m_inputRasterBands.push_back((*it)->text().toUInt());
232 
233  ++it;
234  }
235 
236  return algoInputParams;
237 }
238 
240 {
241  te::rp::Classifier::OutputParameters algoOutputParams;
242 
243  return algoOutputParams;
244 }
245 
247 {
248  m_ui->m_classifierTypeComboBox->clear();
249 
250  m_ui->m_classifierTypeComboBox->addItem(tr("ISOSeg"), CLASSIFIER_ISOSEG);
251  m_ui->m_classifierTypeComboBox->addItem(tr("KMeans"), CLASSIFIER_KMEANS);
252  m_ui->m_classifierTypeComboBox->addItem(tr("MAP - Maximum a Posteriori Probability"), CLASSIFIER_MAP);
253  m_ui->m_classifierTypeComboBox->addItem(tr("EM - Expectation Maximization"), CLASSIFIER_EM);
254  m_ui->m_classifierTypeComboBox->addItem(tr("SAM - Spectral Angle Mapper"), CLASSIFIER_SAM);
255 }
256 
258 {
259  m_ui->m_inputRasterBandsListWidget->clear();
260 
261  assert(m_layer.get());
262 
263  //get input raster
264  std::auto_ptr<te::da::DataSet> ds = m_layer->getData();
265 
266  if(ds.get())
267  {
268  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
269 
270  std::auto_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
271 
272  if(inputRst.get())
273  {
274  for(unsigned int i = 0; i < inputRst->getNumberOfBands(); ++i)
275  {
276  m_ui->m_inputRasterBandsListWidget->addItem(QString::number(i));
277  }
278  }
279  }
280 }
281 
283 {
285 
286  std::map<std::string, te::cl::ROI*> roiSetMap = rs->getROISet();
287  std::map<std::string, te::cl::ROI*>::iterator it = roiSetMap.begin();
288 
289  int count = 1;
290 
291  //iterate roi set
292  while(it != roiSetMap.end())
293  {
294  std::map<std::string, te::gm::Polygon*> roiMap = it->second->getPolygons();
295  std::map<std::string, te::gm::Polygon*>::iterator itPoly = roiMap.begin();
296 
298 
299  //iterate roi
300  while(itPoly != roiMap.end())
301  {
302  te::gm::Polygon* p = itPoly->second;
303 
306 
307  //iterate polygon
308  while (itRaster != itRasterEnd)
309  {
311 
312  raster->getValues(itRaster.getColumn(), itRaster.getRow(), cst);
313 
314  csct.push_back(cst);
315 
316  ++itRaster;
317  }
318 
319  ++itPoly;
320  }
321 
322  mcsctPtr->insert(te::rp::ClassifierMAPStrategy::Parameters::MClassesSamplesCT::value_type(count, csct));
323 
324  ++count;
325 
326  ++it;
327  }
328 
329  return mcsctPtr;
330 }
331 
333 {
335 
336  std::map<std::string, te::cl::ROI*> roiSetMap = rs->getROISet();
337  std::map<std::string, te::cl::ROI*>::iterator it = roiSetMap.begin();
338 
339  int count = 1;
340 
341  //iterate roi set
342  while(it != roiSetMap.end())
343  {
344  std::map<std::string, te::gm::Polygon*> roiMap = it->second->getPolygons();
345  std::map<std::string, te::gm::Polygon*>::iterator itPoly = roiMap.begin();
346 
348 
349  //iterate roi
350  while(itPoly != roiMap.end())
351  {
352  te::gm::Polygon* p = itPoly->second;
353 
356 
357  //iterate polygon
358  while (itRaster != itRasterEnd)
359  {
361 
362  raster->getValues(itRaster.getColumn(), itRaster.getRow(), s);
363 
364  st.push_back(s);
365 
366  ++itRaster;
367  }
368 
369  ++itPoly;
370  }
371 
372  cstPtr->insert(te::rp::ClassifierSAMStrategy::ClassesSamplesT::value_type(count, st));
373 
374  ++count;
375 
376  ++it;
377  }
378 
379  return cstPtr;
380 }
381 
383 {
384  if(show)
385  m_roiMngDlg->show();
386  else
387  m_roiMngDlg->hide();
388 }
389 
391 {
392  m_ui->m_acquireToolButton->setChecked(false);
393  m_ui->m_samAcquireToolButton->setChecked(false);
394 }
395 
397 {
398  int idx = m_ui->m_classifierTypeComboBox->currentIndex();
399  int type = m_ui->m_classifierTypeComboBox->itemData(idx).toInt();
400 
401  if(type == CLASSIFIER_MAP)
402  {
403  m_ui->m_mapTableWidget->setRowCount(0);
404 
405  if(!rs)
406  return;
407 
408  std::map<std::string, te::cl::ROI*> roiSetMap = rs->getROISet();
409  std::map<std::string, te::cl::ROI*>::iterator it = roiSetMap.begin();
410 
411  //iterate roi set
412  while(it != roiSetMap.end())
413  {
414  //get roi info
415  te::cl::ROI* r = it->second;
416 
417  std::string label = r->getLabel();
418 
419  std::size_t samples = r->getPolygons().size();
420  QString samplesNum;
421  samplesNum.setNum(samples);
422 
423  QColor color(r->getColor().c_str());
424 
425  //add table entry
426  int newrow = m_ui->m_mapTableWidget->rowCount();
427  m_ui->m_mapTableWidget->insertRow(newrow);
428 
429  QPixmap pix(16,16);
430  pix.fill(color);
431  QIcon icon(pix);
432 
433  QTableWidgetItem* itemColor = new QTableWidgetItem(icon, "");
434  itemColor->setFlags(Qt::ItemIsEnabled);
435  m_ui->m_mapTableWidget->setItem(newrow, 0, itemColor);
436 
437  QTableWidgetItem* itemLabel = new QTableWidgetItem(QString::fromStdString(label));
438  itemLabel->setFlags(Qt::ItemIsEnabled);
439  m_ui->m_mapTableWidget->setItem(newrow, 1, itemLabel);
440 
441  QTableWidgetItem* itemSamples = new QTableWidgetItem(samplesNum);
442  itemSamples->setFlags(Qt::ItemIsEnabled);
443  m_ui->m_mapTableWidget->setItem(newrow, 2, itemSamples);
444 
445  ++it;
446  }
447 
448  m_ui->m_mapTableWidget->resizeColumnsToContents();
449  }
450  else if(type == CLASSIFIER_SAM)
451  {
452  m_ui->m_samTableWidget->setRowCount(0);
453 
454  if(!rs)
455  return;
456 
457  std::map<std::string, te::cl::ROI*> roiSetMap = rs->getROISet();
458  std::map<std::string, te::cl::ROI*>::iterator it = roiSetMap.begin();
459 
460  //iterate roi set
461  while(it != roiSetMap.end())
462  {
463  //get roi info
464  te::cl::ROI* r = it->second;
465 
466  std::string label = r->getLabel();
467 
468  std::size_t samples = r->getPolygons().size();
469  QString samplesNum;
470  samplesNum.setNum(samples);
471 
472  QColor color(r->getColor().c_str());
473 
474  //add table entry
475  int newrow = m_ui->m_mapTableWidget->rowCount();
476  m_ui->m_samTableWidget->insertRow(newrow);
477 
478  QPixmap pix(16,16);
479  pix.fill(color);
480  QIcon icon(pix);
481 
482  QTableWidgetItem* itemColor = new QTableWidgetItem(icon, "");
483  itemColor->setFlags(Qt::ItemIsEnabled);
484  m_ui->m_samTableWidget->setItem(newrow, 0, itemColor);
485 
486  QTableWidgetItem* itemLabel = new QTableWidgetItem(QString::fromStdString(label));
487  itemLabel->setFlags(Qt::ItemIsEnabled);
488  m_ui->m_samTableWidget->setItem(newrow, 1, itemLabel);
489 
490  QTableWidgetItem* itemSamples = new QTableWidgetItem(samplesNum);
491  itemSamples->setFlags(Qt::ItemIsEnabled);
492  m_ui->m_samTableWidget->setItem(newrow, 2, itemSamples);
493 
494  QDoubleSpinBox* dsb = new QDoubleSpinBox(m_ui->m_samTableWidget);
495  dsb->setMinimum(0.0);
496  dsb->setMaximum(1.0);
497  dsb->setSingleStep(0.1);
498  dsb->setValue(0.1);
499 
500  m_ui->m_samTableWidget->setCellWidget(newrow, 3, dsb);
501 
502  ++it;
503  }
504 
505  m_ui->m_samTableWidget->resizeColumnsToContents();
506  }
507 }
508 
std::vector< te::gm::Polygon * > m_inputPolygons
The polygons to be classified when using object-based image analysis (OBIA).
Definition: Classifier.h:115
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
std::map< ClassIDT, SamplesT > ClassesSamplesT
Classes samples container type definition.
Geometric property.
MClassesSamplesCTPtr m_trainSamplesPtr
A shared pointer to a always-valid structure where trainning samples are stored.
te::rp::Classifier::InputParameters getInputParams()
boost::shared_ptr< MClassesSamplesCT > MClassesSamplesCTPtr
A shared pointer to a multi classes samples container type definition.
unsigned int m_numberOfClusters
The number of clusters (classes) to estimate in the image.
std::string m_strategyName
The classifier strategy name see each te::rp::ClassifierStrategyFactory inherited classes documentati...
Definition: Classifier.h:116
void set(te::map::AbstractLayerPtr layer)
This method is used to set the selected layer for classifier operation.
void setClassifierStrategyParams(const StrategyParameters &p)
Set specific classifier strategy parameters.
Definition: Classifier.cpp:60
std::auto_ptr< te::qt::widgets::ROIManagerDialog > m_roiMngDlg
virtual void getValues(unsigned int c, unsigned int r, std::vector< double > &values) const
Returns the imaginary attribute values in all complex bands of a cell.
Definition: Raster.cpp:258
This class implements the strategy to iterate with spatial restriction, the iteration occurs inside a...
unsigned int getRow() const
Returns the current row in iterator.
unsigned int m_maxInputPoints
The maximum number of points used to estimate the clusters (default = 1000).
Classifier output parameters.
Definition: Classifier.h:127
boost::shared_ptr< ClassesSamplesT > ClassesSamplesTPtr
A shared pointer to a multi classes samples container type definition.
ClassesSamplesTPtr m_trainSamplesPtr
A shared pointer to a always-valid structure where trainning samples are stored.
A ROISet is a set of ROI's.
Definition: ROISet.h:53
te::rp::ClassifierMAPStrategy::Parameters::MClassesSamplesCTPtr getMAPSamples(te::cl::ROISet *rs, te::rst::Raster *raster)
std::vector< double > SampleT
Class sample type definition.
te::rp::ClassifierSAMStrategy::ClassesSamplesTPtr getSAMSamples(te::cl::ROISet *rs, te::rst::Raster *raster)
std::auto_ptr< Ui::ClassifierWizardPageForm > m_ui
std::map< ClassIDT, ClassSamplesContainerT > MClassesSamplesCT
Multi-classes samples container type definition.
unsigned int m_K
The number of clusters (means) to detect in image.
std::vector< double > ClassSampleT
Class sample type definition.
static PolygonIterator end(const te::rst::Raster *r, const te::gm::Polygon *p)
Returns an iterator referring to after the end of the iterator.
This file defines a class for a Classifier Wizard page.
An abstract class for raster data strucutures.
Definition: Raster.h:71
This class is a dialog for the ROI Manager widget.
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
std::vector< unsigned int > m_inputRasterBands
Bands to be processed from the input raster.
Definition: Classifier.h:114
unsigned int m_maxInputPoints
The maximum number of points used to estimate the clusters (default = 1000).
A region of interest (often abbreviated ROI), is a selected subset of samples within a dataset identi...
Definition: ROI.h:60
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr)
double m_epsilon
The stop criteria. When the clusters change in a value smaller then epsilon, the convergence is achie...
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
unsigned int m_maxIterations
The maximum of iterations (E/M steps) to perform if convergence is not achieved.
static PolygonIterator begin(const te::rst::Raster *r, const te::gm::Polygon *p)
Returns an iterator referring to the first value of the band.
std::vector< SampleT > SamplesT
Class samples container type definition.
const std::vector< Geometry * > & getGeometries() const
It returns a reference to the internal list of geometries.
std::string getLabel()
Get the ROI label.
Definition: ROI.cpp:47
unsigned int m_maxIterations
The maximum of iterations to perform if convergence is not achieved.
double m_acceptanceThreshold
The acceptance threshold (the closer to 100%, few clusters are created).
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:432
unsigned int getColumn() const
Returns the current column in iterator.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:508
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
std::vector< ClassSampleT > ClassSamplesContainerT
Class samples container type definition.
void setList(std::list< te::map::AbstractLayerPtr > &layerList)
std::vector< double > m_maxAngularDistances
This is a vector of maximum acceptable angles (radians) between one pixel spectra and the reference s...
std::vector< std::vector< double > > m_clustersMeans
The previously estimated means of the clusters (optional).
std::map< std::string, te::cl::ROI * > & getROISet()
Get the roi set map.
Definition: ROISet.cpp:79
te::rp::Classifier::OutputParameters getOutputParams()
Classifier input parameters.
Definition: Classifier.h:74
double m_epsilon
The stop criteria. When the clusters change in a value smaller then epsilon, the convergence is achie...
std::map< std::string, te::gm::Polygon * > & getPolygons()
Get all polygons belongs to this roi.
Definition: ROI.cpp:62
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
std::string getColor()
Get the ROI color defined by a hexadecimal color name.
Definition: ROI.cpp:57