SegmenterRegionGrowingBaatzMerger.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2015 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/SegmenterRegionGrowingBaatzMerger.cpp
22  \brief Segmenter Baatz merger used in region growing process.
23 */
24 
26 #include "Macros.h"
27 
28 // Baatz Edge Lengh
29 #define BAATZ_EL( featPtr ) featPtr[ 0 ]
30 
31 // Baatz Compactness
32 #define BAATZ_CO( featPtr ) featPtr[ 1 ]
33 
34 // Baatz Smoothness
35 #define BAATZ_SM( featPtr ) featPtr[ 2 ]
36 
37 // Baatz sums
38 #define BAATZ_SU( featPtr, band ) featPtr[ 3 + band ]
39 
40 // Baatz square sums
41 #define BAATZ_SS( featPtr, bandsNmb, band ) featPtr[ 3 + bandsNmb + band ]
42 
43 // Baatz stddev
44 #define BAATZ_ST( featPtr, bandsNmb, band ) featPtr[ 3 + ( 2 * bandsNmb ) + band ]
45 
46 // Baatz stddev start ponter
47 #define BAATZ_STSTARTPTR( featPtr, bandsNmb ) ( featPtr + 3 + ( 2 * bandsNmb ) )
48 
49 namespace te
50 {
51  namespace rp
52  {
54  const double& colorWeight, const double& compactnessWeight,
55  const std::vector< double >& bandsWeights,
56  const SegmentsIdsMatrixT& segmentsIds )
57  :
58  m_segmentsIds( segmentsIds ),
59  m_allSegsCompactnessOffset( 0 ),
60  m_allSegsCompactnessGain( 1.0 ),
61  m_allSegsSmoothnessOffset( 0 ),
62  m_allSegsSmoothnessGain( 0 ),
63  m_colorWeight( (rg::BaatzFeatureType)colorWeight ),
64  m_compactnessWeight( (rg::BaatzFeatureType)compactnessWeight )
65  {
66  m_bandsNumber = (unsigned int)bandsWeights.size();
67 
68  m_bandsWeights.resize( m_bandsNumber, 1 );
69 
70  for( unsigned int band = 0 ; band < m_bandsNumber ; ++band )
71  {
72  m_bandsWeights[ band ] = (rg::BaatzFeatureType)bandsWeights[ band ];
73  }
74  }
75 
77  default;
78 
82  SegmenterRegionGrowingSegment< rg::BaatzFeatureType > * const mergePreviewSegPtr ) const
83  {
84  assert( segment1Ptr );
85  assert( segment1Ptr->m_features );
86  assert( segment2Ptr );
87  assert( segment2Ptr->m_features );
88  assert( mergePreviewSegPtr );
89 
90  // globals
91 
93 
95 
98  mergePreviewSegPtr->m_size = (unsigned int)m_getDissimilarity_sizeUnionD;
99 
100  mergePreviewSegPtr->m_xStart = std::min( segment1Ptr->m_xStart,
101  segment2Ptr->m_xStart );
102  mergePreviewSegPtr->m_yStart = std::min( segment1Ptr->m_yStart,
103  segment2Ptr->m_yStart );
104  mergePreviewSegPtr->m_xBound = std::max( segment1Ptr->m_xBound,
105  segment2Ptr->m_xBound );
106  mergePreviewSegPtr->m_yBound = std::max( segment1Ptr->m_yBound,
107  segment2Ptr->m_yBound );
108 
109  assert( mergePreviewSegPtr->m_xBound > mergePreviewSegPtr->m_xStart );
110  assert( mergePreviewSegPtr->m_yBound > mergePreviewSegPtr->m_yStart );
111 
112  // Finding the form heterogeneity
113 
114  if( m_colorWeight != 1.0 )
115  {
117  m_segmentsIds, mergePreviewSegPtr->m_xStart,
118  mergePreviewSegPtr->m_yStart,
119  mergePreviewSegPtr->m_xBound,
120  mergePreviewSegPtr->m_yBound,
121  segment1Ptr->m_id,
122  segment2Ptr->m_id,
125 
126  BAATZ_EL( mergePreviewSegPtr->m_features ) =
128  +
130 
131  BAATZ_CO( mergePreviewSegPtr->m_features ) = (rg::BaatzFeatureType)(
132  BAATZ_EL( mergePreviewSegPtr->m_features ) /
133  std::sqrt( m_getDissimilarity_sizeUnionD ) );
134 
135  BAATZ_SM( mergePreviewSegPtr->m_features ) =
136  BAATZ_EL( mergePreviewSegPtr->m_features )
137  /
139  (
140  2 * ( mergePreviewSegPtr->m_xBound - mergePreviewSegPtr->m_xStart )
141  )
142  +
143  (
144  2 * ( mergePreviewSegPtr->m_yBound - mergePreviewSegPtr->m_yStart )
145  )
146  );
147 
149  (
150  (
151  (
152  BAATZ_CO( mergePreviewSegPtr->m_features )
153  +
155  )
156  *
158  )
159  -
160  (
161  (
162  (
163  (
164  (
165  BAATZ_CO( segment1Ptr->m_features )
166  +
168  )
169  *
171  )
172  *
174  )
175  +
176  (
177  (
178  (
179  BAATZ_CO( segment2Ptr->m_features )
180  +
182  )
183  *
185  )
186  *
188  )
189  )
190  /
192  )
193  );
194 
196  (
197  (
198  (
199  BAATZ_SM( mergePreviewSegPtr->m_features )
200  +
202  )
203  *
205  )
206  -
207  (
208  (
209  (
210  (
211  (
212  BAATZ_SM( segment1Ptr->m_features )
213  +
215  )
216  *
218  )
219  *
221  )
222  +
223  (
224  (
225  (
226  BAATZ_SM( segment2Ptr->m_features )
227  +
229  )
230  *
232  )
233  *
235  )
236  )
237  /
239  )
240  );
241 
243  (
244  (
246  *
248  )
249  +
250  (
251  ( 1.0f - m_compactnessWeight )
252  *
254  )
255  );
256  }
257 
258  // Finding the color heterogeneity
259 
260  if( m_colorWeight != 0.0 )
261  {
263 
265  {
268  +
270  BAATZ_SU( mergePreviewSegPtr->m_features, m_getDissimilarity_sumsIdx ) =
272 
274  BAATZ_SS( segment1Ptr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx )
275  +
276  BAATZ_SS( segment2Ptr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx );
277  BAATZ_SS( mergePreviewSegPtr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx ) = m_getDissimilarity_squaresSumUnion;
278 
280 
282  std::sqrt(
283  std::max(
285  ,
286  (
287  (
289  -
290  (
292  )
293  +
294  (
296  )
297  )
298  /
300  )
301  )
302  );
303  BAATZ_ST( mergePreviewSegPtr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx ) =
305 
307  (
309  *
310  (
311  (
312  (
314  +
316  )
317  *
319  )
320  -
321  (
322  (
323  (
324  (
325  BAATZ_ST( segment1Ptr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx )
326  +
328  )
329  *
331  )
332  +
333  (
334  (
335  BAATZ_ST( segment2Ptr->m_features, m_bandsNumber, m_getDissimilarity_sumsIdx )
336  +
338  )
339  *
341  )
342  )
343  /
345  )
346  )
347  );
348  }
349  }
350 
352  (
353  (
355  *
357  )
358  +
359  (
360  ( 1.0f - m_colorWeight )
361  *
363  )
364  );
365 
367  }
368 
371  SegmenterRegionGrowingSegment< rg::BaatzFeatureType > const * const segment2Ptr ,
372  SegmenterRegionGrowingSegment< rg::BaatzFeatureType > const * const mergePreviewSegPtr ) const
373  {
374  assert( segment1Ptr );
375  assert( segment1Ptr->m_features );
376  assert( segment2Ptr );
377  assert( segment2Ptr->m_features );
378  assert( mergePreviewSegPtr );
379 
380  // Merging basic features
381 
382  segment1Ptr->m_size = mergePreviewSegPtr->m_size;
383  segment1Ptr->m_xStart = mergePreviewSegPtr->m_xStart;
384  segment1Ptr->m_xBound = mergePreviewSegPtr->m_xBound;
385  segment1Ptr->m_yStart = mergePreviewSegPtr->m_yStart;
386  segment1Ptr->m_yBound = mergePreviewSegPtr->m_yBound;
387 
388  // Merging specific features
389 
390  memcpy( segment1Ptr->m_features, mergePreviewSegPtr->m_features,
392  }
393 
396  {
398  std::numeric_limits< rg::BaatzFeatureType >::max();
399  m_update_compactnessMax = -1.0f *
400  std::numeric_limits< rg::BaatzFeatureType >::max();
401 
403  std::numeric_limits< rg::BaatzFeatureType >::max();
404  m_update_smoothnessMax = -1.0f *
405  std::numeric_limits< rg::BaatzFeatureType >::max();
406 
408  std::numeric_limits< rg::BaatzFeatureType >::max();
409  m_update_stdDevMax = -1.0f *
410  std::numeric_limits< rg::BaatzFeatureType >::max();
411 
412  m_update_currentActSegPtr = actSegsListHeadPtr;
413 
415  {
417 
418  if( m_colorWeight != 1.0 )
419  {
421  {
423  }
425  {
427  }
428 
430  {
432  }
434  {
436  }
437  }
438 
439  if( m_colorWeight != 0.0 )
440  {
442 
444  {
446  {
448  }
450  {
452  }
453  }
454  }
455 
457  }
458 
460  {
462 
463  if( m_update_compactnessMax == 0.0 )
465  else
467  }
468  else
469  {
472  }
473 
475  {
477 
478  if( m_update_smoothnessMax == 0.0 )
480  else
482  }
483  else
484  {
487  }
488 
490  {
491  m_allSegsStdDevOffset = 0.0;
492 
493  if( m_update_stdDevMax == 0.0 )
494  m_allSegsStdDevGain = 1.0;
495  else
497  }
498  else
499  {
502  }
503  }
504 
506  const SegmentsIdsMatrixT& segsIds,
507  const unsigned int& xStart, const unsigned int& yStart,
508  const unsigned int& xBound, const unsigned int& yBound,
511  unsigned int& edgeLength1,
512  unsigned int& edgeLength2 )
513  {
514  const unsigned int colsNumber = segsIds.getColumnsNumber();
515  const unsigned int linesNumber = segsIds.getLinesNumber();
516 
517  TERP_DEBUG_TRUE_OR_THROW( xStart < colsNumber,
518  "Internal Error" )
519  TERP_DEBUG_TRUE_OR_THROW( xBound <= colsNumber,
520  "Internal Error" )
521  TERP_DEBUG_TRUE_OR_THROW( yStart < linesNumber,
522  "Internal Error" )
523  TERP_DEBUG_TRUE_OR_THROW( yBound <= linesNumber,
524  "Internal Error" )
525  TERP_DEBUG_TRUE_OR_THROW( xStart < xBound, "Internal Error" )
526  TERP_DEBUG_TRUE_OR_THROW( yStart < yBound, "Internal Error" )
527 
528  // finding the touching pixels
529 
530  edgeLength1 = 0;
531  edgeLength2 = 0;
532 
533  unsigned int xIdx = 0;
534  const unsigned int lastColIdx = colsNumber - 1;
535  const unsigned int lastLineIdx = linesNumber - 1;
536 
537  for( unsigned int yIdx = yStart ; yIdx < yBound ; ++yIdx )
538  {
539  for( xIdx = xStart; xIdx < xBound ; ++xIdx )
540  {
541  if( segsIds[ yIdx ][ xIdx ] == id1 )
542  {
543  if( yIdx )
544  if( segsIds[ yIdx - 1 ][ xIdx ] == id2 )
545  {
546  ++edgeLength1;
547  continue;
548  }
549  if( xIdx )
550  if( segsIds[ yIdx ][ xIdx - 1 ] == id2 )
551  {
552  ++edgeLength1;
553  continue;
554  }
555  if( yIdx < lastLineIdx)
556  if( segsIds[ yIdx + 1 ][ xIdx ] == id2 )
557  {
558  ++edgeLength1;
559  continue;
560  }
561  if( xIdx < lastColIdx )
562  if( segsIds[ yIdx ][ xIdx + 1 ] == id2 )
563  {
564  ++edgeLength1;
565  continue;
566  }
567  }
568  else if( segsIds[ yIdx ][ xIdx ] == id2 )
569  {
570  if( yIdx )
571  if( segsIds[ yIdx - 1 ][ xIdx ] == id1 )
572  {
573  ++edgeLength2;
574  continue;
575  }
576  if( xIdx )
577  if( segsIds[ yIdx ][ xIdx - 1 ] == id1 )
578  {
579  ++edgeLength2;
580  continue;
581  }
582  if( yIdx < lastLineIdx)
583  if( segsIds[ yIdx + 1 ][ xIdx ] == id1 )
584  {
585  ++edgeLength2;
586  continue;
587  }
588  if( xIdx < lastColIdx )
589  if( segsIds[ yIdx ][ xIdx + 1 ] == id1 )
590  {
591  ++edgeLength2;
592  continue;
593  }
594  }
595  }
596  }
597  }
598  } // end namespace rp
599 } // end namespace te
600 
unsigned int band
unsigned int m_xStart
Segment left X coordinate box over the label image.
std::vector< rg::BaatzFeatureType > m_bandsWeights
A vector where each bands weight are stored.
#define BAATZ_STSTARTPTR(featPtr, bandsNmb)
double DissimilarityTypeT
Type for dissimilarity.
rg::BaatzFeatureType m_colorWeight
The weight given to the color component, deafult:0.5, valid range: [0,1].
bandsWeights
Definition: segmenter.py:6
SegmenterRegionGrowingBaatzMerger(const double &colorWeight, const double &compactnessWeight, const std::vector< double > &bandsWeights, const SegmentsIdsMatrixT &segmentsIds)
Default constructor.
float BaatzFeatureType
Baatz Strategy feature type.
rg::BaatzFeatureType m_allSegsStdDevGain
The gains applied to normalize the standard deviation value.
#define BAATZ_EL(featPtr)
rg::BaatzFeatureType m_compactnessWeight
The weight given to the compactness component, deafult:0.5, valid range: [0,1].
rg::BaatzFeatureType m_allSegsSmoothnessGain
The gains applied to normalize the smoothness value.
#define BAATZ_SU(featPtr, band)
SegmenterRegionGrowingSegment< FeatureDataTypeT > * m_nextActiveSegment
A pointer to the next active segment.
SegmenterRegionGrowingSegment< rg::BaatzFeatureType > * m_update_currentActSegPtr
unsigned int getColumnsNumber() const
The number of current matrix columns.
Definition: Matrix.h:798
rg::BaatzFeatureType m_allSegsStdDevOffset
The offsets applied to normalize the standard deviation value.
URI C++ Library.
Definition: Attributes.h:37
SegmenterSegmentsBlock::SegmentIdDataType m_id
Segment ID.
#define BAATZ_CO(featPtr)
unsigned int m_yStart
Segment upper Y coordinate box over the label image.
DissimilarityTypeT getDissimilarity(SegmenterRegionGrowingSegment< rg::BaatzFeatureType > const *const segment1Ptr, SegmenterRegionGrowingSegment< rg::BaatzFeatureType > const *const segment2Ptr, SegmenterRegionGrowingSegment< rg::BaatzFeatureType > *const mergePreviewSegPtr) const
Returns a dimilarity index between this and the other segment.
rg::BaatzFeatureType m_allSegsCompactnessGain
The gains applied to normalize the compactness value.
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 mergeFeatures(SegmenterRegionGrowingSegment< rg::BaatzFeatureType > *const segment1Ptr, SegmenterRegionGrowingSegment< rg::BaatzFeatureType > const *const segment2Ptr, SegmenterRegionGrowingSegment< rg::BaatzFeatureType > const *const mergePreviewSegPtr) const
Merge specific segment features from both segments into the first segment.
unsigned int m_bandsNumber
The number of features (bands).
#define BAATZ_SM(featPtr)
FeatureType * m_features
A pionter to a fixed size vector of segment features.
unsigned int getSegmentFeaturesSize() const
Return the required segments features vector size (numer of elements).
Segmenter Baatz merger used in region growing process.
const SegmentsIdsMatrixT & m_segmentsIds
A reference to an external valid structure where each all segments IDs are stored.
#define BAATZ_ST(featPtr, bandsNmb, band)
unsigned int m_xBound
Segment lower bound X coordinate box over the label image.
unsigned int m_yBound
Segment lower bound Y coordinate box over the label image.
unsigned int m_size
Segment area (pixels number).
void update(SegmenterRegionGrowingSegment< rg::BaatzFeatureType > *const actSegsListHeadPtr)
Update the internal state.
compactnessWeight
Definition: segmenter.py:6
rg::BaatzFeatureType m_allSegsCompactnessOffset
The offsets applied to normalize the compactness value.
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:400
rg::BaatzFeatureType m_allSegsSmoothnessOffset
The offsets applied to normalize the smoothness value.
#define BAATZ_SS(featPtr, bandsNmb, band)
unsigned int getLinesNumber() const
The number of current matrix lines.
Definition: Matrix.h:791