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 "../../../maptools/Utils.h"
33 #include "../../../rp/Segmenter.h"
34 #include "../../../rp/SegmenterRegionGrowingBaatzStrategy.h"
35 #include "../../../rp/SegmenterRegionGrowingMeanStrategy.h"
36 #include "../progress/ProgressViewerDialog.h"
37 #include "RasterNavigatorWidget.h"
38 #include "SegmenterWizardPage.h"
39 #include "ui_SegmenterWizardPageForm.h"
40 
41 // Qt
42 #include <QGridLayout>
43 #include <QCheckBox>
44 #include <QIntValidator>
45 #include <QMessageBox>
46 
47 // STL
48 #include <memory>
49 
50 
52  : QWizardPage(parent),
53  m_ui(new Ui::SegmenterWizardPageForm),
54  m_layer(nullptr)
55 {
56 // setup controls
57  m_ui->setupUi(this);
58 
60 
61 //build form
62  QGridLayout* displayLayout = new QGridLayout(m_ui->m_frame);
64  m_navigator->showAsPreview(true, false);
65  m_navigator->hideColorCompositionTool(true);
66  displayLayout->addWidget(m_navigator.get());
67  displayLayout->setContentsMargins(0,0,0,0);
68 
69 //configure page
70  this->setTitle(tr("Segmenter"));
71  this->setSubTitle(tr("Select the type of segmenter and set their specific parameters."));
72 
73  QIntValidator* intValRG = new QIntValidator(this);
74  intValRG->setBottom(0);
75  m_ui->m_minimumSegmentSizeRGLineEdit->setValidator(intValRG);
76 
77  QIntValidator* intValB = new QIntValidator(this);
78  intValB->setBottom(0);
79  m_ui->m_minimumSegmentSizeRGLineEdit_2->setValidator(intValB);
80 
81  m_ui->m_noDataValueLineEdit->setValidator(new QDoubleValidator(this));
82 
84  m_ui->m_minimumSegmentSizeRGLineEdit->setText( QString::number( regGrowStrategyParameters.m_minSegmentSize ) );
85  m_ui->m_minimumSegmentSizeRGLineEdit_2->setText( QString::number( regGrowStrategyParameters.m_minSegmentSize ) );
86  m_ui->m_thresholdRGDoubleSpinBox->setValue( regGrowStrategyParameters.m_segmentsSimilarityThreshold );
87  m_ui->m_thresholdBaatzDoubleSpinBox->setValue( regGrowStrategyParameters.m_segmentsSimilarityThreshold );
88  m_ui->m_colorWeightBaatzDoubleSpinBox->setValue( regGrowStrategyParameters.m_colorWeight );
89  m_ui->m_compactnessWeightBaatzDoubleSpinBox->setValue( regGrowStrategyParameters.m_compactnessWeight );
90 
91 //connects
92  connect(m_ui->m_strategyTypeComboBox, SIGNAL(activated(int)), this, SLOT(onStrategyTypeComboBoxActivated(int)));
93  connect(m_navigator.get(), SIGNAL(previewClicked()), this, SLOT(apply()));
94 }
95 
97 {
98  m_inputRst.release();
99 }
100 
102 {
103  int nBands = m_ui->m_bandTableWidget->rowCount();
104 
105  for(int i = 0; i < nBands; ++i)
106  {
107  QCheckBox* checkBox = (QCheckBox*)m_ui->m_bandTableWidget->cellWidget(i, 0);
108 
109  if(checkBox->isChecked())
110  {
111  return true;
112  }
113  }
114 
115  return false;
116 }
117 
119 {
120  m_layer = layer;
121 
122  std::list<te::map::AbstractLayerPtr> list;
123 
124  list.push_back(m_layer);
125 
126  m_navigator->set(m_layer, true);
127 
128  listBands();
129 }
130 
132 {
133  return m_layer;
134 }
135 
137 {
138  te::rp::Segmenter::InputParameters algoInputParams;
139 
140  //get input raster
141 
142  m_inputRst.reset(te::map::GetRaster(m_layer.get()));
143 
144  //set segmenter parameters
145  algoInputParams.m_inputRasterPtr = m_inputRst.release();
146 
147  int nBands = m_ui->m_bandTableWidget->rowCount();
148 
149  for(int i = 0; i < nBands; ++i)
150  {
151  QCheckBox* checkBox = (QCheckBox*)m_ui->m_bandTableWidget->cellWidget(i, 0);
152 
153  if(checkBox->isChecked())
154  {
155  algoInputParams.m_inputRasterBands.push_back(i);
156 
157  if(m_ui->m_noDataValueCheckBox->isChecked() && !m_ui->m_noDataValueLineEdit->text().isEmpty())
158  {
159  algoInputParams.m_inputRasterNoDataValues.push_back(m_ui->m_noDataValueLineEdit->text().toDouble());
160  }
161  }
162  }
163 
164  int index = m_ui->m_strategyTypeComboBox->currentIndex();
165 
166  std::string strategyName = m_ui->m_strategyTypeComboBox->itemData(index).toString().toUtf8().data();
167 
168  if(strategyName == "RegionGrowingMean")
169  {
171  strategyParameters.m_minSegmentSize = m_ui->m_minimumSegmentSizeRGLineEdit->text().toUInt();
172  strategyParameters.m_segmentsSimilarityThreshold = m_ui->m_thresholdRGDoubleSpinBox->value();
173  strategyParameters.m_enableLocalMutualBestFitting = m_ui->m_localMutualBestFittingCheckBox->isChecked();
174  strategyParameters.m_enableSameIterationMerges = m_ui->m_sameIterationMergeCheckBox->isChecked();
175 
176  algoInputParams.m_strategyName = "RegionGrowingMean";
177  algoInputParams.setSegStrategyParams( strategyParameters );
178  }
179  else if(strategyName == "RegionGrowingBaatz")
180  {
182  strategyParameters.m_minSegmentSize = m_ui->m_minimumSegmentSizeRGLineEdit_2->text().toUInt();
183  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  double weightsSum = 0.0;
188  for(int i = 0; i < nBands; ++i)
189  {
190  QCheckBox* checkBox = (QCheckBox*)m_ui->m_bandTableWidget->cellWidget(i, 0);
191 
192  if(checkBox->isChecked())
193  {
194  QDoubleSpinBox* spinBox = (QDoubleSpinBox*)m_ui->m_bandTableWidget->cellWidget(i, 1);
195 
196  strategyParameters.m_bandsWeights.push_back(spinBox->value());
197 
198  weightsSum += strategyParameters.m_bandsWeights[ i ];
199  }
200  }
201 
202  // fixing bands weights decimals ( their sum must be 1 )
203  if( nBands > 0 )
204  {
205  strategyParameters.m_bandsWeights[ nBands - 1 ] += ( 1.0 - weightsSum );
206  }
207 
208  strategyParameters.m_colorWeight = m_ui->m_colorWeightBaatzDoubleSpinBox->value();
209  strategyParameters.m_compactnessWeight = m_ui->m_compactnessWeightBaatzDoubleSpinBox->value();
210 
211  algoInputParams.m_strategyName = "RegionGrowingBaatz";
212  algoInputParams.setSegStrategyParams( strategyParameters );
213  }
214 
215  return algoInputParams;
216 }
217 
219 {
220  std::string strategyName = m_ui->m_strategyTypeComboBox->itemData(index).toString().toUtf8().data();
221 
222  if(strategyName == "RegionGrowingMean")
223  {
224  QStringList list;
225  list.append(tr("Band"));
226 
227  m_ui->m_bandTableWidget->setColumnCount(1);
228  m_ui->m_bandTableWidget->setHorizontalHeaderLabels(list);
229  }
230  else if(strategyName == "RegionGrowingBaatz")
231  {
232  QStringList list;
233  list.append(tr("Band"));
234  list.append(tr("Weight"));
235 
236  m_ui->m_bandTableWidget->setColumnCount(2);
237  m_ui->m_bandTableWidget->setHorizontalHeaderLabels(list);
238 
239  int nBands = m_ui->m_bandTableWidget->rowCount();
240 
241  for(int i = 0; i < nBands; ++i)
242  {
243  QDoubleSpinBox* spinBox = new QDoubleSpinBox(m_ui->m_bandTableWidget);
244  spinBox->setMinimum(0.0);
245  spinBox->setMaximum(1.0);
246  spinBox->setSingleStep(0.1);
247  spinBox->setDecimals(4);
248  spinBox->setValue( 1.0 / ((double)nBands) );
249 
250  m_ui->m_bandTableWidget->setCellWidget(i, 1, spinBox);
251  }
252  }
253 
254  m_ui->m_bandTableWidget->resizeColumnsToContents();
255 
256 #if (QT_VERSION >= 0x050000)
257  m_ui->m_bandTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
258 #else
259  m_ui->m_bandTableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
260 #endif
261 }
262 
264 {
265  QApplication::setOverrideCursor(Qt::WaitCursor);
266 
267 //get preview raster
268  te::rst::Raster* inputRst = m_navigator->getExtentRaster(true);
269 
270  //set segmenters parameters
272 
273  algoInputParams.m_inputRasterPtr = inputRst;
274  algoInputParams.m_enableThreadedProcessing = false;
275  algoInputParams.m_enableBlockProcessing = false;
276 
277  te::rp::Segmenter::OutputParameters algoOutputParams;
278 
279  std::map<std::string, std::string> rinfo;
280  rinfo["MEM_RASTER_NROWS"] = boost::lexical_cast<std::string>(inputRst->getNumberOfRows());
281  rinfo["MEM_RASTER_NCOLS"] = boost::lexical_cast<std::string>(inputRst->getNumberOfColumns());
282  rinfo["MEM_RASTER_DATATYPE"] = boost::lexical_cast<std::string>(inputRst->getBandDataType(0));
283  rinfo["MEM_RASTER_NBANDS"] = boost::lexical_cast<std::string>(inputRst->getNumberOfBands());
284 
285  algoOutputParams.m_rType = "MEM";
286  algoOutputParams.m_rInfo = rinfo;
287 
288  //run contrast
289  te::rp::Segmenter algorithmInstance;
290 
291  //progress
293 
294  try
295  {
296  if(algorithmInstance.initialize(algoInputParams))
297  {
298  if(algorithmInstance.execute(algoOutputParams))
299  {
300  std::unique_ptr<te::rst::Raster> rst = std::move(algoOutputParams.m_outputRasterPtr);
301 
302  m_navigator->drawRaster(rst.get());
303  }
304  }
305  }
306  catch(...)
307  {
308  QMessageBox::warning(this, tr("Warning"), tr("Segmenter error."));
309  }
310 
311  QApplication::restoreOverrideCursor();
312 
313  //delete input raster dataset
314  delete inputRst;
315 }
316 
318 {
319  m_ui->m_strategyTypeComboBox->clear();
320 
321  m_ui->m_strategyTypeComboBox->addItem(tr("Region Growing"), "RegionGrowingMean");
322  m_ui->m_strategyTypeComboBox->addItem(tr("Region Growing Baatz"), "RegionGrowingBaatz");
323 }
324 
326 {
327  assert(m_layer.get());
328 
329  //get input raster
330  std::unique_ptr<te::da::DataSet> ds = m_layer->getData();
331 
332  if(ds.get())
333  {
334  std::size_t rpos = te::da::GetFirstPropertyPos(ds.get(), te::dt::RASTER_TYPE);
335 
336  std::unique_ptr<te::rst::Raster> inputRst = ds->getRaster(rpos);
337 
338  if(inputRst.get())
339  {
340  for(unsigned int i = 0; i < inputRst->getNumberOfBands(); ++i)
341  {
342  m_ui->m_bandTableWidget->setRowCount(0);
343 
344  // initializing the list of bands
345  for(unsigned b = 0 ; b < inputRst->getNumberOfBands(); b++)
346  {
347  int newrow = m_ui->m_bandTableWidget->rowCount();
348  m_ui->m_bandTableWidget->insertRow(newrow);
349 
350  QString bName(tr("Band "));
351  bName.append(QString::number(b));
352 
353  QCheckBox* bandCheckBox = new QCheckBox(bName, this);
354  bandCheckBox->setChecked( true );
355 
356  m_ui->m_bandTableWidget->setCellWidget(newrow, 0, bandCheckBox);
357  }
358  }
359  }
360  }
361 }
std::string m_strategyName
The segmenter strategy name see each te::rp::SegmenterStrategyFactory inherited classes documentation...
Raster segmentation.
double m_segmentsSimilarityThreshold
Segments similarity treshold - Use lower values to merge only those segments that are more similar - ...
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
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...
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
double m_compactnessWeight
The weight given to the compactness component, deafult:0.5, valid range: [0,1].
double m_colorWeight
The weight given to the color component, deafult:0.9, valid range: [0,1].
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
bool m_enableSameIterationMerges
If enabled, a merged segment could be merged with another within the same iteration (default:false)...
std::unique_ptr< te::rst::Raster > m_inputRst
unsigned int m_minSegmentSize
A positive minimum segment size (pixels number - default: 100).
static te::dt::Date ds(2010, 01, 01)
bool m_enableLocalMutualBestFitting
If enabled, a merge only occurs between two segments if the minimum dissimilarity criteria is best fu...
bool m_enableSameIterationMerges
If enabled, a merged segment could be merged with another within the same iteration (default:false)...
int b
Definition: TsRtree.cpp:32
void setSegStrategyParams(const SegmenterStrategyParameters &segStratParams)
Set specific segmenter strategy parameters.
std::vector< std::complex< double > > m_inputRasterNoDataValues
A vector of values to be used as input raster no-data values or an empty vector indicating to use the...
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.
te::rst::Raster const * m_inputRasterPtr
Input raster.
virtual int getBandDataType(std::size_t i) const =0
Returns the data type in a particular band (or dimension).
std::unique_ptr< te::qt::widgets::RasterNavigatorWidget > m_navigator
double m_segmentsSimilarityThreshold
Segments similarity treshold - Use lower values to merge only those segments that are more similar - ...
unsigned int m_minSegmentSize
A positive minimum segment size (pixels number - default: 100).
TEMAPEXPORT te::rst::Raster * GetRaster(AbstractLayer *layer)
It gets the raster referenced by the given data set layer.
std::map< std::string, std::string > m_rInfo
The necessary information to create the raster (as described in te::raster::RasterFactory).
te::rp::Segmenter::InputParameters getInputParams()
This class is used to navigate over a DataSetLayer (having a raster representation) and given a set o...
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...
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
std::unique_ptr< te::rst::Raster > m_outputRasterPtr
A pointer the ge generated output raster (label image).
bool m_enableLocalMutualBestFitting
If enabled, a merge only occurs between two segments if the minimum dissimilarity criteria is best fu...
This file defines a class for a Segmenter Wizard page.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
std::vector< unsigned int > m_inputRasterBands
Bands to be processed from the input raster.
std::unique_ptr< Ui::SegmenterWizardPageForm > m_ui
bool m_enableBlockProcessing
If true, the original raster will be splitted into small blocks, each one will be segmented independe...