All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SegmenterWizardPage.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/qt/widgets/rp/SegmenterWizardPage.cpp
22 
23  \brief This file defines a class for a Segmenter Wizard page.
24 */
25 
26 // TerraLib
27 #include "../../../common/progress/ProgressManager.h"
28 #include "../../../common/StringUtils.h"
29 #include "../../../dataaccess/dataset/DataSet.h"
30 #include "../../../dataaccess/utils/Utils.h"
31 #include "../../../raster/Raster.h"
32 #include "../../../rp/Segmenter.h"
33 #include "../../../rp/SegmenterRegionGrowingStrategy.h"
34 #include "../progress/ProgressViewerDialog.h"
35 #include "RasterNavigatorWidget.h"
36 #include "SegmenterWizardPage.h"
37 #include "ui_SegmenterWizardPageForm.h"
38 
39 // Qt
40 #include <QGridLayout>
41 #include <QCheckBox>
42 #include <QIntValidator>
43 #include <QMessageBox>
44 
45 // STL
46 #include <memory>
47 
48 
50  : QWizardPage(parent),
51  m_ui(new Ui::SegmenterWizardPageForm),
52  m_layer(0)
53 {
54 // setup controls
55  m_ui->setupUi(this);
56 
58 
59 //build form
60  QGridLayout* displayLayout = new QGridLayout(m_ui->m_frame);
62  m_navigator->showAsPreview(true, false);
63  m_navigator->hideColorCompositionTool(true);
64  displayLayout->addWidget(m_navigator.get());
65  displayLayout->setContentsMargins(0,0,0,0);
66 
67 //configure page
68  this->setTitle(tr("Segmenter"));
69  this->setSubTitle(tr("Select the type of segmenter and set their specific parameters."));
70 
71  QIntValidator* intValRG = new QIntValidator(this);
72  intValRG->setBottom(0);
73  m_ui->m_minimumSegmentSizeRGLineEdit->setValidator(intValRG);
74 
75  QIntValidator* intValB = new QIntValidator(this);
76  intValB->setBottom(0);
77  m_ui->m_minimumSegmentSizeRGLineEdit_2->setValidator(intValB);
78 
79  m_ui->m_noDataValueLineEdit->setValidator(new QDoubleValidator(this));
80 
82  m_ui->m_minimumSegmentSizeRGLineEdit->setText( QString::number( regGrowStrategyParameters.m_minSegmentSize ) );
83  m_ui->m_minimumSegmentSizeRGLineEdit_2->setText( QString::number( regGrowStrategyParameters.m_minSegmentSize ) );
84  m_ui->m_thresholdRGDoubleSpinBox->setValue( regGrowStrategyParameters.m_segmentsSimilarityThreshold );
85  m_ui->m_thresholdBaatzDoubleSpinBox->setValue( regGrowStrategyParameters.m_segmentsSimilarityThreshold );
86  m_ui->m_colorWeightBaatzDoubleSpinBox->setValue( regGrowStrategyParameters.m_colorWeight );
87  m_ui->m_compactnessWeightBaatzDoubleSpinBox->setValue( regGrowStrategyParameters.m_compactnessWeight );
88 
89 //connects
90  connect(m_ui->m_strategyTypeComboBox, SIGNAL(activated(int)), this, SLOT(onStrategyTypeComboBoxActivated(int)));
91  connect(m_navigator.get(), SIGNAL(previewClicked()), this, SLOT(apply()));
92 }
93 
95 {
96 }
97 
99 {
100  int nBands = m_ui->m_bandTableWidget->rowCount();
101 
102  for(int i = 0; i < nBands; ++i)
103  {
104  QCheckBox* checkBox = (QCheckBox*)m_ui->m_bandTableWidget->cellWidget(i, 0);
105 
106  if(checkBox->isChecked())
107  {
108  return true;
109  }
110  }
111 
112  return false;
113 }
114 
116 {
117  m_layer = layer;
118 
119  std::list<te::map::AbstractLayerPtr> list;
120 
121  list.push_back(m_layer);
122 
123  m_navigator->set(m_layer, true);
124 
125  listBands();
126 }
127 
129 {
130  return m_layer;
131 }
132 
134 {
135  te::rp::Segmenter::InputParameters algoInputParams;
136 
137  //get input raster
138  std::auto_ptr<te::da::DataSet> ds = m_layer->getData();
139  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
140  m_inputRst.reset(ds->getRaster(rpos).release());
141 
142  //set segmenter parameters
143  algoInputParams.m_inputRasterPtr = m_inputRst.get();
144 
145  int nBands = m_ui->m_bandTableWidget->rowCount();
146 
147  for(int i = 0; i < nBands; ++i)
148  {
149  QCheckBox* checkBox = (QCheckBox*)m_ui->m_bandTableWidget->cellWidget(i, 0);
150 
151  if(checkBox->isChecked())
152  {
153  algoInputParams.m_inputRasterBands.push_back(i);
154 
155  if(m_ui->m_noDataValueCheckBox->isChecked() && !m_ui->m_noDataValueLineEdit->text().isEmpty())
156  {
157  algoInputParams.m_inputRasterNoDataValues.push_back(m_ui->m_noDataValueLineEdit->text().toDouble());
158  }
159  }
160  }
161 
162  int index = m_ui->m_strategyTypeComboBox->currentIndex();
163 
164  std::string strategyName = m_ui->m_strategyTypeComboBox->itemData(index).toString().toStdString();
165 
166  if(strategyName == "RegionGrowing")
167  {
169  strategyParameters.m_minSegmentSize = m_ui->m_minimumSegmentSizeRGLineEdit->text().toUInt();
170  strategyParameters.m_segmentsSimilarityThreshold = m_ui->m_thresholdRGDoubleSpinBox->value();
172  strategyParameters.m_enableLocalMutualBestFitting = m_ui->m_localMutualBestFittingCheckBox->isChecked();
173  strategyParameters.m_enableSameIterationMerges = m_ui->m_sameIterationMergeCheckBox->isChecked();
174 
175  algoInputParams.m_strategyName = "RegionGrowing";
176  algoInputParams.setSegStrategyParams( strategyParameters );
177  }
178  else if(strategyName == "Baatz")
179  {
181  strategyParameters.m_minSegmentSize = m_ui->m_minimumSegmentSizeRGLineEdit->text().toUInt();
182  strategyParameters.m_segmentsSimilarityThreshold = m_ui->m_thresholdBaatzDoubleSpinBox->value();
184  strategyParameters.m_enableLocalMutualBestFitting = m_ui->m_localMutualBestFittingCheckBox->isChecked();
185  strategyParameters.m_enableSameIterationMerges = m_ui->m_sameIterationMergeCheckBox->isChecked();
186 
187  for(int i = 0; i < nBands; ++i)
188  {
189  QCheckBox* checkBox = (QCheckBox*)m_ui->m_bandTableWidget->cellWidget(i, 0);
190 
191  if(checkBox->isChecked())
192  {
193  QDoubleSpinBox* spinBox = (QDoubleSpinBox*)m_ui->m_bandTableWidget->cellWidget(i, 1);
194 
195  strategyParameters.m_bandsWeights.push_back(spinBox->value());
196  }
197  }
198 
199  strategyParameters.m_colorWeight = m_ui->m_colorWeightBaatzDoubleSpinBox->value();
200  strategyParameters.m_compactnessWeight = m_ui->m_compactnessWeightBaatzDoubleSpinBox->value();
201 
202  algoInputParams.m_strategyName = "RegionGrowing";
203  algoInputParams.setSegStrategyParams( strategyParameters );
204  }
205 
206  return algoInputParams;
207 }
208 
210 {
211  std::string strategyName = m_ui->m_strategyTypeComboBox->itemData(index).toString().toStdString();
212 
213  if(strategyName == "RegionGrowing")
214  {
215  QStringList list;
216  list.append(tr("Band"));
217 
218  m_ui->m_bandTableWidget->setColumnCount(1);
219  m_ui->m_bandTableWidget->setHorizontalHeaderLabels(list);
220  }
221  else if(strategyName == "Baatz")
222  {
223  QStringList list;
224  list.append(tr("Band"));
225  list.append(tr("Weight"));
226 
227  m_ui->m_bandTableWidget->setColumnCount(2);
228  m_ui->m_bandTableWidget->setHorizontalHeaderLabels(list);
229 
230  int nBands = m_ui->m_bandTableWidget->rowCount();
231 
232  for(int i = 0; i < nBands; ++i)
233  {
234  QDoubleSpinBox* spinBox = new QDoubleSpinBox(m_ui->m_bandTableWidget);
235  spinBox->setMinimum(0.0);
236  spinBox->setMaximum(1.0);
237  spinBox->setSingleStep(0.1);
238  spinBox->setDecimals(4);
239  spinBox->setValue(0.3333);
240 
241  m_ui->m_bandTableWidget->setCellWidget(i, 1, spinBox);
242  }
243  }
244 
245  m_ui->m_bandTableWidget->resizeColumnsToContents();
246 
247 #if (QT_VERSION >= 0x050000)
248  m_ui->m_bandTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
249 #else
250  m_ui->m_bandTableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
251 #endif
252 }
253 
255 {
256  QApplication::setOverrideCursor(Qt::WaitCursor);
257 
258 //get preview raster
259  te::rst::Raster* inputRst = m_navigator->getExtentRaster(true);
260 
261  //set segmenters parameters
262  te::rp::Segmenter::InputParameters algoInputParams = getInputParams();
263 
264  algoInputParams.m_inputRasterPtr = inputRst;
265  algoInputParams.m_enableThreadedProcessing = false;
266  algoInputParams.m_enableBlockProcessing = false;
267 
268  te::rp::Segmenter::OutputParameters algoOutputParams;
269 
270  std::map<std::string, std::string> rinfo;
271  rinfo["MEM_RASTER_NROWS"] = boost::lexical_cast<std::string>(inputRst->getNumberOfRows());
272  rinfo["MEM_RASTER_NCOLS"] = boost::lexical_cast<std::string>(inputRst->getNumberOfColumns());
273  rinfo["MEM_RASTER_DATATYPE"] = boost::lexical_cast<std::string>(inputRst->getBandDataType(0));
274  rinfo["MEM_RASTER_NBANDS"] = boost::lexical_cast<std::string>(inputRst->getNumberOfBands());
275 
276  algoOutputParams.m_rType = "MEM";
277  algoOutputParams.m_rInfo = rinfo;
278 
279  //run contrast
280  te::rp::Segmenter algorithmInstance;
281 
282  //progress
285 
286  try
287  {
288  if(algorithmInstance.initialize(algoInputParams))
289  {
290  if(algorithmInstance.execute(algoOutputParams))
291  {
292  std::auto_ptr<te::rst::Raster> rst = algoOutputParams.m_outputRasterPtr;
293 
294  m_navigator->drawRaster(rst.get());
295  }
296  }
297  }
298  catch(...)
299  {
300  QMessageBox::warning(this, tr("Warning"), tr("Constrast error."));
301  }
302 
304 
305  QApplication::restoreOverrideCursor();
306 
307  //delete input raster dataset
308  delete inputRst;
309 }
310 
312 {
313  m_ui->m_strategyTypeComboBox->clear();
314 
315  m_ui->m_strategyTypeComboBox->addItem(tr("Region Growing"), "RegionGrowing");
316  m_ui->m_strategyTypeComboBox->addItem(tr("Baatz"), "Baatz");
317 }
318 
320 {
321  assert(m_layer.get());
322 
323  //get input raster
324  std::auto_ptr<te::da::DataSet> ds = m_layer->getData();
325 
326  if(ds.get())
327  {
328  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
329 
330  std::auto_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
331 
332  if(inputRst.get())
333  {
334  for(unsigned int i = 0; i < inputRst->getNumberOfBands(); ++i)
335  {
336  m_ui->m_bandTableWidget->setRowCount(0);
337 
338  // initializing the list of bands
339  for(unsigned b = 0 ; b < inputRst->getNumberOfBands(); b++)
340  {
341  int newrow = m_ui->m_bandTableWidget->rowCount();
342  m_ui->m_bandTableWidget->insertRow(newrow);
343 
344  QString bName(tr("Band "));
345  bName.append(QString::number(b));
346 
347  QCheckBox* bandCheckBox = new QCheckBox(bName, this);
348  bandCheckBox->setChecked( true );
349 
350  m_ui->m_bandTableWidget->setCellWidget(newrow, 0, bandCheckBox);
351  }
352  }
353  }
354  }
355 }
std::string m_strategyName
The segmenter strategy name see each te::rp::SegmenterStrategyFactory inherited classes documentation...
Definition: Segmenter.h:101
The Baatz based features will be used - Reference: Baatz, M.; Schape, A. Multiresolution segmentation...
Segmenter Output Parameters.
Definition: Segmenter.h:149
std::auto_ptr< te::qt::widgets::RasterNavigatorWidget > m_navigator
Raster segmentation.
Definition: Segmenter.h:73
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Definition: Raster.cpp:213
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
Definition: Segmenter.cpp:802
bool m_enableSameIterationMerges
If enabled, a merged segment could be merged with another within the same iteration (default:false)...
std::auto_ptr< te::rst::Raster > m_outputRasterPtr
A pointer the ge generated output raster (label image).
Definition: Segmenter.h:157
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
Definition: Segmenter.h:153
std::vector< double > m_bandsWeights
The weight given to each band, when applicable (note: the bands weights sum must always be 1) or an e...
void setSegStrategyParams(const SegmenterStrategyParameters &segStratParams)
Set specific segmenter strategy parameters.
Definition: Segmenter.cpp:127
void removeViewer(int viewerId)
Dettach a progress viewer.
static ProgressManager & getInstance()
It returns a reference to the singleton instance.
The mean of segments pixel values will be used - Reference: S. A. Bins, L. M. G. Fonseca, G. J. Erthal e F. M. Ii, "Satellite Imagery segmentation: a region growing approach", VIII Simposio Brasileiro de Sensoriamento Remoto, Salvador, BA, 14-19 abril 1996.
An abstract class for raster data strucutures.
Definition: Raster.h:71
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
te::rst::Raster const * m_inputRasterPtr
Input raster.
Definition: Segmenter.h:85
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
SegmentFeaturesType m_segmentFeatures
What segment features will be used on the segmentation process (default:InvalidFeaturesType).
Segmenter Input Parameters.
Definition: Segmenter.h:81
std::auto_ptr< Ui::SegmenterWizardPageForm > m_ui
unsigned int m_minSegmentSize
A positive minimum segment size (pixels number - default: 100).
double m_segmentsSimilarityThreshold
Segments similarity treshold - Use lower values to merge only those segments that are more similar - ...
int addViewer(AbstractProgressViewer *apv)
Attach a progress viewer.
std::map< std::string, std::string > m_rInfo
The necessary information to create the raster (as described in te::raster::RasterFactory).
Definition: Segmenter.h:155
te::rp::Segmenter::InputParameters getInputParams()
This class is used to navigate over a DataSetLayer (having a raster representation) and given a set o...
double m_colorWeight
The weight given to the color component, deafult:0.9, valid range: [0,1].
void set(te::map::AbstractLayerPtr layer)
This method is used to set the selected layer for segmenter operation.
This file has the RasterNavigatorWidget class.
bool m_enableThreadedProcessing
If true, threaded processing will be performed (best with multi-core or multi-processor systems (defa...
Definition: Segmenter.h:91
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:481
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
Definition: Segmenter.cpp:217
double m_compactnessWeight
The weight given to the compactness component, deafult:0.5, valid range: [0,1].
std::vector< double > m_inputRasterNoDataValues
A vector of values to be used as input raster no-data values or an empty vector indicating to use the...
Definition: Segmenter.h:89
This file defines a class for a Segmenter Wizard page.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
bool m_enableLocalMutualBestFitting
If enabled, a merge only occurs between two segments if the minimum dissimilarity criteria is best fu...
virtual int getBandDataType(std::size_t i) const =0
Returns the data type in a particular band (or dimension).
std::vector< unsigned int > m_inputRasterBands
Bands to be processed from the input raster.
Definition: Segmenter.h:87
bool m_enableBlockProcessing
If true, the original raster will be splitted into small blocks, each one will be segmented independe...
Definition: Segmenter.h:95