All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SegmenterRegionGrowingStrategy.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/SegmenterRegionGrowingStrategy.cpp
22  \briefRaster region growing segmenter strategy.
23 */
24 
26 
27 #include "Macros.h"
28 
29 #include "../raster/Band.h"
30 #include "../raster/BandProperty.h"
31 #include "../raster/RasterFactory.h"
32 #include "../raster/Grid.h"
33 #include "../datatype/Enums.h"
34 #include "../common/progress/TaskProgress.h"
35 
36 #include <algorithm>
37 #include <cfloat>
38 #include <cmath>
39 #include <cstring>
40 #include <limits>
41 
42 #include <boost/lexical_cast.hpp>
43 
44 // Baatz Edge Lengh
45 #define BAATZ_EL( featPtr ) featPtr[ 0 ]
46 
47 // Baatz Compactness
48 #define BAATZ_CO( featPtr ) featPtr[ 1 ]
49 
50 // Baatz Smoothness
51 #define BAATZ_SM( featPtr ) featPtr[ 2 ]
52 
53 // Baatz sums
54 #define BAATZ_SU( featPtr, band ) featPtr[ 3 + band ]
55 
56 // Baatz square sums
57 #define BAATZ_SS( featPtr, bandsNmb, band ) featPtr[ 3 + bandsNmb + band ]
58 
59 // Baatz stddev
60 #define BAATZ_ST( featPtr, bandsNmb, band ) featPtr[ 3 + ( 2 * bandsNmb ) + band ]
61 
62 // Baatz stddev start ponter
63 #define BAATZ_STSTARTPTR( featPtr, bandsNmb ) ( featPtr + 3 + ( 2 * bandsNmb ) )
64 
65 namespace
66 {
68  segmenterRegionGrowingStrategyFactoryInstance;
69 }
70 
71 namespace te
72 {
73  namespace rp
74  {
75  //-------------------------------------------------------------------------
76 
78  {
79  reset();
80  }
81 
83  {
84  }
85 
89  {
90  reset();
91 
92  m_minSegmentSize = params.m_minSegmentSize;
93  m_segmentsSimilarityThreshold = params.m_segmentsSimilarityThreshold;
94  m_segmentFeatures = params.m_segmentFeatures;
95  m_bandsWeights = params.m_bandsWeights;
96  m_colorWeight = params.m_colorWeight;
97  m_compactnessWeight = params.m_compactnessWeight;
98  m_segmentsSimIncreaseSteps = params.m_segmentsSimIncreaseSteps;
99  m_enableLocalMutualBestFitting = params.m_enableLocalMutualBestFitting;
100  m_enableSameIterationMerges = params.m_enableSameIterationMerges;
101 
102  return *this;
103  }
104 
106  throw( te::rp::Exception )
107  {
108  m_minSegmentSize = 100;
109  m_segmentsSimilarityThreshold = 0.03;
110  m_segmentFeatures = InvalidFeaturesType;
111  m_bandsWeights.clear();
112  m_colorWeight = 0.9;
113  m_compactnessWeight = 0.5;
114  m_segmentsSimIncreaseSteps = 2;
115  m_enableLocalMutualBestFitting = false;
116  m_enableSameIterationMerges = false;
117  }
118 
120  {
122  }
123 
124  //-------------------------------------------------------------------------
125 
127  {
128  }
129 
131  {
132  }
133 
134  //-------------------------------------------------------------------------
135 
136  SegmenterRegionGrowingStrategy::MeanMerger::MeanMerger( const unsigned int featuresNumber )
137  {
138  m_featuresNumber = featuresNumber;
139  m_dissimilarityNormFactor = (SegmenterRegionGrowingSegment::FeatureType)(
140  2.0 * std::sqrt( (double)featuresNumber ) );
141  }
142 
144  {
145  }
146 
148  SegmenterRegionGrowingSegment const * const segment1Ptr,
149  SegmenterRegionGrowingSegment const * const segment2Ptr,
150  SegmenterRegionGrowingSegment * const ) const
151  {
152  assert( segment1Ptr );
153  assert( segment1Ptr->m_features );
154  assert( segment2Ptr );
155  assert( segment2Ptr->m_features );
156 
157  m_getDissimilarity_dissValue = 0.0;
158 
159  for( m_getDissimilarity_meansIdx = 0 ; m_getDissimilarity_meansIdx < m_featuresNumber ;
160  ++m_getDissimilarity_meansIdx )
161  {
162  m_getDissimilarity_diffValue = segment1Ptr->m_features[ m_getDissimilarity_meansIdx ] -
163  segment2Ptr->m_features[ m_getDissimilarity_meansIdx ];
164 
165  m_getDissimilarity_dissValue += ( m_getDissimilarity_diffValue * m_getDissimilarity_diffValue );
166  }
167 
168  m_getDissimilarity_dissValue = std::sqrt( m_getDissimilarity_dissValue );
169  m_getDissimilarity_dissValue /= m_dissimilarityNormFactor;
170 
171  return m_getDissimilarity_dissValue;
172  }
173 
175  SegmenterRegionGrowingSegment * const segment1Ptr,
176  SegmenterRegionGrowingSegment const * const segment2Ptr,
177  SegmenterRegionGrowingSegment const * const ) const
178  {
179  assert( segment1Ptr );
180  assert( segment1Ptr->m_features );
181  assert( segment2Ptr );
182  assert( segment2Ptr->m_features );
183 
184  // Merging basic features
185 
186  segment1Ptr->m_size += segment2Ptr->m_size;
187 
188  segment1Ptr->m_xStart = std::min(
189  segment1Ptr->m_xStart,
190  segment2Ptr->m_xStart );
191  segment1Ptr->m_xBound = std::max(
192  segment1Ptr->m_xBound,
193  segment2Ptr->m_xBound );
194 
195  segment1Ptr->m_yStart = std::min(
196  segment1Ptr->m_yStart,
197  segment2Ptr->m_yStart );
198  segment1Ptr->m_yBound = std::max(
199  segment1Ptr->m_yBound,
200  segment2Ptr->m_yBound );
201 
202  // Merging specific features
203 
204  for( unsigned int meansIdx = 0 ; meansIdx < m_featuresNumber ; ++meansIdx )
205  {
206  segment1Ptr->m_features[ meansIdx ] =
207  (
208  (
209  segment1Ptr->m_features[ meansIdx ]
210  *
212  )
213  +
214  (
215  segment2Ptr->m_features[ meansIdx ]
216  *
218  )
219  )
220  /
221  (
223  (
224  segment1Ptr->m_size
225  +
226  segment2Ptr->m_size
227  )
228  );
229  }
230  }
231 
232  //-------------------------------------------------------------------------
233 
235  const double& colorWeight, const double& compactnessWeight,
236  const std::vector< double >& bandsWeights,
237  const SegmentsIdsMatrixT& segmentsIds )
238  :
239  m_segmentsIds( segmentsIds ),
240  m_allSegsCompactnessOffset( 0 ),
241  m_allSegsCompactnessGain( 1.0 ),
242  m_allSegsSmoothnessOffset( 0 ),
243  m_allSegsSmoothnessGain( 0 ),
244  m_colorWeight( (SegmenterRegionGrowingSegment::FeatureType)colorWeight ),
245  m_compactnessWeight( (SegmenterRegionGrowingSegment::FeatureType)compactnessWeight )
246  {
247  m_bandsNumber = (unsigned int)bandsWeights.size();
248 
249  m_bandsWeights.resize( m_bandsNumber, 1 );
250 
251  for( unsigned int band = 0 ; band < m_bandsNumber ; ++band )
252  {
254  bandsWeights[ band ];
255  }
256  }
257 
259  {
260  }
261 
263  SegmenterRegionGrowingSegment const * const segment1Ptr,
264  SegmenterRegionGrowingSegment const * const segment2Ptr,
265  SegmenterRegionGrowingSegment * const mergePreviewSegPtr ) const
266  {
267  assert( segment1Ptr );
268  assert( segment1Ptr->m_features );
269  assert( segment2Ptr );
270  assert( segment2Ptr->m_features );
271  assert( mergePreviewSegPtr );
272 
273  // globals
274 
275  m_getDissimilarity_sizeSeg1D =
277 
278  m_getDissimilarity_sizeSeg2D =
280 
281  m_getDissimilarity_sizeUnionD = m_getDissimilarity_sizeSeg1D + m_getDissimilarity_sizeSeg2D;
282  TERP_DEBUG_TRUE_OR_THROW( m_getDissimilarity_sizeUnionD, "Internal error" );
283  mergePreviewSegPtr->m_size = (unsigned int)m_getDissimilarity_sizeUnionD;
284 
285  mergePreviewSegPtr->m_xStart = std::min( segment1Ptr->m_xStart,
286  segment2Ptr->m_xStart );
287  mergePreviewSegPtr->m_yStart = std::min( segment1Ptr->m_yStart,
288  segment2Ptr->m_yStart );
289  mergePreviewSegPtr->m_xBound = std::max( segment1Ptr->m_xBound,
290  segment2Ptr->m_xBound );
291  mergePreviewSegPtr->m_yBound = std::max( segment1Ptr->m_yBound,
292  segment2Ptr->m_yBound );
293 
294  assert( mergePreviewSegPtr->m_xBound > mergePreviewSegPtr->m_xStart );
295  assert( mergePreviewSegPtr->m_yBound > mergePreviewSegPtr->m_yStart );
296 
297  // Finding the form heterogeneity
298 
299  if( m_colorWeight != 1.0 )
300  {
302  m_segmentsIds, mergePreviewSegPtr->m_xStart,
303  mergePreviewSegPtr->m_yStart,
304  mergePreviewSegPtr->m_xBound,
305  mergePreviewSegPtr->m_yBound,
306  segment1Ptr->m_id,
307  segment2Ptr->m_id,
308  m_getDissimilarity_touchingEdgeLength1,
309  m_getDissimilarity_touchingEdgeLength2 );
310 
311  BAATZ_EL( mergePreviewSegPtr->m_features ) =
312  BAATZ_EL( segment1Ptr->m_features ) - ( (SegmenterRegionGrowingSegment::FeatureType)m_getDissimilarity_touchingEdgeLength1 )
313  +
314  BAATZ_EL( segment2Ptr->m_features ) - ( (SegmenterRegionGrowingSegment::FeatureType)m_getDissimilarity_touchingEdgeLength2 );
315 
317  BAATZ_EL( mergePreviewSegPtr->m_features ) /
318  std::sqrt( m_getDissimilarity_sizeUnionD ) );
319 
320  BAATZ_SM( mergePreviewSegPtr->m_features ) =
321  BAATZ_EL( mergePreviewSegPtr->m_features )
322  /
324  (
325  2 * ( mergePreviewSegPtr->m_xBound - mergePreviewSegPtr->m_xStart )
326  )
327  +
328  (
329  2 * ( mergePreviewSegPtr->m_yBound - mergePreviewSegPtr->m_yStart )
330  )
331  );
332 
333  m_getDissimilarity_hCompact =
334  (
335  (
336  (
337  BAATZ_CO( mergePreviewSegPtr->m_features )
338  +
339  m_allSegsCompactnessOffset
340  )
341  *
342  m_allSegsCompactnessGain
343  )
344  -
345  (
346  (
347  (
348  (
349  (
350  BAATZ_CO( segment1Ptr->m_features )
351  +
352  m_allSegsCompactnessOffset
353  )
354  *
355  m_allSegsCompactnessGain
356  )
357  *
358  m_getDissimilarity_sizeSeg1D
359  )
360  +
361  (
362  (
363  (
364  BAATZ_CO( segment2Ptr->m_features )
365  +
366  m_allSegsCompactnessOffset
367  )
368  *
369  m_allSegsCompactnessGain
370  )
371  *
372  m_getDissimilarity_sizeSeg2D
373  )
374  )
375  /
376  m_getDissimilarity_sizeUnionD
377  )
378  );
379 
380  m_getDissimilarity_hSmooth =
381  (
382  (
383  (
384  BAATZ_SM( mergePreviewSegPtr->m_features )
385  +
386  m_allSegsSmoothnessOffset
387  )
388  *
389  m_allSegsSmoothnessGain
390  )
391  -
392  (
393  (
394  (
395  (
396  (
397  BAATZ_SM( segment1Ptr->m_features )
398  +
399  m_allSegsSmoothnessOffset
400  )
401  *
402  m_allSegsSmoothnessGain
403  )
404  *
405  m_getDissimilarity_sizeSeg1D
406  )
407  +
408  (
409  (
410  (
411  BAATZ_SM( segment2Ptr->m_features )
412  +
413  m_allSegsSmoothnessOffset
414  )
415  *
416  m_allSegsSmoothnessGain
417  )
418  *
419  m_getDissimilarity_sizeSeg2D
420  )
421  )
422  /
423  m_getDissimilarity_sizeUnionD
424  )
425  );
426 
427  m_getDissimilarity_hForm =
428  (
429  (
430  m_compactnessWeight
431  *
432  m_getDissimilarity_hCompact
433  )
434  +
435  (
436  ( 1.0f - m_compactnessWeight )
437  *
438  m_getDissimilarity_hSmooth
439  )
440  );
441  }
442 
443  // Finding the color heterogeneity
444 
445  if( m_colorWeight != 0.0 )
446  {
447  m_getDissimilarity_hColor = 0;
448 
449  for( m_getDissimilarity_sumsIdx = 0 ; m_getDissimilarity_sumsIdx < m_bandsNumber ; ++m_getDissimilarity_sumsIdx )
450  {
451  m_getDissimilarity_sumUnion =
452  BAATZ_SU( segment1Ptr->m_features, m_getDissimilarity_sumsIdx )
453  +
454  BAATZ_SU( segment2Ptr->m_features, m_getDissimilarity_sumsIdx );
455  BAATZ_SU( mergePreviewSegPtr->m_features, m_getDissimilarity_sumsIdx ) =
456  m_getDissimilarity_sumUnion;
457 
458  m_getDissimilarity_squaresSumUnion =
459  BAATZ_SS( segment1Ptr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx )
460  +
461  BAATZ_SS( segment2Ptr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx );
462  BAATZ_SS( mergePreviewSegPtr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx ) = m_getDissimilarity_squaresSumUnion;
463 
464  m_getDissimilarity_meanUnion = m_getDissimilarity_sumUnion / m_getDissimilarity_sizeUnionD;
465 
466  m_getDissimilarity_stdDevUnion =
467  std::sqrt(
468  std::max(
470  ,
471  (
472  (
473  m_getDissimilarity_squaresSumUnion
474  -
475  (
476  ((SegmenterRegionGrowingSegment::FeatureType)2) * m_getDissimilarity_meanUnion * m_getDissimilarity_sumUnion
477  )
478  +
479  (
480  m_getDissimilarity_sizeUnionD * m_getDissimilarity_meanUnion * m_getDissimilarity_meanUnion
481  )
482  )
483  /
484  m_getDissimilarity_sizeUnionD
485  )
486  )
487  );
488  BAATZ_ST( mergePreviewSegPtr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx ) =
489  m_getDissimilarity_stdDevUnion;
490 
491  m_getDissimilarity_hColor +=
492  (
493  m_bandsWeights[ m_getDissimilarity_sumsIdx ]
494  *
495  (
496  (
497  (
498  m_getDissimilarity_stdDevUnion
499  +
500  m_allSegsStdDevOffset
501  )
502  *
503  m_allSegsStdDevGain
504  )
505  -
506  (
507  (
508  (
509  (
510  BAATZ_ST( segment1Ptr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx )
511  +
512  m_allSegsStdDevOffset
513  )
514  *
515  m_allSegsStdDevGain
516  )
517  +
518  (
519  (
520  BAATZ_ST( segment2Ptr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx )
521  +
522  m_allSegsStdDevOffset
523  )
524  *
525  m_allSegsStdDevGain
526  )
527  )
528  /
529  m_getDissimilarity_sizeUnionD
530  )
531  )
532  );
533  }
534  }
535 
536  m_getDissimilarity_hColor =
537  (
538  (
539  m_getDissimilarity_hColor
540  *
541  m_colorWeight
542  )
543  +
544  (
545  ( 1.0f - m_colorWeight )
546  *
547  m_getDissimilarity_hForm
548  )
549  );
550 
551  return std::max( m_getDissimilarity_hColor, ((SegmenterRegionGrowingSegment::FeatureType)0) );
552  }
553 
555  SegmenterRegionGrowingSegment * const segment1Ptr,
556  SegmenterRegionGrowingSegment const * const segment2Ptr ,
557  SegmenterRegionGrowingSegment const * const mergePreviewSegPtr ) const
558  {
559  assert( segment1Ptr );
560  assert( segment1Ptr->m_features );
561  assert( segment2Ptr );
562  assert( segment2Ptr->m_features );
563  assert( mergePreviewSegPtr );
564 
565  // Merging basic features
566 
567  segment1Ptr->m_size = mergePreviewSegPtr->m_size;
568  segment1Ptr->m_xStart = mergePreviewSegPtr->m_xStart;
569  segment1Ptr->m_xBound = mergePreviewSegPtr->m_xBound;
570  segment1Ptr->m_yStart = mergePreviewSegPtr->m_yStart;
571  segment1Ptr->m_yBound = mergePreviewSegPtr->m_yBound;
572 
573  // Merging specific features
574 
575  memcpy( segment1Ptr->m_features, mergePreviewSegPtr->m_features,
576  sizeof( SegmenterRegionGrowingSegment::FeatureType ) * getSegmentFeaturesSize() );
577  }
578 
580  SegmenterRegionGrowingSegment* const actSegsListHeadPtr )
581  {
582  m_update_compactnessMin =
583  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
584  m_update_compactnessMax = -1.0f *
585  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
586 
587  m_update_smoothnessMin =
588  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
589  m_update_smoothnessMax = -1.0f *
590  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
591 
592  m_update_stdDevMin =
593  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
594  m_update_stdDevMax = -1.0f *
595  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
596 
597  m_update_currentActSegPtr = actSegsListHeadPtr;
598 
599  while( m_update_currentActSegPtr )
600  {
601  m_update_featuresPtr = m_update_currentActSegPtr->m_features;
602 
603  if( m_colorWeight != 1.0 )
604  {
605  if( m_update_compactnessMin > BAATZ_CO( m_update_featuresPtr ) )
606  {
607  m_update_compactnessMin = BAATZ_CO( m_update_featuresPtr );
608  }
609  if( m_update_compactnessMax < BAATZ_CO( m_update_featuresPtr ) )
610  {
611  m_update_compactnessMax = BAATZ_CO( m_update_featuresPtr );
612  }
613 
614  if( m_update_smoothnessMin > BAATZ_SM( m_update_featuresPtr ) )
615  {
616  m_update_smoothnessMin = BAATZ_SM( m_update_featuresPtr );
617  }
618  if( m_update_smoothnessMax < BAATZ_SM( m_update_featuresPtr ) )
619  {
620  m_update_smoothnessMax = BAATZ_SM( m_update_featuresPtr );
621  }
622  }
623 
624  if( m_colorWeight != 0.0 )
625  {
626  m_update_stdDevPtr = BAATZ_STSTARTPTR( m_update_featuresPtr, m_bandsNumber );
627 
628  for( m_update_band = 0 ; m_update_band < m_bandsNumber ; ++m_update_band, ++m_update_stdDevPtr )
629  {
630  if( m_update_stdDevMin > *m_update_stdDevPtr )
631  {
632  m_update_stdDevMin = *m_update_stdDevPtr;
633  }
634  if( m_update_stdDevMax < *m_update_stdDevPtr )
635  {
636  m_update_stdDevMax = *m_update_stdDevPtr;
637  }
638  }
639  }
640 
641  m_update_currentActSegPtr = m_update_currentActSegPtr->m_nextActiveSegment;
642  }
643 
644  if( m_update_compactnessMax == m_update_compactnessMin )
645  {
646  m_allSegsCompactnessOffset = 0.0;
647 
648  if( m_update_compactnessMax == 0.0 )
649  m_allSegsCompactnessGain = 1.0;
650  else
651  m_allSegsCompactnessGain = 1.0f / m_update_compactnessMax;
652  }
653  else
654  {
655  m_allSegsCompactnessOffset = -1.0f * m_update_compactnessMin;
656  m_allSegsCompactnessGain = 1.0f / ( m_update_compactnessMax - m_update_compactnessMin );
657  }
658 
659  if( m_update_smoothnessMax == m_update_smoothnessMin )
660  {
661  m_allSegsSmoothnessOffset = 0.0;
662 
663  if( m_update_smoothnessMax == 0.0 )
664  m_allSegsSmoothnessGain = 1.0;
665  else
666  m_allSegsSmoothnessGain = 1.0f / m_update_smoothnessMax;
667  }
668  else
669  {
670  m_allSegsSmoothnessOffset = -1.0f * m_update_smoothnessMin;
671  m_allSegsSmoothnessGain = 1.0f / ( m_update_smoothnessMax - m_update_smoothnessMin );
672  }
673 
674  if( m_update_stdDevMax == m_update_stdDevMin )
675  {
676  m_allSegsStdDevOffset = 0.0;
677 
678  if( m_update_stdDevMax == 0.0 )
679  m_allSegsStdDevGain = 1.0;
680  else
681  m_allSegsStdDevGain = 1.0f / m_update_stdDevMax;
682  }
683  else
684  {
685  m_allSegsStdDevOffset = -1.0f * m_update_stdDevMin;
686  m_allSegsStdDevGain = 1.0f / ( m_update_stdDevMax - m_update_stdDevMin );
687  }
688  }
689 
690  //-------------------------------------------------------------------------
691 
693  {
694  m_isInitialized = false;
695  }
696 
698  {
699  reset();
700  }
701 
703  SegmenterStrategyParameters const* const strategyParams )
704  throw( te::rp::Exception )
705  {
706  m_isInitialized = false;
707  reset();
708 
710  dynamic_cast< SegmenterRegionGrowingStrategy::Parameters const* >( strategyParams );
711 
712  if( paramsPtr )
713  {
714  m_parameters = *( paramsPtr );
715 
717  "Invalid segmenter strategy parameter m_minSegmentSize" )
718 
721  "Invalid segmenter strategy parameter m_segmentsSimilarityThreshold" )
722 
725  "Invalid segmenter strategy parameter m_segmentFeatures" )
726 
728  {
730  "Invalid segmenter strategy parameter m_bandsWeights" );
731 
732  double bandsWeightsSum = 0;
733  unsigned int bandsWeightsIdx = 0 ;
734  for( bandsWeightsIdx = 0 ; bandsWeightsIdx <
735  m_parameters.m_bandsWeights.size() ; ++bandsWeightsIdx )
736  {
738  m_parameters.m_bandsWeights[ bandsWeightsIdx ] >= 0.0,
739  "Invalid segmenter strategy parameter m_bandsWeights" );
740  bandsWeightsSum += m_parameters.m_bandsWeights[ bandsWeightsIdx ];
741  }
742  TERP_TRUE_OR_RETURN_FALSE( bandsWeightsSum != 0.0,
743  "Invalid segmenter strategy parameter m_bandsWeights" );
744  for( bandsWeightsIdx = 0 ; bandsWeightsIdx <
745  m_parameters.m_bandsWeights.size() ; ++bandsWeightsIdx )
746  {
747  m_parameters.m_bandsWeights[ bandsWeightsIdx ] /= bandsWeightsSum;
748  }
749 
750  }
751 
752  m_isInitialized = true;
753 
754  return true;
755  }
756  else
757  {
758  return false;
759  }
760  }
761 
763  {
764  m_isInitialized = false;
768  }
769 
771  SegmenterIdsManager& segmenterIdsManager,
772  const te::rp::SegmenterSegmentsBlock& block2ProcessInfo,
773  const te::rst::Raster& inputRaster,
774  const std::vector< unsigned int >& inputRasterBands,
775  const std::vector< double >& inputRasterNoDataValues,
776  const std::vector< double >& inputRasterBandMinValues,
777  const std::vector< double >& inputRasterBandMaxValues,
778  te::rst::Raster& outputRaster,
779  const unsigned int outputRasterBand,
780  const bool enableProgressInterface )
781  throw( te::rp::Exception )
782  {
784  "Instance not initialized" )
785 
786  // Updating the bands weights info, if needed
787 
788  if( m_parameters.m_bandsWeights.empty() )
789  m_parameters.m_bandsWeights.resize( inputRasterBands.size(), 1.0 /
790  ((double)inputRasterBands.size()) );
791 
792  // Creating the merger instance
793 
794  std::auto_ptr< Merger > mergerPtr;
795 
797  {
799  {
800  mergerPtr.reset( new MeanMerger( inputRasterBands.size() ) );
801  break;
802  }
804  {
805  mergerPtr.reset( new BaatzMerger( m_parameters.m_colorWeight,
808  break;
809  }
810  default :
811  {
812  TERP_LOG_AND_THROW( "Invalid segment features type" );
813  break;
814  }
815  }
816 
817  // Initiating the segments pool
818 
819  const unsigned int segmentFeaturesSize = mergerPtr->getSegmentFeaturesSize();
820 
821  // The number of segments plus 3 (due 3 auxiliary segments
823  block2ProcessInfo.m_height * block2ProcessInfo.m_width ),
824  segmentFeaturesSize ), "Segments pool initiation error" );
825 
826 // {
827 // // checking alignment
828 // SegmenterRegionGrowingSegment* auxSegPtr = 0;
829 // unsigned int counter = 0;
830 // while( auxSegPtr = m_segmentsPool.getNextSegment() )
831 // {
832 // for( unsigned int featureIdx = 0 ; featureIdx < auxSegPtr->m_featuresSize ;
833 // ++featureIdx )
834 // {
835 // auxSegPtr->m_features[ featureIdx ] = (SegmenterRegionGrowingSegment::FeatureType)
836 // counter;
837 // }
838 // }
839 // m_segmentsPool.resetUseCounter();
840 // counter = 0;
841 // while( auxSegPtr = m_segmentsPool.getNextSegment() )
842 // {
843 // for( unsigned int featureIdx = 0 ; featureIdx < auxSegPtr->m_featuresSize ;
844 // ++featureIdx )
845 // {
846 // if( auxSegPtr->m_features[ featureIdx ] != (SegmenterRegionGrowingSegment::FeatureType)
847 // counter ) throw;
848 // }
849 // }
850 // }
851 
853  auxSeg1Ptr->disable();
855  auxSeg2Ptr->disable();
857  auxSeg3Ptr->disable();
858 
859  // Allocating the ids matrix
860 
861  if( ( m_segmentsIdsMatrix.getLinesNumber() != block2ProcessInfo.m_height ) ||
862  ( m_segmentsIdsMatrix.getColumnsNumber() != block2ProcessInfo.m_width ) )
863  {
864  TERP_TRUE_OR_RETURN_FALSE( m_segmentsIdsMatrix.reset( block2ProcessInfo.m_height,
865  block2ProcessInfo.m_width,
867  "Error allocating segments Ids matrix" );
868  }
869 
870  // Initializing segments
871 
872  SegmenterRegionGrowingSegment* actSegsListHeadPtr = 0;
873 
874  TERP_TRUE_OR_RETURN_FALSE( initializeSegments( segmenterIdsManager,
875  block2ProcessInfo, inputRaster, inputRasterBands, inputRasterNoDataValues,
876  inputRasterBandMinValues, inputRasterBandMaxValues,
877  &actSegsListHeadPtr ),
878  "Segments initalization error" );
879 
880  TERP_TRUE_OR_RETURN_FALSE( actSegsListHeadPtr != 0,
881  "Invalid active segments list header" );
882 
883  // Progress interface
884 
885  std::auto_ptr< te::common::TaskProgress > progressPtr;
886  if( enableProgressInterface )
887  {
888  progressPtr.reset( new te::common::TaskProgress );
889  progressPtr->setTotalSteps( 2 + m_parameters.m_segmentsSimIncreaseSteps );
890  progressPtr->setMessage( "Segmentation" );
891  }
892 
893  // Globals
894 
895  SegmenterRegionGrowingSegment::FeatureType minFoundDissimilarity = 0.0;
896  SegmenterRegionGrowingSegment::FeatureType maxFoundDissimilarity = 0.0;
897  unsigned int totalMergesNumber = 0;
898  SegmenterRegionGrowingSegment::IterationCounterType globalMergeIterationsCounter = 1;
899 
900  // Initial merge of equal segments
901 
902  if( enableProgressInterface )
903  {
904  if( ! progressPtr->isActive() )
905  {
906  return false;
907  }
908  progressPtr->pulse();
909  }
910 
911  // Merging the segments that are equal
912 
913 // TERP_LOGMSG( getActiveSegmentsNumber( actSegsListHeadPtr ) );
914 
915  mergeSegments(
916  0.0,
917  0,
918  segmenterIdsManager,
919  *mergerPtr,
920  false,
921  true,
922  auxSeg1Ptr,
923  auxSeg2Ptr,
924  auxSeg3Ptr,
925  minFoundDissimilarity,
926  maxFoundDissimilarity,
927  totalMergesNumber,
928  globalMergeIterationsCounter,
929  &actSegsListHeadPtr );
930 
931 // TERP_LOGMSG( getActiveSegmentsNumber( actSegsListHeadPtr ) );
932 
933  // Main Segmentation loop
934 
935  for( unsigned int segmentsSimIncreaseStep = 1 ; segmentsSimIncreaseStep <=
936  m_parameters.m_segmentsSimIncreaseSteps ; ++segmentsSimIncreaseStep )
937  {
938  const SegmenterRegionGrowingSegment::FeatureType disimilarityThreshold =
939  ( ((SegmenterRegionGrowingSegment::FeatureType)segmentsSimIncreaseStep) )
940  *
942  /
944 
945  mergeSegments(
946  disimilarityThreshold,
947  0,
948  segmenterIdsManager,
949  *mergerPtr,
952  auxSeg1Ptr,
953  auxSeg2Ptr,
954  auxSeg3Ptr,
955  minFoundDissimilarity,
956  maxFoundDissimilarity,
957  totalMergesNumber,
958  globalMergeIterationsCounter,
959  &actSegsListHeadPtr );
960 
961 // TERP_LOGMSG( getActiveSegmentsNumber( actSegsListHeadPtr ) );
962 
963  if( enableProgressInterface )
964  {
965  if( ! progressPtr->isActive() )
966  {
967  return false;
968  }
969  progressPtr->pulse();
970  }
971  }
972 
973  // Forcing the merge of too small segments
974 
976  {
977  mergeSegments(
978  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max(),
980  segmenterIdsManager,
981  *mergerPtr,
982  false,
983  true,
984  auxSeg1Ptr,
985  auxSeg2Ptr,
986  auxSeg3Ptr,
987  minFoundDissimilarity,
988  maxFoundDissimilarity,
989  totalMergesNumber,
990  globalMergeIterationsCounter,
991  &actSegsListHeadPtr );
992 
993 // TERP_LOGMSG( getActiveSegmentsNumber( actSegsListHeadPtr ) );
994  }
995 
996  if( enableProgressInterface )
997  {
998  if( ! progressPtr->isActive() )
999  {
1000  return false;
1001  }
1002  progressPtr->pulse();
1003  }
1004 
1005  // Flush result to the output raster
1006 
1007  {
1008  unsigned int blkCol = 0;
1009  SegmenterSegmentsBlock::SegmentIdDataType* segmentsIdsLinePtr = 0;
1010 
1011  for( unsigned int blkLine = 0 ; blkLine < block2ProcessInfo.m_height ; ++blkLine )
1012  {
1013  segmentsIdsLinePtr = m_segmentsIdsMatrix[ blkLine ];
1014 
1015  for( blkCol = 0 ; blkCol < block2ProcessInfo.m_width ; ++blkCol )
1016  {
1017  if( segmentsIdsLinePtr[ blkCol ] )
1018  {
1019  outputRaster.setValue( blkCol + block2ProcessInfo.m_startX, blkLine
1020  + block2ProcessInfo.m_startY, segmentsIdsLinePtr[ blkCol ],
1021  outputRasterBand );
1022  }
1023  }
1024  }
1025  }
1026 
1027  return true;
1028  }
1029 
1031  const unsigned int bandsToProcess,
1032  const unsigned int pixelsNumber ) const
1033  {
1034  TERP_TRUE_OR_THROW( m_isInitialized, "Instance not initialized" );
1035 
1036  // The features matrix inside the pool
1037  double featuresSizeBytes = 0.0;
1039  {
1041  {
1042  featuresSizeBytes = (double)
1043  (
1044  pixelsNumber
1045  *
1046  bandsToProcess
1047  *
1049  );
1050  break;
1051  }
1053  {
1054  featuresSizeBytes = (double)
1055  (
1056  pixelsNumber
1057  *
1058  (
1059  (
1060  3
1061  *
1063  )
1064  +
1065  (
1066  3
1067  *
1068  bandsToProcess
1069  *
1071  )
1072  )
1073  );
1074  break;
1075  }
1076  default :
1077  {
1078  TERP_LOG_AND_THROW( "Invalid segment features type" );
1079  break;
1080  }
1081  }
1082 
1083  return (double)
1084  (
1085  featuresSizeBytes
1086  +
1087  ( // The segments matrix inside the pool
1088  pixelsNumber
1089  *
1090  (
1092  +
1093  ( // An initial vector of pointers to 8 neighbors
1094  6
1095  *
1097  )
1098  )
1099  )
1100  +
1101  ( // The segments IDs matrix inside the strategy
1102  pixelsNumber
1103  *
1105  )
1106  );
1107  }
1108 
1110  {
1111  TERP_TRUE_OR_THROW( m_isInitialized, "Instance not initialized" );
1112  return (unsigned int)( std::sqrt( (double)m_parameters.m_minSegmentSize) );
1113  }
1114 
1116  SegmenterIdsManager& segmenterIdsManager,
1117  const te::rp::SegmenterSegmentsBlock& block2ProcessInfo,
1118  const te::rst::Raster& inputRaster,
1119  const std::vector< unsigned int >& inputRasterBands,
1120  const std::vector< double >& inputRasterNoDataValues,
1121  const std::vector< double >& inputRasterBandMinValues,
1122  const std::vector< double >& inputRasterBandMaxValues,
1123  SegmenterRegionGrowingSegment** actSegsListHeadPtr )
1124  {
1125  const unsigned int inputRasterBandsSize = (unsigned int)
1126  inputRasterBands.size();
1127 
1128  (*actSegsListHeadPtr) = 0;
1129 
1130  // calculating offset and gain
1131 
1132  std::vector< SegmenterRegionGrowingSegment::FeatureType > inputRasterBandGains(
1133  inputRasterBandMinValues.size() );
1134 
1135  {
1136  for( unsigned int inputRasterBandMinValuesIdx = 0 ; inputRasterBandMinValuesIdx
1137  < inputRasterBandMinValues.size() ; ++inputRasterBandMinValuesIdx )
1138  {
1139  inputRasterBandGains[ inputRasterBandMinValuesIdx ] =
1140  inputRasterBandMaxValues[ inputRasterBandMinValuesIdx ] -
1141  inputRasterBandMinValues[ inputRasterBandMinValuesIdx ];
1142 
1143  if( inputRasterBandGains[ inputRasterBandMinValuesIdx ] != 0.0 )
1144  {
1145  inputRasterBandGains[ inputRasterBandMinValuesIdx ] = 1.0 /
1146  inputRasterBandGains[ inputRasterBandMinValuesIdx ];
1147  }
1148  }
1149  }
1150 
1151  // Initializing each segment
1152 
1153  unsigned int blkLine = 0;
1154  unsigned int blkCol = 0;
1155  SegmenterRegionGrowingSegment* segmentPtr = 0;
1156  SegmenterRegionGrowingSegment* neighborSegmentPtr = 0;
1157  bool rasterValuesAreValid = true;
1158  unsigned int inputRasterBandsIdx = 0;
1159  double value = 0;
1160  const std::vector< double > dummyZeroesVector( inputRasterBandsSize, 0 );
1161 
1162  std::list< SegmenterSegmentsBlock::SegmentIdDataType >
1163  unusedLineSegmentIds;
1164 
1165  std::vector< SegmenterSegmentsBlock::SegmentIdDataType >
1166  lineSegmentIds;
1167  lineSegmentIds.reserve( block2ProcessInfo.m_width );
1168 
1169  std::vector< SegmenterRegionGrowingSegment::FeatureType > rasterValues;
1170  std::vector< SegmenterRegionGrowingSegment::FeatureType > rasterSquareValues;
1171  rasterValues.resize( inputRasterBandsSize, 0 );
1172  rasterSquareValues.resize( inputRasterBandsSize, 0 );
1173  std::vector< SegmenterRegionGrowingSegment* > usedSegPointers1( block2ProcessInfo.m_width, 0 );
1174  std::vector< SegmenterRegionGrowingSegment* > usedSegPointers2( block2ProcessInfo.m_width, 0 );
1175  std::vector< SegmenterRegionGrowingSegment* >* lastLineSegsPtrs = &usedSegPointers1;
1176  std::vector< SegmenterRegionGrowingSegment* >* currLineSegsPtrs = &usedSegPointers2;
1177 
1178  SegmenterRegionGrowingSegment* prevActSegPtr = 0;
1179 
1180  unsigned int rasterValuesIdx = 0;
1181 
1182  for( blkLine = 0 ; blkLine < block2ProcessInfo.m_height ; ++blkLine )
1183  {
1184  segmenterIdsManager.getNewIDs( block2ProcessInfo.m_width, lineSegmentIds );
1185 
1186  for( blkCol = 0 ; blkCol < block2ProcessInfo.m_width ; ++blkCol )
1187  {
1188  if(
1189  ( blkLine >= block2ProcessInfo.m_topCutOffProfile[ blkCol ] )
1190  &&
1191  ( blkLine <= block2ProcessInfo.m_bottomCutOffProfile[ blkCol ] )
1192  &&
1193  ( blkCol >= block2ProcessInfo.m_leftCutOffProfile[ blkLine ] )
1194  &&
1195  ( blkCol <= block2ProcessInfo.m_rightCutOffProfile[ blkLine ] )
1196  )
1197  {
1198  rasterValuesAreValid = true;
1199 
1200  for( inputRasterBandsIdx = 0 ; inputRasterBandsIdx <
1201  inputRasterBandsSize ; ++inputRasterBandsIdx )
1202  {
1203  inputRaster.getValue( blkCol + block2ProcessInfo.m_startX, blkLine +
1204  block2ProcessInfo.m_startY, value,
1205  inputRasterBands[ inputRasterBandsIdx ] );
1206 
1207  if( value == inputRasterNoDataValues[ inputRasterBandsIdx ] )
1208  {
1209  rasterValuesAreValid = false;
1210  break;
1211  }
1212  else
1213  {
1214  value -= inputRasterBandMinValues[ inputRasterBandsIdx ];
1215  value *= inputRasterBandGains[ inputRasterBandsIdx ];
1216 
1217  rasterValues[ inputRasterBandsIdx ] =
1219  rasterSquareValues[ inputRasterBandsIdx ] =
1220  (SegmenterRegionGrowingSegment::FeatureType)( value * value );
1221  }
1222  }
1223  }
1224  else
1225  {
1226  rasterValuesAreValid = false;
1227  }
1228 
1229  // assotiating a segment object
1230 
1231  if( rasterValuesAreValid )
1232  {
1234  {
1236  {
1237  segmentPtr = m_segmentsPool.getNextSegment();
1238  assert( segmentPtr );
1239 
1240  for( rasterValuesIdx = 0 ; rasterValuesIdx < inputRasterBandsSize ;
1241  ++rasterValuesIdx )
1242  {
1243  segmentPtr->m_features[ rasterValuesIdx ] = rasterValues[
1244  rasterValuesIdx ];
1245  }
1246 
1247  break;
1248  }
1250  {
1251  segmentPtr = m_segmentsPool.getNextSegment();
1252  assert( segmentPtr );
1253 
1254  for( rasterValuesIdx = 0 ; rasterValuesIdx < inputRasterBandsSize ;
1255  ++rasterValuesIdx )
1256  {
1257  BAATZ_SU( segmentPtr->m_features, rasterValuesIdx ) =
1258  rasterValues[ rasterValuesIdx ];
1259  BAATZ_SS( segmentPtr->m_features, inputRasterBandsSize, rasterValuesIdx ) =
1260  rasterSquareValues[ rasterValuesIdx ];
1261  BAATZ_ST( segmentPtr->m_features, inputRasterBandsSize, rasterValuesIdx ) =
1262  0.0;
1263  }
1264 
1265  BAATZ_EL( segmentPtr->m_features ) = 4;
1266  BAATZ_CO( segmentPtr->m_features ) = 4;
1267  BAATZ_SM( segmentPtr->m_features ) = 1;
1268 
1269  break;
1270  }
1271  default :
1272  {
1273  TERP_LOG_AND_THROW( "Invalid segment features type" );
1274  break;
1275  }
1276  }
1277 
1278  currLineSegsPtrs->operator[]( blkCol ) = segmentPtr;
1279 
1280  segmentPtr->m_id = lineSegmentIds[ blkCol ];
1281  segmentPtr->m_size = 1;
1282  segmentPtr->m_xStart = blkCol;
1283  segmentPtr->m_xBound = blkCol + 1;
1284  segmentPtr->m_yStart = blkLine;
1285  segmentPtr->m_yBound = blkLine + 1;
1286  segmentPtr->m_mergetIteration = 0;
1287  segmentPtr->m_prevActiveSegment = prevActSegPtr;
1288  segmentPtr->m_nextActiveSegment = 0;
1289 
1290  m_segmentsIdsMatrix( blkLine, blkCol ) = segmentPtr->m_id;
1291 
1292  // updating the neighboorhood info
1293 
1294  segmentPtr->clearNeighborSegments();
1295 
1296  if( blkLine )
1297  {
1298  neighborSegmentPtr = lastLineSegsPtrs->operator[]( blkCol );
1299 
1300  if( neighborSegmentPtr )
1301  {
1302  segmentPtr->addNeighborSegment( neighborSegmentPtr );
1303 
1304  neighborSegmentPtr->addNeighborSegment( segmentPtr );
1305  }
1306  }
1307 
1308  if( blkCol )
1309  {
1310  neighborSegmentPtr = currLineSegsPtrs->operator[]( blkCol - 1 );
1311 
1312  if( neighborSegmentPtr )
1313  {
1314  segmentPtr->addNeighborSegment( neighborSegmentPtr );
1315 
1316  neighborSegmentPtr->addNeighborSegment( segmentPtr );
1317  }
1318  }
1319 
1320  // Updating the active segments list header
1321 
1322  if( (*actSegsListHeadPtr) == 0 )
1323  {
1324  (*actSegsListHeadPtr) = segmentPtr;
1325  }
1326 
1327  // Updating the previous active segment
1328 
1329  if( prevActSegPtr )
1330  {
1331  prevActSegPtr->m_nextActiveSegment = segmentPtr;
1332  }
1333 
1334  prevActSegPtr = segmentPtr;
1335  }
1336  else // !rasterValueIsValid
1337  {
1338  m_segmentsIdsMatrix( blkLine, blkCol ) = 0;
1339  unusedLineSegmentIds.push_back( lineSegmentIds[ blkCol ] );
1340  currLineSegsPtrs->operator[]( blkCol ) = 0;
1341  }
1342  }
1343 
1344  // Free unused IDs
1345 
1346  if( ! unusedLineSegmentIds.empty() )
1347  {
1348  segmenterIdsManager.addFreeIDs( unusedLineSegmentIds );
1349  unusedLineSegmentIds.clear();
1350  }
1351 
1352  // Swapping the pointers to the vectors of used segment pointers
1353 
1354  if( lastLineSegsPtrs == ( &usedSegPointers1 ) )
1355  {
1356  lastLineSegsPtrs = &usedSegPointers2;
1357  currLineSegsPtrs = &usedSegPointers1;
1358  }
1359  else
1360  {
1361  lastLineSegsPtrs = &usedSegPointers1;
1362  currLineSegsPtrs = &usedSegPointers2;
1363  }
1364  }
1365 
1366  return true;
1367  }
1368 
1370  const SegmenterRegionGrowingSegment::FeatureType disimilarityThreshold,
1371  const unsigned int maxSegSizeThreshold,
1372  SegmenterIdsManager& segmenterIdsManager,
1373  Merger& merger,
1374  const bool enablelocalMutualBestFitting,
1375  const bool enableSameIterationMerges,
1376  SegmenterRegionGrowingSegment* auxSeg1Ptr,
1377  SegmenterRegionGrowingSegment* auxSeg2Ptr,
1378  SegmenterRegionGrowingSegment* auxSeg3Ptr,
1379  SegmenterRegionGrowingSegment::FeatureType& minFoundDissimilarity,
1380  SegmenterRegionGrowingSegment::FeatureType& maxFoundDissimilarity,
1381  unsigned int& totalMergesNumber,
1382  SegmenterRegionGrowingSegment::IterationCounterType& globalMergeIterationsCounter,
1383  SegmenterRegionGrowingSegment** const actSegsListHeadPtrPtr )
1384  {
1385  TERP_TRUE_OR_THROW( actSegsListHeadPtrPtr != 0, "Invalid active segments list header pointer" );
1386  TERP_TRUE_OR_THROW( (*actSegsListHeadPtrPtr) != 0, "Invalid active segments list header pointer" );
1387 
1388  minFoundDissimilarity =
1389  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
1390  maxFoundDissimilarity = -1.0 * minFoundDissimilarity;
1391  totalMergesNumber = 0;
1392 
1393  // Globals
1394 
1395  SegmenterRegionGrowingSegment::FeatureType internalDisimilarityThreshold =
1396  disimilarityThreshold;
1397  unsigned int internalMaxSegSizeThreshold = maxSegSizeThreshold;
1398  if( maxSegSizeThreshold )
1399  {
1400  internalDisimilarityThreshold = std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
1401  }
1402  else
1403  {
1404  internalMaxSegSizeThreshold = std::numeric_limits< unsigned int >::max();
1405  }
1406  unsigned int iterationMergedSegmentsNumber = 0;
1407  unsigned int segmentsLine = 0;
1408  unsigned int segmentsLineBound = 0;
1409  unsigned int segmentCol = 0;
1410  unsigned int segmentColStart = 0;
1411  unsigned int segmentColBound = 0;
1412  SegmenterRegionGrowingSegment* minForwardDissimilaritySegmentPtr = 0;
1413  SegmenterRegionGrowingSegment::FeatureType forwardDissimilarityValue = 0;
1414  SegmenterRegionGrowingSegment::FeatureType minForwardDissimilarityValue = 0;
1415  SegmenterRegionGrowingSegment* minBackwardDissimilaritySegmentPtr = 0;
1416  SegmenterRegionGrowingSegment::FeatureType backwardDissimilarityValue = 0;
1417  SegmenterRegionGrowingSegment::FeatureType minBackwardDissimilarityValue = 0;
1418  SegmenterSegmentsBlock::SegmentIdDataType* segmentsIdsLinePtr = 0;
1419  SegmenterSegmentsBlock::SegmentIdDataType currentSegmentId = 0;
1420  std::list< SegmenterSegmentsBlock::SegmentIdDataType > freeSegmentIds;
1421  unsigned int neighborSegIdx = 0;
1422  SegmenterRegionGrowingSegment* currActSegPtr = (*actSegsListHeadPtrPtr);
1423 
1424  // Main iterations loop
1425 
1426  do
1427  {
1428  iterationMergedSegmentsNumber = 0;
1429  currActSegPtr = (*actSegsListHeadPtrPtr);
1430 
1431  // Updating the merger state
1432 
1433  merger.update( *actSegsListHeadPtrPtr );
1434 
1435  // iterating over each segment
1436 
1437  do
1438  {
1439  if(
1440  (
1441  enableSameIterationMerges
1442  ||
1443  ( currActSegPtr->m_mergetIteration < globalMergeIterationsCounter )
1444  )
1445  &&
1446  ( currActSegPtr->m_size <= internalMaxSegSizeThreshold )
1447  )
1448  {
1449  // finding the neighbor segment with minimum dissimilary value
1450  // related to the current sement
1451 
1452  minForwardDissimilaritySegmentPtr = 0;
1453  minForwardDissimilarityValue =
1454  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
1455 
1456  for( neighborSegIdx = 0 ; neighborSegIdx < currActSegPtr->m_neighborSegmentsSize ;
1457  ++neighborSegIdx )
1458  {
1459  if( currActSegPtr->m_neighborSegments[ neighborSegIdx ] )
1460  {
1461  forwardDissimilarityValue = merger.getDissimilarity( currActSegPtr,
1462  currActSegPtr->m_neighborSegments[ neighborSegIdx ], auxSeg1Ptr );
1463 
1464  if(
1465  ( forwardDissimilarityValue <= internalDisimilarityThreshold )
1466  &&
1467  ( forwardDissimilarityValue < minForwardDissimilarityValue )
1468  )
1469  {
1470  minForwardDissimilarityValue = forwardDissimilarityValue;
1471  minForwardDissimilaritySegmentPtr = currActSegPtr->m_neighborSegments[ neighborSegIdx ];
1472  auxSeg3Ptr->operator=( *auxSeg1Ptr );
1473  }
1474  }
1475  }
1476 
1477  // does the neighbor wants to merge back ?
1478 
1479  if( enablelocalMutualBestFitting && ( minForwardDissimilaritySegmentPtr != 0 ) )
1480  {
1481  // Calculating all neighbor neighbor segments dissimilarity
1482 
1483  minBackwardDissimilaritySegmentPtr = 0;
1484  backwardDissimilarityValue = 0;
1485  minBackwardDissimilarityValue =
1486  std::numeric_limits< SegmenterRegionGrowingSegment::FeatureType >::max();
1487 
1488  for( neighborSegIdx = 0 ; neighborSegIdx < minForwardDissimilaritySegmentPtr->m_neighborSegmentsSize ;
1489  ++neighborSegIdx )
1490  {
1491  if( minForwardDissimilaritySegmentPtr->m_neighborSegments[ neighborSegIdx ] )
1492  {
1493  backwardDissimilarityValue =
1494  merger.getDissimilarity( minForwardDissimilaritySegmentPtr,
1495  minForwardDissimilaritySegmentPtr->m_neighborSegments[ neighborSegIdx ], auxSeg2Ptr );
1496 
1497  if( backwardDissimilarityValue < minBackwardDissimilarityValue )
1498  {
1499  minBackwardDissimilarityValue = backwardDissimilarityValue;
1500  minBackwardDissimilaritySegmentPtr =
1501  minForwardDissimilaritySegmentPtr->m_neighborSegments[ neighborSegIdx ];
1502  }
1503  }
1504  }
1505 
1506  if( minBackwardDissimilaritySegmentPtr != currActSegPtr )
1507  {
1508  minForwardDissimilaritySegmentPtr = 0;
1509  }
1510  }
1511 
1512  // if the min forward dissimilarity segment was found
1513 
1514  if(
1515  ( minForwardDissimilaritySegmentPtr != 0 )
1516  &&
1517  (
1518  enableSameIterationMerges
1519  ||
1520  (
1521  minForwardDissimilaritySegmentPtr->m_mergetIteration
1522  <
1523  globalMergeIterationsCounter
1524  )
1525  )
1526  )
1527  {
1528  if( minFoundDissimilarity > minForwardDissimilarityValue )
1529  {
1530  minFoundDissimilarity = minForwardDissimilarityValue;
1531  }
1532  if( maxFoundDissimilarity < minForwardDissimilarityValue )
1533  {
1534  maxFoundDissimilarity = minForwardDissimilarityValue;
1535  }
1536 
1537  // If the maximum similary neighbor was found it will be merged
1538  // if the dissimilarity value is below the threshold
1539  // merging segment data
1540 
1541  merger.mergeFeatures( currActSegPtr, minForwardDissimilaritySegmentPtr,
1542  auxSeg3Ptr );
1543 
1544  currActSegPtr->m_mergetIteration = globalMergeIterationsCounter;
1545 
1546  currActSegPtr->removeNeighborSegment( minForwardDissimilaritySegmentPtr );
1547 
1548  // updating the max similarity segment neighborhood segments
1549  // with the current segment
1550 
1551  for( neighborSegIdx = 0 ; neighborSegIdx < minForwardDissimilaritySegmentPtr->m_neighborSegmentsSize ;
1552  ++neighborSegIdx )
1553  {
1554  if(
1555  ( minForwardDissimilaritySegmentPtr->m_neighborSegments[ neighborSegIdx ] != 0 )
1556  &&
1557  ( minForwardDissimilaritySegmentPtr->m_neighborSegments[ neighborSegIdx ] != currActSegPtr )
1558  )
1559  {
1560  // adding the max similarity neighborhood segments to the
1561  // current one, if it is not already there
1562 
1563  currActSegPtr->addNeighborSegment(
1564  minForwardDissimilaritySegmentPtr->m_neighborSegments[ neighborSegIdx ] );
1565 
1566  // adding the current segment into the max similarity
1567  // neighborhood segments list, if it is not already there
1568 
1569  minForwardDissimilaritySegmentPtr->m_neighborSegments[ neighborSegIdx ]->addNeighborSegment(
1570  currActSegPtr );
1571 
1572  // removing the merged segment reference from its neighbor
1573  // list
1574 
1575  minForwardDissimilaritySegmentPtr->m_neighborSegments[ neighborSegIdx ]->removeNeighborSegment(
1576  minForwardDissimilaritySegmentPtr );
1577  }
1578  }
1579 
1580  // updating the segments Ids container matrix
1581 
1582  segmentsLineBound = minForwardDissimilaritySegmentPtr->m_yBound;
1583  segmentColStart = minForwardDissimilaritySegmentPtr->m_xStart;
1584  segmentColBound = minForwardDissimilaritySegmentPtr->m_xBound;
1585  currentSegmentId = currActSegPtr->m_id;
1586 
1587  for( segmentsLine = minForwardDissimilaritySegmentPtr->m_yStart ;
1588  segmentsLine < segmentsLineBound ; ++segmentsLine )
1589  {
1590  segmentsIdsLinePtr = m_segmentsIdsMatrix[ segmentsLine ];
1591 
1592  for( segmentCol = segmentColStart ; segmentCol <
1593  segmentColBound ; ++segmentCol )
1594  {
1595  if( segmentsIdsLinePtr[ segmentCol ] ==
1596  minForwardDissimilaritySegmentPtr->m_id )
1597  {
1598  segmentsIdsLinePtr[ segmentCol ] = currentSegmentId;
1599  }
1600  }
1601  }
1602 
1603  // disabling the merged segment
1604  // The merged segment id will be given back to ids manager
1605 
1606  if( minForwardDissimilaritySegmentPtr == (*actSegsListHeadPtrPtr) )
1607  {
1608  (*actSegsListHeadPtrPtr) = (*actSegsListHeadPtrPtr)->m_nextActiveSegment;
1609  }
1610 
1611  if( minForwardDissimilaritySegmentPtr->m_prevActiveSegment )
1612  {
1613  minForwardDissimilaritySegmentPtr->m_prevActiveSegment->m_nextActiveSegment =
1614  minForwardDissimilaritySegmentPtr->m_nextActiveSegment;
1615  }
1616 
1617  if( minForwardDissimilaritySegmentPtr->m_nextActiveSegment )
1618  {
1619  minForwardDissimilaritySegmentPtr->m_nextActiveSegment->m_prevActiveSegment =
1620  minForwardDissimilaritySegmentPtr->m_prevActiveSegment;
1621  }
1622 
1623  minForwardDissimilaritySegmentPtr->disable();
1624 
1625  minForwardDissimilaritySegmentPtr->clearNeighborSegments();
1626 
1627  freeSegmentIds.push_back( minForwardDissimilaritySegmentPtr->m_id );
1628 
1629  ++iterationMergedSegmentsNumber;
1630  }
1631  }
1632 
1633  // going to the next segment
1634 
1635  currActSegPtr = currActSegPtr->m_nextActiveSegment;
1636 
1637  } while( currActSegPtr );
1638 
1639  // give back the free unused sement ids
1640 
1641  if( ! freeSegmentIds.empty() )
1642  {
1643  segmenterIdsManager.addFreeIDs( freeSegmentIds );
1644  freeSegmentIds.clear();
1645  }
1646 
1647  totalMergesNumber += iterationMergedSegmentsNumber;
1648 
1649 // std::cout << std::endl << "Iteration Number: " << iterationNumber <<
1650 // " Merged segments number:" << iterationMergedSegmentsNumber << std::endl;
1651 
1652  ++globalMergeIterationsCounter;
1653  }
1654  while( iterationMergedSegmentsNumber && ( globalMergeIterationsCounter <
1655  std::numeric_limits< SegmenterRegionGrowingSegment::IterationCounterType>::max() ) );
1656  }
1657 
1659  const SegmentsIdsMatrixT& segmentsIds, bool normto8bits,
1660  const std::string& fileName )
1661  {
1662  std::map<std::string, std::string> rinfo;
1663  rinfo["SOURCE"] = fileName;
1664 
1665  const unsigned int linesNmb = segmentsIds.getLinesNumber();
1666  const unsigned int colsNmb = segmentsIds.getColumnsNumber();
1667 
1668  te::rst::Grid* gridPtr = new te::rst::Grid( colsNmb, linesNmb );
1669 
1670  std::vector< te::rst::BandProperty* > bandsProps;
1671  bandsProps.push_back( new te::rst::BandProperty( 0,
1672  (normto8bits ? te::dt::UCHAR_TYPE : te::dt::UINT32_TYPE) ) );
1673 
1674  te::rst::Raster* rasterPtr = te::rst::RasterFactory::make( "GDAL",
1675  gridPtr, bandsProps, rinfo );
1676  TERP_TRUE_OR_THROW( rasterPtr, "Invalid pointer" )
1677 
1678  unsigned int col = 0;
1679  unsigned int line = 0 ;
1680 
1681  double offset = 0.0;
1682  double scale = 1.0;
1683 
1684  if( normto8bits )
1685  {
1686  double minValue = DBL_MAX;
1687  double maxValue = -1.0 * DBL_MAX;
1688  double value = 0;
1689 
1690  for( line = 0 ; line < linesNmb ; ++line )
1691  {
1692  for( col = 0 ; col < colsNmb ; ++col )
1693  {
1694  value = (double)segmentsIds( line, col );
1695 
1696  if( value > maxValue ) maxValue = value;
1697  if( value < minValue ) minValue = value;
1698  }
1699  }
1700 
1701  offset = minValue;
1702  scale = 254.0 / ( maxValue - minValue );
1703  }
1704 
1705  double value = 0;
1706 
1707  for( line = 0 ; line < linesNmb ; ++line )
1708  {
1709  for( col = 0 ; col < colsNmb ; ++col )
1710  {
1711  value = ( ((double)segmentsIds( line, col )) - offset ) * scale;
1712  TERP_TRUE_OR_THROW( value <= 255.0, "Invalid value:" +
1713  boost::lexical_cast< std::string >( value ) )
1714 
1715  rasterPtr->setValue( col, line, value , 0 );
1716  }
1717  }
1718 
1719  delete rasterPtr;
1720  }
1721 
1723  const SegmentsIdsMatrixT& segsIds,
1724  const unsigned int& xStart, const unsigned int& yStart,
1725  const unsigned int& xBound, const unsigned int& yBound,
1728  unsigned int& edgeLength1,
1729  unsigned int& edgeLength2 )
1730  {
1731  const unsigned int colsNumber = segsIds.getColumnsNumber();
1732  const unsigned int linesNumber = segsIds.getLinesNumber();
1733 
1734  TERP_DEBUG_TRUE_OR_THROW( xStart < colsNumber,
1735  "Internal Error" )
1736  TERP_DEBUG_TRUE_OR_THROW( xBound <= colsNumber,
1737  "Internal Error" )
1738  TERP_DEBUG_TRUE_OR_THROW( yStart < linesNumber,
1739  "Internal Error" )
1740  TERP_DEBUG_TRUE_OR_THROW( yBound <= linesNumber,
1741  "Internal Error" )
1742  TERP_DEBUG_TRUE_OR_THROW( xStart < xBound, "Internal Error" )
1743  TERP_DEBUG_TRUE_OR_THROW( yStart < yBound, "Internal Error" )
1744 
1745  // finding the touching pixels
1746 
1747  edgeLength1 = 0;
1748  edgeLength2 = 0;
1749 
1750  unsigned int xIdx = 0;
1751  const unsigned int lastColIdx = colsNumber - 1;
1752  const unsigned int lastLineIdx = linesNumber - 1;
1753 
1754  for( unsigned int yIdx = yStart ; yIdx < yBound ; ++yIdx )
1755  {
1756  for( xIdx = xStart; xIdx < xBound ; ++xIdx )
1757  {
1758  if( segsIds[ yIdx ][ xIdx ] == id1 )
1759  {
1760  if( yIdx )
1761  if( segsIds[ yIdx - 1 ][ xIdx ] == id2 )
1762  {
1763  ++edgeLength1;
1764  continue;
1765  }
1766  if( xIdx )
1767  if( segsIds[ yIdx ][ xIdx - 1 ] == id2 )
1768  {
1769  ++edgeLength1;
1770  continue;
1771  }
1772  if( yIdx < lastLineIdx)
1773  if( segsIds[ yIdx + 1 ][ xIdx ] == id2 )
1774  {
1775  ++edgeLength1;
1776  continue;
1777  }
1778  if( xIdx < lastColIdx )
1779  if( segsIds[ yIdx ][ xIdx + 1 ] == id2 )
1780  {
1781  ++edgeLength1;
1782  continue;
1783  }
1784  }
1785  else if( segsIds[ yIdx ][ xIdx ] == id2 )
1786  {
1787  if( yIdx )
1788  if( segsIds[ yIdx - 1 ][ xIdx ] == id1 )
1789  {
1790  ++edgeLength2;
1791  continue;
1792  }
1793  if( xIdx )
1794  if( segsIds[ yIdx ][ xIdx - 1 ] == id1 )
1795  {
1796  ++edgeLength2;
1797  continue;
1798  }
1799  if( yIdx < lastLineIdx)
1800  if( segsIds[ yIdx + 1 ][ xIdx ] == id1 )
1801  {
1802  ++edgeLength2;
1803  continue;
1804  }
1805  if( xIdx < lastColIdx )
1806  if( segsIds[ yIdx ][ xIdx + 1 ] == id1 )
1807  {
1808  ++edgeLength2;
1809  continue;
1810  }
1811  }
1812  }
1813  }
1814  }
1815 
1817  SegmenterRegionGrowingSegment* const actSegsListHeadPtr ) const
1818  {
1819  unsigned int returnValue = 0;
1820 
1821  SegmenterRegionGrowingSegment* currSegPtr = actSegsListHeadPtr;
1822 
1823  while( currSegPtr )
1824  {
1825  ++returnValue;
1826  currSegPtr = currSegPtr->m_nextActiveSegment;
1827  }
1828 
1829  return returnValue;
1830  }
1831 
1832  //-------------------------------------------------------------------------
1833 
1835  : te::rp::SegmenterStrategyFactory( "RegionGrowing" )
1836  {
1837  }
1838 
1840  {
1841  }
1842 
1844  {
1846  }
1847 
1848  } // end namespace rp
1849 } // end namespace te
1850 
SegmenterRegionGrowingSegment::FeatureType getDissimilarity(SegmenterRegionGrowingSegment const *const segment1Ptr, SegmenterRegionGrowingSegment const *const segment2Ptr, SegmenterRegionGrowingSegment *const mergePreviewSegPtr) const
Returns a dimilarity index between this and the other segment.
Segmenter segments IDs manager.
virtual void setValue(unsigned int c, unsigned int r, const double value, std::size_t b=0)
Sets the attribute value in a band of a cell.
Definition: Raster.cpp:233
void mergeFeatures(SegmenterRegionGrowingSegment *const segment1Ptr, SegmenterRegionGrowingSegment const *const segment2Ptr, SegmenterRegionGrowingSegment const *const mergePreviewSegPtr) const
Merge specific segment features from both segments into the first segment.
The Baatz based features will be used - Reference: Baatz, M.; Schape, A. Multiresolution segmentation...
#define BAATZ_SM(featPtr)
bool m_isInitialized
true if this instance is initialized.
Raster region growing segmenter strategy.
unsigned int m_neighborSegmentsSize
The current size of m_neighborSegments.
void disable()
Disable this segment ( same as m_mergetIteration = std::numeric_limits< SegmenterRegionGrowingSegment...
std::vector< SegmenterRegionGrowingSegment::FeatureType > m_bandsWeights
A vector where each bands weight are stored.
A raster band description.
Definition: BandProperty.h:61
BaatzMerger(const double &colorWeight, const double &compactnessWeight, const std::vector< double > &bandsWeights, const SegmentsIdsMatrixT &segmentsIds)
Default constructor.
#define BAATZ_SS(featPtr, bandsNmb, band)
virtual void update(SegmenterRegionGrowingSegment *const actSegsListHeadPtr)=0
Update the internal state.
SegmenterRegionGrowingStrategy::Parameters m_parameters
Internal execution parameters.
#define BAATZ_CO(featPtr)
unsigned int m_yBound
Segment lower bound Y coordinate box over the label image.
unsigned int m_xStart
Segment left X coordinate box over the label image.
SegmentsIdsMatrixT m_segmentsIdsMatrix
A internal segments IDs matrix that can be reused on each strategy execution.
SegmenterRegionGrowingSegment::FeatureType getDissimilarity(SegmenterRegionGrowingSegment const *const segment1Ptr, SegmenterRegionGrowingSegment const *const segment2Ptr, SegmenterRegionGrowingSegment *const mergePreviewSegPtr) const
Returns a dimilarity index between this and the other segment.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
bool m_enableSameIterationMerges
If enabled, a merged segment could be merged with another within the same iteration (default:false)...
IterationCounterType m_mergetIteration
The current merge iteration.
void mergeFeatures(SegmenterRegionGrowingSegment *const segment1Ptr, SegmenterRegionGrowingSegment const *const segment2Ptr, SegmenterRegionGrowingSegment const *const mergePreviewSegPtr) const
Merge specific segment features from both segments into the first segment.
virtual SegmenterRegionGrowingSegment::FeatureType getDissimilarity(SegmenterRegionGrowingSegment const *const segment1Ptr, SegmenterRegionGrowingSegment const *const segment2Ptr, SegmenterRegionGrowingSegment *const mergePreviewSegPtr) const =0
Returns a dimilarity index between this and the other segment.
unsigned int m_xBound
Segment lower bound X coordinate box over the label image.
void update(SegmenterRegionGrowingSegment *const actSegsListHeadPtr)
Update the internal state.
SegmenterRegionGrowingSegment * m_nextActiveSegment
A pointer to the next active segment.
Raster region growing segmenter strategy factory.
void addNeighborSegment(SegmenterRegionGrowingSegment *const nSegPtr)
Add a pointer of a neighbor segment (if it is not already there).
#define BAATZ_ST(featPtr, bandsNmb, band)
#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...
Definition: Macros.h:183
bool initializeSegments(SegmenterIdsManager &segmenterIdsManager, const te::rp::SegmenterSegmentsBlock &block2ProcessInfo, const te::rst::Raster &inputRaster, const std::vector< unsigned int > &inputRasterBands, const std::vector< double > &inputRasterNoDataValues, const std::vector< double > &inputRasterBandMinValues, const std::vector< double > &inputRasterBandMaxValues, SegmenterRegionGrowingSegment **actSegsListHeadPtr)
Initialize the segment objects container and the segment IDs container.
Raster segmenter strategy factory base class.
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...
std::vector< unsigned int > m_rightCutOffProfile
SegmenterRegionGrowingSegmentsPool m_segmentsPool
A pool of segments that can be reused on each strategy execution.
void mergeSegments(const SegmenterRegionGrowingSegment::FeatureType disimilarityThreshold, const unsigned int maxSegSizeThreshold, SegmenterIdsManager &segmenterIdsManager, Merger &merger, const bool enablelocalMutualBestFitting, const bool enableSameIterationMerges, SegmenterRegionGrowingSegment *auxSeg1Ptr, SegmenterRegionGrowingSegment *auxSeg2Ptr, SegmenterRegionGrowingSegment *auxSeg3Ptr, SegmenterRegionGrowingSegment::FeatureType &minFoundDissimilarity, SegmenterRegionGrowingSegment::FeatureType &maxFoundDissimilarity, unsigned int &totalMergesNumber, SegmenterRegionGrowingSegment::IterationCounterType &globalMergeIterationsCounter, SegmenterRegionGrowingSegment **const actSegsListHeadPtrPtr)
Merge closest segments.
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
#define TERP_LOG_AND_THROW(message)
Logs a error message and throws.
Definition: Macros.h:138
unsigned int getColumnsNumber() const
The number of current matrix columns.
Definition: Matrix.h:678
SegmenterRegionGrowingSegment * m_prevActiveSegment
A pointer to the previous active segment.
unsigned short int IterationCounterType
Feature type definition.
Raster segmenter strategy base class.
SegmentFeaturesType m_segmentFeatures
What segment features will be used on the segmentation process (default:InvalidFeaturesType).
double getMemUsageEstimation(const unsigned int bandsToProcess, const unsigned int pixelsNumber) const
Returns a memory estimation (bytes).
void reset()
Clear all internal allocated resources and go back to the initial not-initialized state...
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
SegmenterRegionGrowingSegment * getNextSegment()
Retrive a stored segment.
bool initialize(const SegmenterSegmentsBlock::SegmentIdDataType segsNumber, const unsigned int featuresNumber)
Pool initialization.
te::rp::SegmenterStrategy * build()
Concrete factories (derived from this one) must implement this method in order to create objects...
unsigned int getOptimalBlocksOverlapSize() const
Returns a optimal blocks overlap size (number of border pixels overlapped between blocks...
FeatureType * m_features
A pionter to a fixed size vector of segment features.
SegmenterRegionGrowingSegment ** m_neighborSegments
Neighborhood segments pointers (some pointers can be null) or a null pointer if there is no neighborh...
unsigned int m_size
Segment area (pixels number).
bool initialize(SegmenterStrategyParameters const *const strategyParams)
Initialize the segmentation strategy.
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 - ...
unsigned int getActiveSegmentsNumber(SegmenterRegionGrowingSegment *const actSegsListHeadPtr) const
Returns the number of active segments.
void reset()
Reset (clear) the active instance data.
Definition: Matrix.h:480
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.
Definition: Raster.cpp:228
Abstract parameters base interface.
#define BAATZ_EL(featPtr)
unsigned int m_yStart
Segment upper Y coordinate box over the label image.
unsigned int m_bandsNumber
The number of features (bands).
static Raster * make()
It creates and returns an empty raster with default raster driver.
double m_colorWeight
The weight given to the color component, deafult:0.9, valid range: [0,1].
unsigned int m_segmentsSimIncreaseSteps
The maximum number of steps to increment the similarity threshold value for the cases where no segmen...
#define BAATZ_STSTARTPTR(featPtr, bandsNmb)
const Parameters & operator=(const Parameters &params)
virtual void mergeFeatures(SegmenterRegionGrowingSegment *const segment1Ptr, SegmenterRegionGrowingSegment const *const segment2Ptr, SegmenterRegionGrowingSegment const *const mergePreviewSegPtr) const =0
Merge specific segment features from both segments into the first segment.
Segmenter segments block description class.
void exportSegs2Tif(const SegmentsIdsMatrixT &segmentsIds, bool normto8bits, const std::string &fileName)
Export the segments IDs to a tif file.
double m_compactnessWeight
The weight given to the compactness component, deafult:0.5, valid range: [0,1].
AbstractParameters * clone() const
Create a clone copy of this instance.
void removeNeighborSegment(SegmenterRegionGrowingSegment *const nSegPtr)
Remove all occurrences of a neighbor segment.
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:356
static void getTouchingEdgeLength(const SegmentsIdsMatrixT &segsIds, const unsigned int &xStart, const unsigned int &yStart, const unsigned int &xBound, const unsigned int &yBound, const SegmenterSegmentsBlock::SegmentIdDataType &id1, const SegmenterSegmentsBlock::SegmentIdDataType &id2, unsigned int &edgeLength1, unsigned int &edgeLength2)
Returns the count of points from region 1 (with ID1) touching the region 2 (with ID2).
void addFreeIDs(const std::vector< SegmenterSegmentsBlock::SegmentIdDataType > &ids)
Stores free unique IDs for later use.
A rectified grid is the spatial support for raster data.
Definition: Grid.h:68
std::vector< unsigned int > m_topCutOffProfile
bool m_enableLocalMutualBestFitting
If enabled, a merge only occurs between two segments if the minimum dissimilarity criteria is best fu...
unsigned int getLinesNumber() const
The number of current matrix lines.
Definition: Matrix.h:671
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:149
Raster region growing segmenter strategy.
void clearNeighborSegments()
Remove all neighbor segments.
bool getNewIDs(const unsigned int &idsNumber, std::vector< SegmenterSegmentsBlock::SegmentIdDataType > &ids)
Returns new segment unique IDs.
bool execute(SegmenterIdsManager &segmenterIdsManager, const te::rp::SegmenterSegmentsBlock &block2ProcessInfo, const te::rst::Raster &inputRaster, const std::vector< unsigned int > &inputRasterBands, const std::vector< double > &inputRasterNoDataValues, const std::vector< double > &inputRasterBandMinValues, const std::vector< double > &inputRasterBandMaxValues, te::rst::Raster &outputRaster, const unsigned int outputRasterBand, const bool enableProgressInterface)
Executes the segmentation strategy over region delimited by the given block.
std::vector< unsigned int > m_leftCutOffProfile
SegmenterSegmentsBlock::SegmentIdDataType m_id
Segment ID.
#define BAATZ_SU(featPtr, band)
std::vector< unsigned int > m_bottomCutOffProfile