All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Segmenter.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2009 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/Segmenter.cpp
22  \brief Raster segmentation.
23 */
24 
25 #include "Segmenter.h"
26 
28 #include "Functions.h"
29 #include "Macros.h"
30 
31 #include "../raster/RasterFactory.h"
32 #include "../raster/Band.h"
33 #include "../raster/BandProperty.h"
34 #include "../raster/Raster.h"
35 #include "../raster/Enums.h"
36 #include "../raster/Grid.h"
37 #include "../dataaccess/datasource/DataSource.h"
38 #include "../common/PlatformUtils.h"
39 #include "../common/StringUtils.h"
40 #include "../geometry/Coord2D.h"
41 #include "../datatype/Enums.h"
42 
43 #include <map>
44 #include <memory>
45 #include <climits>
46 #include <cmath>
47 #include <cfloat>
48 
49 namespace te
50 {
51  namespace rp
52  {
54  {
56  reset();
57  }
58 
60  {
61  m_segStratParamsPtr = 0;
62  reset();
63  operator=( other );
64  }
65 
67  {
68  reset();
69  }
70 
71  void Segmenter::InputParameters::reset() throw( te::rp::Exception )
72  {
73  m_inputRasterPtr = 0;
74  m_inputRasterBands.clear();
75  m_enableThreadedProcessing = true;
76  m_maxSegThreads = 0;
77  m_enableBlockProcessing = true;
78  m_enableBlockMerging = true;
79  m_maxBlockSize = 0;
80  m_strategyName.clear();
81  m_enableProgress = false;
82 
83  if( m_segStratParamsPtr )
84  {
85  delete m_segStratParamsPtr;
86  m_segStratParamsPtr = 0;
87  }
88  }
89 
91  const Segmenter::InputParameters& params )
92  {
93  reset();
94 
95  m_inputRasterPtr = params.m_inputRasterPtr;
96  m_inputRasterBands = params.m_inputRasterBands;
97  m_enableThreadedProcessing = params.m_enableThreadedProcessing;
98  m_maxSegThreads = params.m_maxSegThreads;
99  m_enableBlockProcessing = params.m_enableBlockProcessing;
100  m_enableBlockMerging = params.m_enableBlockMerging;
101  m_maxBlockSize = params.m_maxBlockSize;
102  m_strategyName = params.m_strategyName;
103  m_enableProgress = params.m_enableProgress;
104 
105  m_segStratParamsPtr = params.m_segStratParamsPtr ?
107  : 0;
108 
109  return *this;
110  }
111 
113  {
114  return new InputParameters( *this );
115  }
116 
118  const SegmenterStrategyParameters& params )
119  {
120  if( m_segStratParamsPtr )
121  {
122  delete m_segStratParamsPtr;
123  m_segStratParamsPtr = 0;
124  }
125 
126  m_segStratParamsPtr = (SegmenterStrategyParameters*)params.clone();
127  }
128 
131  {
132  return m_segStratParamsPtr;
133  }
134 
136  {
137  reset();
138  }
139 
141  {
142  reset();
143  operator=( other );
144  }
145 
147  {
148  reset();
149  }
150 
151  void Segmenter::OutputParameters::reset() throw( te::rp::Exception )
152  {
153  m_rType.clear();
154  m_rInfo.clear();
155  m_outputRasterPtr.reset();
156  }
157 
159  const Segmenter::OutputParameters& params )
160  {
161  reset();
162 
163  m_rType = params.m_rType;
164  m_rInfo = params.m_rInfo;
165 
166  return *this;
167  }
168 
170  {
171  return new OutputParameters( *this );
172  }
173 
175  {
176  m_inputParametersPtr = 0;
177  m_outputParametersPtr = 0;
178  m_segsBlocksMatrixPtr = 0;
179  m_generalMutexPtr = 0;
180  m_inputRasterIOMutexPtr = 0;
181  m_outputRasterIOMutexPtr = 0;
182  m_blockProcessedSignalMutexPtr = 0;
183  m_abortSegmentationFlagPtr = 0;
184  m_segmentsIdsManagerPtr = 0;
185  m_blockProcessedSignalPtr = 0;
186  m_runningThreadsCounterPtr = 0;
187  m_inputRasterGainsPtr = 0;
188  m_inputRasterOffsetsPtr = 0;
189  m_enableStrategyProgress = false;
190  m_progressPtr = 0;
191  }
192 
194  {
195  }
196 
198  {
199  m_instanceInitialized = false;
200  }
201 
203  {
204  }
205 
207  throw( te::rp::Exception )
208  {
210  {
211  // creating the output raster
212 
213  Segmenter::OutputParameters* outputParamsPtr = dynamic_cast<
214  Segmenter::OutputParameters* >( &outputParams );
215  TERP_TRUE_OR_RETURN_FALSE( outputParamsPtr, "Invalid parameters" );
216 
217  {
218  std::vector< te::rst::BandProperty* > bandsProperties;
219  bandsProperties.push_back( new te::rst::BandProperty(
222  bandsProperties[ 0 ]->m_colorInterp = te::rst::GrayIdxCInt;
223  bandsProperties[ 0 ]->m_noDataValue = 0;
224  bandsProperties[ 0 ]->m_type = te::dt::UINT32_TYPE;
225 
226  outputParamsPtr->m_outputRasterPtr.reset(
228  outputParamsPtr->m_rType,
230  bandsProperties,
231  outputParamsPtr->m_rInfo,
232  0,
233  0 ) );
234  TERP_TRUE_OR_RETURN_FALSE( outputParamsPtr->m_outputRasterPtr.get(),
235  "Output raster creation error" );
236  }
237 
238  // Finding the input raster normalization parameters
239 
240  std::vector< double > inputRasterGains(
242  std::vector< double > inputRasterOffsets(
244 
245  {
246  const unsigned int nRows =
248  const unsigned int nCols =
250  unsigned int row = 0;
251  unsigned int col = 0;
252  double bandMin = DBL_MAX;
253  double bandMax = -1.0 * DBL_MAX;
254  double value = 0;
255 
256  for( unsigned int inputRasterBandsIdx = 0 ; inputRasterBandsIdx <
257  m_inputParameters.m_inputRasterBands.size() ; ++inputRasterBandsIdx )
258  {
259  const te::rst::Band& band =
261  m_inputParameters.m_inputRasterBands[ inputRasterBandsIdx ] ) );
262  bandMin = DBL_MAX;
263  bandMax = -1.0 * DBL_MAX;
264 
265  for( row = 0 ; row < nRows ; ++row )
266  for( col = 0 ; col < nCols ; ++col )
267  {
268  band.getValue( col, row, value );
269 
270  if( bandMin > value ) bandMin = value;
271  if( bandMax < value ) bandMax = value;
272  }
273 
274  if( bandMax != bandMin )
275  {
276  inputRasterGains[ inputRasterBandsIdx ] = 1.0 / ( bandMax - bandMin );
277  inputRasterOffsets[ inputRasterBandsIdx ] = -1.0 * bandMin;
278  }
279  }
280  }
281 
282  // instantiating the segmentation strategy
283 
284  std::auto_ptr< SegmenterStrategy > strategyPtr(
286  TERP_TRUE_OR_RETURN_FALSE( strategyPtr.get(),
287  "Unable to create an segmentation strategy" );
288  TERP_TRUE_OR_RETURN_FALSE( strategyPtr->initialize(
290  "Unable to initialize the segmentation strategy" );
291 
292  const double stratMemUsageEstimation = strategyPtr->getMemUsageEstimation(
296  TERP_DEBUG_TRUE_OR_THROW( stratMemUsageEstimation > 0.0,
297  "Invalid strategy memory usage factorMemUsageFactor" );
298 
299  const unsigned stratBlocksOverlapSize =
300  strategyPtr->getOptimalBlocksOverlapSize();
301 
302  // defining the number of processing threads
303 
304  unsigned int maxSegThreads = 0;
307  {
308  maxSegThreads = ( m_inputParameters.m_maxSegThreads ?
310  }
311 
312  // Guessing memory limits
313 
314  const unsigned int totalRasterPixels =
317  const double totalPhysMem = (double)te::common::GetTotalPhysicalMemory();
318  const double usedVMem = (double)te::common::GetUsedVirtualMemory();
319  const double totalVMem = ( (double)te::common::GetTotalVirtualMemory() ) /
320  2.0;
321  const double freeVMem = MIN( totalPhysMem,
322  ( ( totalVMem <= usedVMem ) ? 0.0 : ( totalVMem - usedVMem ) ) );
323  const double pixelRequiredRam = stratMemUsageEstimation
324  / ((double)totalRasterPixels);
325  const double maxSimultaneousMemoryPixels = 0.7 * MIN(
326  ((double)totalRasterPixels),
327  freeVMem / pixelRequiredRam );
328 
329  // Calc the maximum block width & height
330 
331  unsigned int maxNonExpandedBlockWidth = 0;
332  unsigned int maxNonExpandedBlockHeight = 0;
333  unsigned int maxExpandedBlockWidth = 0;
334  unsigned int maxExpandedBlockHeight = 0;
335  unsigned int blocksHOverlapSize = 0;
336  unsigned int blocksVOverlapSize = 0;
337 
339  &&
340  (
341  ( maxSegThreads > 0 )
342  ||
343  ( maxSimultaneousMemoryPixels < ((double)totalRasterPixels ) )
344  ||
345  (
347  &&
348  (
350  <
351  totalRasterPixels
352  )
353  )
354  )
355  )
356  {
357  // Calculating max bock pixels using the avaliable resources or
358  // the user given parameters
359 
360  unsigned int maxBlockPixels = 0;
361 
363  {
364  maxBlockPixels = m_inputParameters.m_maxBlockSize *
366  }
367  else
368  {
369  maxBlockPixels = static_cast<unsigned int>(
370  ( maxSimultaneousMemoryPixels /
371  ( static_cast<double>( maxSegThreads ? maxSegThreads : 1 ) ) ) );
372  }
373 
374  // updating maxBlockPixels considering the blocks overlap size
375 
377  {
378  // Adjusting the block sizes
379 
383  std::max( blocksHOverlapSize, blocksVOverlapSize ) *
384  std::max( blocksHOverlapSize, blocksVOverlapSize ),
385  maxBlockPixels,
386  0.4,
387  0.4,
388  maxNonExpandedBlockWidth,
389  maxNonExpandedBlockHeight,
390  blocksHOverlapSize,
391  blocksVOverlapSize ),
392  "Error calculating best block size" );
393 
394  maxExpandedBlockWidth = maxNonExpandedBlockWidth +
395  blocksHOverlapSize + blocksHOverlapSize;
396  maxExpandedBlockHeight = maxNonExpandedBlockHeight +
397  blocksVOverlapSize + blocksVOverlapSize;
398  }
399  else
400  {
401  // Adjusting the block sizes
402 
403  unsigned int blocksHOverlapSize = 0;
404  unsigned int blocksVOverlapSize = 0;
405 
409  stratBlocksOverlapSize * stratBlocksOverlapSize,
410  maxBlockPixels,
411  0.0,
412  0.0,
413  maxNonExpandedBlockWidth,
414  maxNonExpandedBlockHeight,
415  blocksHOverlapSize,
416  blocksVOverlapSize ),
417  "Error calculating best block size" );
418 
419  maxExpandedBlockWidth = maxNonExpandedBlockWidth;
420  maxExpandedBlockHeight = maxNonExpandedBlockHeight;
421  }
422  }
423  else
424  {
425  maxNonExpandedBlockWidth = maxExpandedBlockWidth =
427  maxNonExpandedBlockHeight = maxExpandedBlockHeight =
429  }
430 
431  // Defining number of blocks
432 
433  const unsigned int hBlocksNumber = (unsigned int)ceil(
435  ((double)maxNonExpandedBlockWidth) );
436  const unsigned int vBlocksNumber = (unsigned int)ceil(
438  ((double)maxNonExpandedBlockHeight ) );
439 
440  // Generating cut off profiles. When possible, an empty profile
441  // vector is generated
442 
443  std::vector< std::vector< unsigned int> > imageHorizontalProfiles;
444  std::vector< unsigned int > imageHorizontalProfilesCenterLines;
445  std::vector< std::vector< unsigned int> > imageVerticalProfiles;
446  std::vector< unsigned int > imageVerticalProfilesCenterLines;
447 
450  {
451 // std::cout << std::endl << "Starting CutOff profiles generation" << std::endl;
452 
453  const unsigned int tileHNeighborhoodSize = blocksHOverlapSize / 2;
454  const unsigned int tileVNeighborhoodSize = blocksVOverlapSize / 2;
455  const unsigned int pixelNeighborhoodSize = 5;
456  const unsigned int profileAntiSmoothingFactor = 3;
457 
458  std::vector< unsigned int> profile;
459  unsigned int profileIdx = 0;
460 
461  for( profileIdx = 1 ; profileIdx < hBlocksNumber ;
462  ++profileIdx )
463  {
464  profile.clear();
465 
466  const unsigned int centerLine = ( ( profileIdx ) *
467  maxNonExpandedBlockHeight );
468  imageHorizontalProfilesCenterLines.push_back( centerLine );
469 
470  if( genImageHCutOffProfile( centerLine,
472  pixelNeighborhoodSize, tileHNeighborhoodSize,
473  profileAntiSmoothingFactor, profile ) )
474  {
475  imageHorizontalProfiles.push_back( profile );
476  }
477  else
478  {
479  imageHorizontalProfiles.push_back( std::vector< unsigned int>() );
480  }
481  }
482 
483  for( profileIdx = 1 ; profileIdx < vBlocksNumber ;
484  ++profileIdx )
485  {
486  profile.clear();
487 
488  const unsigned int centerLine = ( ( profileIdx ) *
489  maxNonExpandedBlockWidth );
490  imageVerticalProfilesCenterLines.push_back( centerLine );
491 
492  if( genImageVCutOffProfile( centerLine,
494  pixelNeighborhoodSize, tileVNeighborhoodSize,
495  profileAntiSmoothingFactor, profile ) )
496  {
497  imageVerticalProfiles.push_back( profile );
498  }
499  else
500  {
501  imageVerticalProfiles.push_back( std::vector< unsigned int>() );
502  }
503  }
504 /*
505  TERP_TRUE_OR_THROW( createCutOffLinesTiff( imageHorizontalProfiles,
506  imageHorizontalProfilesCenterLines,
507  imageVerticalProfiles, imageVerticalProfilesCenterLines,
508  "cutoflines.tif" ), "internal error" )
509 */
510 
511 // std::cout << std::endl << "CutOff profiles generated" << std::endl;
512  }
513 
514  // Initializing the segments blocks matrix
515 
516  SegmentsBlocksMatrixT segmentsblocksMatrix;
517  segmentsblocksMatrix.reset( SegmentsBlocksMatrixT::RAMMemPol );
518 
519  {
520  TERP_TRUE_OR_RETURN_FALSE( segmentsblocksMatrix.reset( vBlocksNumber,
521  hBlocksNumber ), "Blocks matrix reset error" );
522 
523  const int linesBound = (int)
525  const int colsBound = (int)
527  int blockXBound = 0;
528  int blockYBound = 0;
529  int blockXStart = 0;
530  int blockYStart = 0;
531 
532  for( unsigned int segmentsMatrixLine = 0 ; segmentsMatrixLine <
533  segmentsblocksMatrix.getLinesNumber() ; ++segmentsMatrixLine )
534  {
535  for( unsigned int segmentsMatrixCol = 0 ; segmentsMatrixCol <
536  segmentsblocksMatrix.getColumnsNumber() ; ++segmentsMatrixCol )
537  {
538  SegmenterSegmentsBlock& segmentsBlock = segmentsblocksMatrix(
539  segmentsMatrixLine, segmentsMatrixCol );
540 
541  blockXStart = ((int)( segmentsMatrixCol *
542  maxNonExpandedBlockWidth ) ) - ((int)blocksHOverlapSize );
543  blockYStart = ((int)( segmentsMatrixLine *
544  maxNonExpandedBlockHeight ) ) - ((int)blocksVOverlapSize );
545  blockXBound = blockXStart + ((int)maxExpandedBlockWidth);
546  blockYBound = blockYStart + ((int)maxExpandedBlockHeight);
547 
548  segmentsBlock.m_status =
550  segmentsBlock.m_startX = (unsigned int)MAX( 0, blockXStart );
551  segmentsBlock.m_startY = (unsigned int)MAX( 0, blockYStart );
552 
553  segmentsBlock.m_width = ((unsigned int)MIN( blockXBound,
554  colsBound ) ) - segmentsBlock.m_startX;
555  segmentsBlock.m_height = ((unsigned int)MIN( blockYBound,
556  linesBound ) ) - segmentsBlock.m_startY;
557 
558  segmentsBlock.m_segmentsMatrixXIndex = segmentsMatrixCol;
559  segmentsBlock.m_segmentsMatrixYIndex = segmentsMatrixLine;
560 
561  // transfering cutoff profiles
562 
565  {
567  imageHorizontalProfiles, imageVerticalProfiles,
568  segmentsBlock ), "Block cutOff profiles update error" );
569  }
570  }
571  }
572  }
573 
574  // Starting the segmentation
575 
576  boost::mutex generalMutex;
577  boost::mutex inputRasterIOMutex;
578  boost::mutex outputRasterIOMutex;
579  boost::mutex blockProcessedSignalMutex;
580 
581  volatile bool abortSegmentationFlag = false;
582 
583  SegmenterIdsManager segmenterIdsManager;
584 
585  boost::condition_variable blockProcessedSignal;
586 
587  volatile unsigned int runningThreadsCounter = 0;
588 
589  std::auto_ptr< te::common::TaskProgress > progressPtr;
591  ( ( vBlocksNumber * hBlocksNumber ) > 1 ) )
592  {
593  progressPtr.reset( new te::common::TaskProgress );
594  progressPtr->setTotalSteps( vBlocksNumber * hBlocksNumber );
595  progressPtr->setMessage( "Segmentation" );
596  }
597 
598  SegmenterThreadEntryParams segmenterThreadEntryParams;
599  segmenterThreadEntryParams.m_inputParametersPtr = &m_inputParameters;
600  segmenterThreadEntryParams.m_outputParametersPtr = outputParamsPtr;
601  segmenterThreadEntryParams.m_segsBlocksMatrixPtr = &segmentsblocksMatrix;
602  segmenterThreadEntryParams.m_generalMutexPtr = &generalMutex;
603  segmenterThreadEntryParams.m_inputRasterIOMutexPtr =
604  &inputRasterIOMutex;
605  segmenterThreadEntryParams.m_outputRasterIOMutexPtr =
606  &outputRasterIOMutex;
607  segmenterThreadEntryParams.m_blockProcessedSignalMutexPtr =
608  &blockProcessedSignalMutex;
609  segmenterThreadEntryParams.m_abortSegmentationFlagPtr = &abortSegmentationFlag;
610  segmenterThreadEntryParams.m_segmentsIdsManagerPtr = &segmenterIdsManager;
611  segmenterThreadEntryParams.m_blockProcessedSignalPtr = &blockProcessedSignal;
612  segmenterThreadEntryParams.m_runningThreadsCounterPtr =
613  &runningThreadsCounter;
614  segmenterThreadEntryParams.m_inputRasterGainsPtr = &inputRasterGains;
615  segmenterThreadEntryParams.m_inputRasterOffsetsPtr = &inputRasterOffsets;
616  segmenterThreadEntryParams.m_enableStrategyProgress = m_inputParameters.m_enableProgress &&
617  ( ( vBlocksNumber * hBlocksNumber ) == 1 );
618  segmenterThreadEntryParams.m_progressPtr = maxSegThreads ? 0 : progressPtr.get();
619 
620  if( maxSegThreads )
621  { // threaded segmentation mode
622 
623  // spawning the segmentation threads
624 
625  runningThreadsCounter = maxSegThreads;
626 
627  boost::thread_group threads;
628 
629  for( unsigned int threadIdx = 0 ; threadIdx < maxSegThreads ;
630  ++threadIdx )
631  {
632  threads.add_thread( new boost::thread( segmenterThreadEntry,
633  &segmenterThreadEntryParams ) );
634  };
635 
636  // waiting all threads to finish
637 
638  while( (!abortSegmentationFlag) && (runningThreadsCounter > 0 ) )
639  {
640  boost::unique_lock<boost::mutex> lock( blockProcessedSignalMutex );
641  blockProcessedSignal.timed_wait( lock,
642  boost::posix_time::seconds( 1 ) );
643 
644  if( progressPtr.get() )
645  {
646  int segmentedBlocksNmb = 0;
647  for( unsigned int segmentsMatrixLine = 0 ; segmentsMatrixLine <
648  segmentsblocksMatrix.getLinesNumber() ; ++segmentsMatrixLine )
649  {
650  for( unsigned int segmentsMatrixCol = 0 ; segmentsMatrixCol <
651  segmentsblocksMatrix.getColumnsNumber() ; ++segmentsMatrixCol )
652  {
653  if( segmentsblocksMatrix[ segmentsMatrixLine ][ segmentsMatrixCol ].m_status
655  {
656  ++segmentedBlocksNmb;
657  }
658  }
659  }
660 
661  if( segmentedBlocksNmb != progressPtr->getCurrentStep() )
662  {
663  progressPtr->pulse();
664  }
665 
666  if( ! progressPtr->isActive() )
667  {
668  abortSegmentationFlag = true;
669  }
670  }
671 
672 // globalMutex.lock();
673 // std::cout << std::endl << "Waiting threads..." << std::endl;
674 // globalMutex.unlock();
675  }
676 
677  // joining all threads
678 
679  threads.join_all();
680 /*
681  globalMutex.lock();
682  std::cout << std::endl << "Threads joined." << std::endl;
683  globalMutex.unlock();
684 */
685  }
686  else
687  { // non-threaded segmentation mode
688  runningThreadsCounter = 1;
689  segmenterThreadEntry( &segmenterThreadEntryParams );
690  }
691 
692  return (!abortSegmentationFlag);
693  }
694  else
695  {
696  return false;
697  }
698  }
699 
700  void Segmenter::reset() throw( te::rp::Exception )
701  {
702  m_instanceInitialized = false;
704  }
705 
707  throw( te::rp::Exception )
708  {
709  reset();
710 
711  Segmenter::InputParameters const* inputParamsPtr = dynamic_cast<
712  Segmenter::InputParameters const* >( &inputParams );
713 
714  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr, "Invalid parameters" );
716  "Invalid raster pointer" );
719  "Invalid raster" );
720 
721  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_inputRasterBands.size() > 0,
722  "Invalid raster bands number" );
723 
724  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
725  inputParamsPtr->m_inputRasterBands.size() ; ++inRasterBandsIdx )
726  {
728  inputParamsPtr->m_inputRasterBands[ inRasterBandsIdx ] <
729  inputParamsPtr->m_inputRasterPtr->getNumberOfBands(),
730  "Invalid raster bands" );
731  }
732 
733  m_inputParameters = *inputParamsPtr;
734  m_instanceInitialized = true;
735 
736  return true;
737  }
738 
740  {
741  return m_instanceInitialized;
742  }
743 
745  const unsigned int totalImageLines,
746  const unsigned int totalImageCols,
747  const unsigned int minBlockPixels,
748  const unsigned int maxBlockPixels,
749  const double blocksHOverlapSizePercent,
750  const double blocksVOverlapSizePectent,
751  unsigned int& blockWidth,
752  unsigned int& blockHeight,
753  unsigned int& blocksHOverlapSize,
754  unsigned int& blocksVOverlapSize ) const
755  {
756  if( minBlockPixels > maxBlockPixels ) return false;
757 
758  const double rasterRCFactor = ((double)totalImageLines) /
759  ((double)totalImageCols);
760 
761  const double minRasterLinesNmb = sqrt( ((double)minBlockPixels) *
762  rasterRCFactor );
763 
764  const double maxScaleFactor = ((double)totalImageLines) /
765  minRasterLinesNmb;
766 
767  unsigned int rescaledAndExtendedBlockPixelsNmb = 0;
768 
769  for( double scaleFactor = 1.0 ; scaleFactor <= maxScaleFactor ;
770  scaleFactor += 1.0 )
771  {
772  blockHeight = (unsigned int)std::ceil( ((double)totalImageLines) / scaleFactor );
773  blockWidth = (unsigned int)std::ceil( ((double)totalImageCols) / scaleFactor );
774 
775  blocksHOverlapSize = (unsigned int)( blocksHOverlapSizePercent * ((double)blockWidth) );
776  blocksVOverlapSize = (unsigned int)( blocksVOverlapSizePectent * ((double)blockHeight) );
777 
778  rescaledAndExtendedBlockPixelsNmb = ( blockHeight + blocksVOverlapSize +
779  blocksVOverlapSize ) * ( blockWidth + blocksHOverlapSize + blocksHOverlapSize );
780 
781  if( rescaledAndExtendedBlockPixelsNmb <= maxBlockPixels )
782  {
783  return true;
784  }
785  }
786 
787  return false;
788  }
789 
791  {
792  TERP_DEBUG_TRUE_OR_THROW( paramsPtr, "Invalid pointer" );
794  "Invalid pointer" );
796  "Invalid pointer" );
798  "Invalid pointer" );
800  "Invalid pointer" );
802  "Invalid pointer" );
804  "Invalid pointer" );
806  "Invalid pointer" );
808  "Invalid pointer" );
810  "Invalid pointer" );
812  "Invalid pointer" );
814  "Invalid pointer" );
816  "Invalid pointer" );
818  "Invalid pointer" );
819 
820  // Creating the segmentation strategy instance
821 
822  boost::shared_ptr< SegmenterStrategy > strategyPtr(
824  paramsPtr->m_inputParametersPtr->m_strategyName ) );
825  TERP_TRUE_OR_THROW( strategyPtr.get(),
826  "Unable to create an segmentation strategy" );
827  if( ! strategyPtr->initialize(
829  {
830  paramsPtr->m_generalMutexPtr->lock();
831 
832  *(paramsPtr->m_runningThreadsCounterPtr) =
833  *(paramsPtr->m_runningThreadsCounterPtr) - 1;
834  *(paramsPtr->m_abortSegmentationFlagPtr) = true;
835 
836 // std::cout << std::endl<< "Thread exit (error)"
837 // << std::endl;
838 
839  paramsPtr->m_generalMutexPtr->unlock();
840 
841  return;
842  }
843 
844  // Looking for a non processed segments block
845 
846  std::auto_ptr< te::rst::Raster > tempInRasterPtr;
847  std::auto_ptr< te::rst::Raster > tempOutRasterPtr;
848 
849  te::rst::Raster const* currentInRasterPtr = 0;
850  te::rst::Raster* currentOutRasterPtr = 0;
851 
852  std::vector< unsigned int > currentInRasterBands;
853  unsigned int currentOutRasterBand = 0;
854 
855  for( unsigned int sBMLine = 0 ; sBMLine <
856  paramsPtr->m_segsBlocksMatrixPtr->getLinesNumber() ; ++sBMLine )
857  {
858  for( unsigned int sBMCol = 0 ; sBMCol <
859  paramsPtr->m_segsBlocksMatrixPtr->getColumnsNumber() ; ++sBMCol )
860  {
861  if( *(paramsPtr->m_abortSegmentationFlagPtr) )
862  {
863  paramsPtr->m_generalMutexPtr->lock();
864 
865  *(paramsPtr->m_runningThreadsCounterPtr) =
866  *(paramsPtr->m_runningThreadsCounterPtr) - 1;
867 
868 // std::cout << std::endl<< "Thread exit (error)"
869 // << std::endl;
870 
871  paramsPtr->m_generalMutexPtr->unlock();
872 
873  return;
874  }
875  else
876  {
877  paramsPtr->m_generalMutexPtr->lock();
878 
879  SegmenterSegmentsBlock& segsBlk =
880  paramsPtr->m_segsBlocksMatrixPtr->operator()( sBMLine, sBMCol );
881 
883  {
885 /*
886  std::cout << std::endl<< "Start block processing [" +
887  te::common::Convert2String( sBMCol ) + "," +
888  te::common::Convert2String( sBMLine ) + "]"
889  << std::endl;
890 */
891  paramsPtr->m_generalMutexPtr->unlock();
892 
893  // Defining the current input and output rasters
894 
896  {
897  // Defining the current input raster
898 
899  if( ( currentInRasterPtr == 0 ) ||
900  ( currentInRasterPtr->getNumberOfColumns() != segsBlk.m_width ) ||
901  ( currentInRasterPtr->getNumberOfRows() != segsBlk.m_height ) )
902  {
903  paramsPtr->m_inputRasterIOMutexPtr->lock();
904 
905  // Creating a new temporary input raster
906 
907  std::vector< te::rst::BandProperty* > newInBandProperties;
908 
909  for( unsigned int inRasterBandsIdx = 0; inRasterBandsIdx <
910  paramsPtr->m_inputParametersPtr->m_inputRasterBands.size() ;
911  ++inRasterBandsIdx )
912  {
913  newInBandProperties.push_back( new te::rst::BandProperty(
914  *(paramsPtr->m_inputParametersPtr->m_inputRasterPtr->operator[](
915  inRasterBandsIdx ).getProperty() ) ) );
916  }
917 
918  te::rst::Grid const* oldGridPtr =
920  te::gm::Coord2D newULC( oldGridPtr->gridToGeo( ((double)
921  segsBlk.m_startX) - 0.5, ((double)segsBlk.m_startY )-0.5 ) );
922 
923  std::map< std::string, std::string > rInfo;
924 
925  tempInRasterPtr.reset(
927  segsBlk.m_width, segsBlk.m_height,
928  oldGridPtr->getResolutionX(),
929  oldGridPtr->getResolutionY(),
930  &newULC, oldGridPtr->getSRID() ),
931  newInBandProperties, rInfo ) );
932 
933  if( tempInRasterPtr.get() == 0 )
934  {
935  paramsPtr->m_inputRasterIOMutexPtr->unlock();
936 
937  paramsPtr->m_generalMutexPtr->lock();
938 
939  --( *(paramsPtr->m_runningThreadsCounterPtr) );
940  *(paramsPtr->m_abortSegmentationFlagPtr) = true;
941 
942 // std::cout << std::endl<< "Thread exit (error)"
943 // << std::endl;
944 
945  paramsPtr->m_generalMutexPtr->unlock();
946 
947  return;
948  }
949 
950  currentInRasterPtr = tempInRasterPtr.get();
951 
952  currentInRasterBands.clear();
953 
954  for( unsigned int inRasterBandsIdx = 0; inRasterBandsIdx <
955  paramsPtr->m_inputParametersPtr->m_inputRasterBands.size() ;
956  ++inRasterBandsIdx )
957  {
958  currentInRasterBands.push_back( inRasterBandsIdx );
959  }
960 
961  paramsPtr->m_inputRasterIOMutexPtr->unlock();
962  }
963 
964  // loading data
965 
966  {
967  paramsPtr->m_inputRasterIOMutexPtr->lock();
968 
969  unsigned int blkY = 0;
970  unsigned int blkX = 0;
971  unsigned int rasterY = 0;
972  te::rst::Band const* inBandPtr = 0;
973  te::rst::Band* outBandPtr = 0;
974  double value = 0;
975 
976  for( unsigned int inRasterBandsIdx = 0; inRasterBandsIdx <
977  paramsPtr->m_inputParametersPtr->m_inputRasterBands.size() ;
978  ++inRasterBandsIdx )
979  {
980  inBandPtr =
983  inRasterBandsIdx ] );
984  outBandPtr =
985  tempInRasterPtr->getBand( inRasterBandsIdx );
986 
987  for( blkY = 0 ; blkY < segsBlk.m_height ; ++blkY )
988  {
989  rasterY = blkY + segsBlk.m_startY;
990 
991  for( blkX = 0 ; blkX < segsBlk.m_width ; ++blkX )
992  {
993  inBandPtr->getValue( blkX + segsBlk.m_startX,
994  rasterY, value );
995  outBandPtr->setValue( blkX, blkY, value );
996  }
997  }
998  }
999 
1000  paramsPtr->m_inputRasterIOMutexPtr->unlock();
1001  }
1002 
1003  // Creating a new temporary output raster
1004 
1005  if( ( currentOutRasterPtr == 0 ) ||
1006  ( currentOutRasterPtr->getNumberOfColumns() != segsBlk.m_width ) ||
1007  ( currentOutRasterPtr->getNumberOfRows() != segsBlk.m_height ) )
1008  {
1009  paramsPtr->m_inputRasterIOMutexPtr->lock();
1010 
1011  te::rst::BandProperty* newBandPropertyPtr =
1013  newBandPropertyPtr->m_colorInterp = te::rst::GrayIdxCInt;
1014  newBandPropertyPtr->m_noDataValue = 0;
1015 
1016  std::vector< te::rst::BandProperty* > newBandProperties;
1017  newBandProperties.push_back( newBandPropertyPtr );
1018 
1019  te::rst::Grid const* oldGridPtr =
1021  te::gm::Coord2D newULC( oldGridPtr->gridToGeo( ((double)
1022  segsBlk.m_startX) - 0.5, ((double)segsBlk.m_startY )-0.5 ) );
1023 
1024  std::map< std::string, std::string > rInfo;
1025 
1026  tempOutRasterPtr.reset(
1028  segsBlk.m_width, segsBlk.m_height,
1029  oldGridPtr->getResolutionX(),
1030  oldGridPtr->getResolutionY(),
1031  &newULC, oldGridPtr->getSRID() ),
1032  newBandProperties, rInfo ) );
1033 
1034  if( tempOutRasterPtr.get() == 0 )
1035  {
1036  paramsPtr->m_inputRasterIOMutexPtr->unlock();
1037 
1038  paramsPtr->m_generalMutexPtr->lock();
1039 
1040  --( *(paramsPtr->m_runningThreadsCounterPtr) );
1041  *(paramsPtr->m_abortSegmentationFlagPtr) = true;
1042 
1043 // std::cout << std::endl<< "Thread exit (error)"
1044 // << std::endl;
1045 
1046  paramsPtr->m_generalMutexPtr->unlock();
1047 
1048  return;
1049  }
1050 
1051  paramsPtr->m_inputRasterIOMutexPtr->unlock();
1052 
1053  currentOutRasterPtr = tempOutRasterPtr.get();
1054  currentOutRasterBand = 0;
1055  }
1056  }
1057  else
1058  {
1059  currentInRasterPtr = paramsPtr->m_inputParametersPtr->m_inputRasterPtr;
1060  currentOutRasterPtr = paramsPtr->m_outputParametersPtr->m_outputRasterPtr.get();
1061  currentInRasterBands = paramsPtr->m_inputParametersPtr->m_inputRasterBands;
1062  currentOutRasterBand = 0;
1063  }
1064 
1065 
1066  // Executing the strategy
1067 
1068  if( ! strategyPtr->execute(
1069  *paramsPtr->m_segmentsIdsManagerPtr,
1070  *currentInRasterPtr, currentInRasterBands,
1071  *paramsPtr->m_inputRasterGainsPtr,
1072  *paramsPtr->m_inputRasterOffsetsPtr,
1073  *currentOutRasterPtr, currentOutRasterBand,
1074  paramsPtr->m_enableStrategyProgress ) )
1075  {
1076  paramsPtr->m_generalMutexPtr->lock();
1077 
1078  *(paramsPtr->m_runningThreadsCounterPtr) =
1079  *(paramsPtr->m_runningThreadsCounterPtr) - 1;
1080  *(paramsPtr->m_abortSegmentationFlagPtr) = true;
1081 
1082 // std::cout << std::endl<< "Thread exit (error)"
1083 // << std::endl;
1084 
1085  paramsPtr->m_generalMutexPtr->unlock();
1086 
1087  return;
1088  }
1089 
1090  // flushing data if needed
1091 
1093  {
1094  paramsPtr->m_outputRasterIOMutexPtr->lock();
1095 
1096  unsigned int blkY = 0;
1097  unsigned int blkX = 0;
1098  unsigned int rasterY = 0;
1099  te::rst::Band& inBand = *( tempOutRasterPtr->getBand(0) );
1100  te::rst::Band& outBand =
1101  *( paramsPtr->m_outputParametersPtr->m_outputRasterPtr->getBand(
1102  0 ) );
1103  double value = 0;
1104 
1105  if( paramsPtr->m_inputParametersPtr->m_enableBlockMerging )
1106  {
1107  const bool hasTopCutOffProfile =
1108  ! segsBlk.m_topCutOffProfile.empty();
1109  const bool hasBottomCutOffProfile =
1110  ! segsBlk.m_bottomCutOffProfile.empty();
1111  const bool hasLeftCutOffProfile =
1112  ! segsBlk.m_leftCutOffProfile.empty();
1113  const bool hasRightCutOffProfile =
1114  ! segsBlk.m_rightCutOffProfile.empty();
1115  bool isDummyPixel = false;
1116 
1117 
1118  for( blkY = 0 ; blkY < segsBlk.m_height ; ++blkY )
1119  {
1120  rasterY = blkY + segsBlk.m_startY;
1121 
1122  for( blkX = 0 ; blkX < segsBlk.m_width ; ++blkX )
1123  {
1124  isDummyPixel = false;
1125 
1126  if( hasTopCutOffProfile )
1127  {
1128  if( segsBlk.m_topCutOffProfile[ blkX ] > blkY )
1129  {
1130  isDummyPixel = true;
1131  }
1132  }
1133  if( hasBottomCutOffProfile )
1134  {
1135  if( segsBlk.m_bottomCutOffProfile[ blkX ] < blkY )
1136  {
1137  isDummyPixel = true;
1138  }
1139  }
1140  if( hasLeftCutOffProfile )
1141  {
1142  if( segsBlk.m_leftCutOffProfile[ blkY ] > blkX )
1143  {
1144  isDummyPixel = true;
1145  }
1146  }
1147  if( hasRightCutOffProfile )
1148  {
1149  if( segsBlk.m_rightCutOffProfile[ blkY ] < blkX )
1150  {
1151  isDummyPixel = true;
1152  }
1153  }
1154 
1155  if( !isDummyPixel )
1156  {
1157  inBand.getValue( blkX, blkY, value );
1158  outBand.setValue( blkX + segsBlk.m_startX,
1159  rasterY, value );
1160  }
1161  }
1162  }
1163  }
1164  else
1165  {
1166  for( blkY = 0 ; blkY < segsBlk.m_height ; ++blkY )
1167  {
1168  rasterY = blkY + segsBlk.m_startY;
1169 
1170  for( blkX = 0 ; blkX < segsBlk.m_width ; ++blkX )
1171  {
1172  inBand.getValue( blkX, blkY, value );
1173  outBand.setValue( blkX + segsBlk.m_startX,
1174  rasterY, value );
1175  }
1176  }
1177  }
1178 
1179  paramsPtr->m_outputRasterIOMutexPtr->unlock();
1180  }
1181 
1182  // updating block status
1183 
1184  paramsPtr->m_generalMutexPtr->lock();
1185 
1187 /*
1188  std::cout << std::endl<< "Block processed [" +
1189  te::common::Convert2String( sBMCol ) + "," +
1190  te::common::Convert2String( sBMLine ) + "]"
1191  << std::endl;
1192 */
1193  paramsPtr->m_generalMutexPtr->unlock();
1194 
1195  // pulsing the progress
1196 
1197  if( paramsPtr->m_progressPtr )
1198  {
1199  paramsPtr->m_generalMutexPtr->lock();
1200 
1201  if( paramsPtr->m_progressPtr->isActive() )
1202  {
1203  paramsPtr->m_progressPtr->pulse();
1204  paramsPtr->m_generalMutexPtr->unlock();
1205  }
1206  else
1207  {
1208  --( *(paramsPtr->m_runningThreadsCounterPtr) );
1209  *(paramsPtr->m_abortSegmentationFlagPtr) = true;
1210 
1211 // std::cout << std::endl<< "Thread exit (error)"
1212 // << std::endl;
1213 
1214  paramsPtr->m_generalMutexPtr->unlock();
1215 
1216  return;
1217  }
1218  }
1219 
1220  // notifying the main thread with the block processed signal
1221 
1222  boost::lock_guard<boost::mutex> blockProcessedSignalLockGuard(
1223  *( paramsPtr->m_blockProcessedSignalMutexPtr) );
1224 
1225  paramsPtr->m_blockProcessedSignalPtr->notify_one();
1226 
1227  }
1228  else
1229  {
1230  paramsPtr->m_generalMutexPtr->unlock();
1231  }
1232  }
1233  }
1234  }
1235 
1236  // ending tasks
1237 
1238  paramsPtr->m_generalMutexPtr->lock();
1239 
1240  *(paramsPtr->m_runningThreadsCounterPtr) =
1241  *(paramsPtr->m_runningThreadsCounterPtr) - 1;
1242 
1243 // std::cout << std::endl<< "Thread exit (OK)"
1244 // << std::endl;
1245 
1246  paramsPtr->m_generalMutexPtr->unlock();
1247  }
1248 
1249  bool Segmenter::genImageHCutOffProfile( const unsigned int profileCenter,
1250  const te::rst::Raster& inRaster,
1251  const std::vector< unsigned int >& inRasterBands,
1252  const unsigned int pixelNeighborhoodSize,
1253  const unsigned int tileNeighborhoodSize,
1254  const unsigned int profileAntiSmoothingFactor,
1255  std::vector< unsigned int>& profile ) const
1256  {
1257  TERP_DEBUG_TRUE_OR_THROW( profileAntiSmoothingFactor,
1258  "Invalid parameter" )
1259 
1260  profile.clear();
1261 
1262  if( tileNeighborhoodSize < pixelNeighborhoodSize ) return false;
1263 
1264  const int inRasterRowsNmb = (int)inRaster.getNumberOfRows();
1265  const int inRasterColsNmb = (int)inRaster.getNumberOfColumns();
1266  const int inRasterBandsSize = (int)inRasterBands.size();
1267 
1268  // Calculating the tiles buffer dimension
1269 
1270  const int tilesBufferStartIdx = MAX( 0, MIN( inRasterRowsNmb - 1,
1271  ((int)profileCenter) - ((int)tileNeighborhoodSize) ) );
1272  const int tilesBufferBoundIdx = MAX( 0, MIN( inRasterRowsNmb,
1273  1 + ((int)profileCenter) + ((int)tileNeighborhoodSize) ) );
1274  const int tilesBufferSize = tilesBufferBoundIdx - tilesBufferStartIdx;
1275  if( tilesBufferSize < ( 1 + ( 2 * ( (int)( pixelNeighborhoodSize ) ) ) ) )
1276  return false;
1277 
1278  const int minCrossProfileStartIdx = tilesBufferStartIdx +
1279  (int)pixelNeighborhoodSize;
1280  const int maxCrossProfileBoundIdx = tilesBufferBoundIdx -
1281  (int)pixelNeighborhoodSize;
1282 
1283  int crossProfileIdx = 0;
1284  int crossProfileStartIdx = 0;
1285  int crossProfileBoundIdx = 0;
1286 
1287  int pixelNBStartIdx = 0;
1288  int pixelNBEndIdx = 0;
1289  int pixel1NBIdx = 0;
1290  int pixel2NBIdx = 0;
1291  int pixelNBOffset = 0;
1292 
1293  double diffSum = 0;
1294  double currBandDiffSum = 0;
1295  double higherDiffSum = 0;
1296  int higherDiffSumIdx = 0;
1297 
1298  int inRasterBandsIdx = 0;
1299  unsigned int bandIdx = 0;
1300 
1301  double pixel1Value = 0;
1302  double pixel2Value = 0;
1303 
1304  profile.resize( inRasterColsNmb, 0 );
1305 
1306  for( int profileElementIdx = 0 ; profileElementIdx < inRasterColsNmb ;
1307  ++profileElementIdx )
1308  {
1309  if( profileElementIdx )
1310  {
1311  crossProfileStartIdx = profile[ profileElementIdx - 1 ] -
1312  (int)profileAntiSmoothingFactor;
1313  crossProfileStartIdx = MAX( crossProfileStartIdx,
1314  minCrossProfileStartIdx );
1315 
1316  crossProfileBoundIdx = profile[ profileElementIdx - 1 ] + 1 +
1317  ((int)profileAntiSmoothingFactor);
1318  crossProfileBoundIdx = MIN( crossProfileBoundIdx,
1319  maxCrossProfileBoundIdx );
1320  }
1321  else
1322  {
1323  crossProfileStartIdx = minCrossProfileStartIdx;
1324  crossProfileBoundIdx = maxCrossProfileBoundIdx;
1325  }
1326 
1327  higherDiffSum = 0;
1328  higherDiffSumIdx = crossProfileStartIdx;
1329 
1330  for( crossProfileIdx = crossProfileStartIdx ; crossProfileIdx <
1331  crossProfileBoundIdx ; ++crossProfileIdx )
1332  {
1333  // look for the higher diff using all bands
1334  // within the defined neighborhood
1335 
1336  diffSum = 0;
1337 
1338  for( inRasterBandsIdx = 0 ; inRasterBandsIdx < inRasterBandsSize ;
1339  ++inRasterBandsIdx )
1340  {
1341  bandIdx = inRasterBands[ inRasterBandsIdx ];
1342  TERP_DEBUG_TRUE_OR_THROW( bandIdx < inRaster.getNumberOfBands(),
1343  "Invalid band" )
1344 
1345  pixelNBStartIdx = crossProfileIdx - ( (int)pixelNeighborhoodSize);
1346  pixelNBEndIdx = crossProfileIdx + ( (int)pixelNeighborhoodSize);
1347  currBandDiffSum = 0;
1348 
1349  for( pixelNBOffset = 0 ; pixelNBOffset < ((int)pixelNeighborhoodSize) ;
1350  ++pixelNBOffset )
1351  {
1352  pixel1NBIdx = pixelNBStartIdx + pixelNBOffset;
1353  pixel2NBIdx = pixelNBEndIdx - pixelNBOffset;
1354 
1355  TERP_DEBUG_TRUE_OR_THROW( ( pixel1NBIdx >= 0 ) &&
1356  ( pixel1NBIdx < inRasterRowsNmb ), "Invalid pixel2Idx" )
1357  TERP_DEBUG_TRUE_OR_THROW( ( pixel2NBIdx >= 0 ) &&
1358  ( pixel2NBIdx < inRasterRowsNmb ), "Invalid pixel2Idx" )
1359 
1360  inRaster.getValue( profileElementIdx,
1361  pixel1NBIdx, pixel1Value, bandIdx );
1362  inRaster.getValue( profileElementIdx,
1363  pixel2NBIdx, pixel2Value, bandIdx );
1364 
1365  currBandDiffSum += ABS( pixel1Value - pixel2Value );
1366  }
1367 
1368  diffSum += ( currBandDiffSum / ((double)( pixelNBEndIdx -
1369  pixelNBStartIdx + 1 ) ) );
1370  }
1371 
1372  if( diffSum > higherDiffSum )
1373  {
1374  higherDiffSum = diffSum;
1375  higherDiffSumIdx = crossProfileIdx;
1376  }
1377  }
1378 
1379  profile[ profileElementIdx ] = higherDiffSumIdx;
1380  }
1381 
1382  return true;
1383  }
1384 
1385  bool Segmenter::genImageVCutOffProfile( const unsigned int profileCenter,
1386  const te::rst::Raster& inRaster,
1387  const std::vector< unsigned int >& inRasterBands,
1388  const unsigned int pixelNeighborhoodSize,
1389  const unsigned int tileNeighborhoodSize,
1390  const unsigned int profileAntiSmoothingFactor,
1391  std::vector< unsigned int>& profile ) const
1392  {
1393  TERP_DEBUG_TRUE_OR_THROW( profileAntiSmoothingFactor,
1394  "Invalid parameter" )
1395 
1396  profile.clear();
1397 
1398  if( tileNeighborhoodSize < pixelNeighborhoodSize ) return false;
1399 
1400  const int inRasterRowsNmb = (int)inRaster.getNumberOfRows();
1401  const int inRasterColsNmb = (int)inRaster.getNumberOfColumns();
1402  const int inRasterBandsSize = (int)inRasterBands.size();
1403 
1404  // Calculating the tiles buffer dimension
1405 
1406  const int tilesBufferStartIdx = MAX( 0, MIN( inRasterColsNmb - 1,
1407  ((int)profileCenter) - ((int)tileNeighborhoodSize) ) );
1408  const int tilesBufferBoundIdx = MAX( 0, MIN( inRasterColsNmb,
1409  1 + ((int)profileCenter) + ((int)tileNeighborhoodSize) ) );
1410  const int tilesBufferSize = tilesBufferBoundIdx - tilesBufferStartIdx;
1411  if( tilesBufferSize < ( 1 + ( 2 * ( (int)( pixelNeighborhoodSize ) ) ) ) )
1412  return false;
1413 
1414  const int minCrossProfileStartIdx = tilesBufferStartIdx +
1415  (int)pixelNeighborhoodSize;
1416  const int maxCrossProfileBoundIdx = tilesBufferBoundIdx -
1417  (int)pixelNeighborhoodSize;
1418 
1419  int crossProfileIdx = 0;
1420  int crossProfileStartIdx = 0;
1421  int crossProfileBoundIdx = 0;
1422 
1423  int pixelNBStartIdx = 0;
1424  int pixelNBEndIdx = 0;
1425  int pixel1NBIdx = 0;
1426  int pixel2NBIdx = 0;
1427  int pixelNBOffset = 0;
1428 
1429  double diffSum = 0;
1430  double currBandDiffSum = 0;
1431  double higherDiffSum = 0;
1432  int higherDiffSumIdx = 0;
1433 
1434  int inRasterBandsIdx = 0;
1435  unsigned int bandIdx = 0;
1436 
1437  double pixel1Value = 0;
1438  double pixel2Value = 0;
1439 
1440  profile.resize( inRasterRowsNmb, 0 );
1441 
1442  for( int profileElementIdx = 0 ; profileElementIdx < inRasterRowsNmb ;
1443  ++profileElementIdx )
1444  {
1445  if( profileElementIdx )
1446  {
1447  crossProfileStartIdx = profile[ profileElementIdx - 1 ] -
1448  (int)profileAntiSmoothingFactor;
1449  crossProfileStartIdx = MAX( crossProfileStartIdx,
1450  minCrossProfileStartIdx );
1451 
1452  crossProfileBoundIdx = profile[ profileElementIdx - 1 ] + 1 +
1453  ((int)profileAntiSmoothingFactor);
1454  crossProfileBoundIdx = MIN( crossProfileBoundIdx,
1455  maxCrossProfileBoundIdx );
1456  }
1457  else
1458  {
1459  crossProfileStartIdx = minCrossProfileStartIdx;
1460  crossProfileBoundIdx = maxCrossProfileBoundIdx;
1461  }
1462 
1463  higherDiffSum = 0;
1464  higherDiffSumIdx = crossProfileStartIdx;
1465 
1466  for( crossProfileIdx = crossProfileStartIdx ; crossProfileIdx <
1467  crossProfileBoundIdx ; ++crossProfileIdx )
1468  {
1469  // look for the higher diff using all bands
1470  // within the defined neighborhood
1471 
1472  diffSum = 0;
1473 
1474  for( inRasterBandsIdx = 0 ; inRasterBandsIdx < inRasterBandsSize ;
1475  ++inRasterBandsIdx )
1476  {
1477  bandIdx = inRasterBands[ inRasterBandsIdx ];
1478  TERP_DEBUG_TRUE_OR_THROW( bandIdx < inRaster.getNumberOfBands(),
1479  "Invalid band" )
1480 
1481  pixelNBStartIdx = crossProfileIdx - ( (int)pixelNeighborhoodSize);
1482  pixelNBEndIdx = crossProfileIdx + ( (int)pixelNeighborhoodSize);
1483  currBandDiffSum = 0;
1484 
1485  for( pixelNBOffset = 0 ; pixelNBOffset < ((int)pixelNeighborhoodSize) ;
1486  ++pixelNBOffset )
1487  {
1488  pixel1NBIdx = pixelNBStartIdx + pixelNBOffset;
1489  pixel2NBIdx = pixelNBEndIdx - pixelNBOffset;
1490 
1491  TERP_DEBUG_TRUE_OR_THROW( ( pixel1NBIdx >= 0 ) &&
1492  ( pixel1NBIdx < inRasterColsNmb ), "Invalid pixel2Idx" )
1493  TERP_DEBUG_TRUE_OR_THROW( ( pixel2NBIdx >= 0 ) &&
1494  ( pixel2NBIdx < inRasterColsNmb ), "Invalid pixel2Idx" )
1495 
1496  inRaster.getValue( pixel1NBIdx, profileElementIdx,
1497  pixel1Value, bandIdx );
1498  inRaster.getValue( pixel2NBIdx, profileElementIdx,
1499  pixel2Value, bandIdx );
1500 
1501  currBandDiffSum += ABS( pixel1Value - pixel2Value );
1502  }
1503 
1504  diffSum += ( currBandDiffSum / ((double)( pixelNBEndIdx -
1505  pixelNBStartIdx + 1 ) ) );
1506  }
1507 
1508  if( diffSum > higherDiffSum )
1509  {
1510  higherDiffSum = diffSum;
1511  higherDiffSumIdx = crossProfileIdx;
1512  }
1513  }
1514 
1515  profile[ profileElementIdx ] = higherDiffSumIdx;
1516  }
1517 
1518  return true;
1519  }
1520 
1522  const std::vector< std::vector< unsigned int> >& imageHorizontalProfiles,
1523  const std::vector< std::vector< unsigned int> >& imageVerticalProfiles,
1524  SegmenterSegmentsBlock& segmentsBlock ) const
1525  {
1526  // generating m_topCutOffProfile
1527 
1528  segmentsBlock.m_topCutOffProfile.clear();
1529 
1530  if( ( segmentsBlock.m_segmentsMatrixYIndex > 0 ) &&
1531  ( segmentsBlock.m_segmentsMatrixYIndex <=
1532  imageHorizontalProfiles.size() ) )
1533  {
1534  const std::vector< unsigned int >& profile = imageHorizontalProfiles[
1535  segmentsBlock.m_segmentsMatrixYIndex - 1 ];
1536 
1537  if( ! profile.empty() )
1538  {
1539  segmentsBlock.m_topCutOffProfile.resize( segmentsBlock.m_width );
1540  int profElementValue = 0;
1541 
1542  for( unsigned int profEIdx = 0 ; profEIdx < segmentsBlock.m_width ;
1543  ++profEIdx )
1544  {
1545  TERP_DEBUG_TRUE_OR_THROW( profEIdx + segmentsBlock.m_startX <
1546  profile.size(), "Internal error" )
1547  profElementValue =
1548  ((int)profile[ profEIdx + segmentsBlock.m_startX ]) -
1549  ((int)segmentsBlock.m_startY);
1550  profElementValue = MAX( 0, profElementValue );
1551  profElementValue = MIN( (int)segmentsBlock.m_height, profElementValue );
1552 
1553  segmentsBlock.m_topCutOffProfile[ profEIdx ] = profElementValue;
1554  }
1555  }
1556  }
1557 
1558  // generating m_bottomCutOffProfile
1559 
1560  segmentsBlock.m_bottomCutOffProfile.clear();
1561 
1562  if( segmentsBlock.m_segmentsMatrixYIndex <
1563  imageHorizontalProfiles.size() )
1564  {
1565  const std::vector< unsigned int >& profile = imageHorizontalProfiles[
1566  segmentsBlock.m_segmentsMatrixYIndex ];
1567 
1568  if( ! profile.empty() )
1569  {
1570  segmentsBlock.m_bottomCutOffProfile.resize( segmentsBlock.m_width );
1571  int profElementValue = 0;
1572 
1573  for( unsigned int profEIdx = 0 ; profEIdx < segmentsBlock.m_width ;
1574  ++profEIdx )
1575  {
1576  TERP_DEBUG_TRUE_OR_THROW( profEIdx + segmentsBlock.m_startX <
1577  profile.size(), "Internal error" )
1578  profElementValue =
1579  ((int)profile[ profEIdx + segmentsBlock.m_startX ]) -
1580  ((int)segmentsBlock.m_startY);
1581  profElementValue = MAX( 0, profElementValue );
1582  profElementValue = MIN( (int)segmentsBlock.m_height, profElementValue );
1583 
1584  segmentsBlock.m_bottomCutOffProfile[ profEIdx ] = profElementValue;
1585  }
1586  }
1587  }
1588 
1589  // generating m_leftCutOffProfile
1590 
1591  segmentsBlock.m_leftCutOffProfile.clear();
1592 
1593  if( ( segmentsBlock.m_segmentsMatrixXIndex > 0 ) &&
1594  ( segmentsBlock.m_segmentsMatrixXIndex <=
1595  imageVerticalProfiles.size() ) )
1596  {
1597  const std::vector< unsigned int >& profile = imageVerticalProfiles[
1598  segmentsBlock.m_segmentsMatrixXIndex - 1 ];
1599 
1600  if( ! profile.empty() )
1601  {
1602  segmentsBlock.m_leftCutOffProfile.resize( segmentsBlock.m_height );
1603  int profElementValue = 0;
1604 
1605  for( unsigned int profEIdx = 0 ; profEIdx < segmentsBlock.m_height ;
1606  ++profEIdx )
1607  {
1608  TERP_DEBUG_TRUE_OR_THROW( profEIdx + segmentsBlock.m_startY <
1609  profile.size(), "Internal error" )
1610  profElementValue =
1611  ((int)profile[ profEIdx + segmentsBlock.m_startY ]) -
1612  ((int)segmentsBlock.m_startX);
1613  profElementValue = MAX( 0, profElementValue );
1614  profElementValue = MIN( (int)segmentsBlock.m_width, profElementValue );
1615 
1616  segmentsBlock.m_leftCutOffProfile[ profEIdx ] = profElementValue;
1617  }
1618  }
1619  }
1620 
1621  // generating m_rightCutOffProfile
1622 
1623  segmentsBlock.m_rightCutOffProfile.clear();
1624 
1625  if( segmentsBlock.m_segmentsMatrixXIndex <
1626  imageVerticalProfiles.size() )
1627  {
1628  const std::vector< unsigned int >& profile = imageVerticalProfiles[
1629  segmentsBlock.m_segmentsMatrixXIndex ];
1630 
1631  if( ! profile.empty() )
1632  {
1633  segmentsBlock.m_rightCutOffProfile.resize( segmentsBlock.m_height );
1634  int profElementValue = 0;
1635 
1636  for( unsigned int profEIdx = 0 ; profEIdx < segmentsBlock.m_height ;
1637  ++profEIdx )
1638  {
1639  TERP_DEBUG_TRUE_OR_THROW( profEIdx + segmentsBlock.m_startY <
1640  profile.size(), "Internal error" )
1641  profElementValue =
1642  ((int)profile[ profEIdx + segmentsBlock.m_startY ]) -
1643  ((int)segmentsBlock.m_startX);
1644  profElementValue = MAX( 0, profElementValue );
1645  profElementValue = MIN( (int)segmentsBlock.m_width, profElementValue );
1646 
1647  segmentsBlock.m_rightCutOffProfile[ profEIdx ] = profElementValue;
1648  }
1649  }
1650  }
1651 
1652  return true;
1653  }
1654 
1656  const std::vector< std::vector< unsigned int> >& imageHorizontalProfiles,
1657  const std::vector< unsigned int >& imageHorizontalProfilesCenterLines,
1658  const std::vector< std::vector< unsigned int> >& imageVerticalProfiles,
1659  const std::vector< unsigned int >& imageVerticalProfilesCenterLines,
1660  const std::string& filename )
1661  {
1662  TERP_TRUE_OR_THROW( imageHorizontalProfiles.size() ==
1663  imageHorizontalProfilesCenterLines.size(), "Internal error" )
1664  TERP_TRUE_OR_THROW( imageVerticalProfiles.size() ==
1665  imageVerticalProfilesCenterLines.size(), "Internal error" )
1666 
1667  std::vector< te::rst::BandProperty* > bandsProperties;
1668  bandsProperties.push_back( new te::rst::BandProperty(
1671  bandsProperties[ 0 ]->m_colorInterp = te::rst::GrayIdxCInt;
1672  bandsProperties[ 0 ]->m_noDataValue = 0;
1673  bandsProperties[ 0 ]->m_type = te::dt::UCHAR_TYPE;
1674  //bandsProperties[ 0 ]->m_noDataValue = 0;
1675 
1676  std::map< std::string, std::string > rInfo;
1677  rInfo[ "URI" ] = "cutofflines.tif";
1678 
1679  std::auto_ptr< te::rst::Raster > outRasterPtr(
1682  bandsProperties, rInfo ) );
1683  TERP_TRUE_OR_RETURN_FALSE( outRasterPtr.get(),
1684  "Tiff creation error" )
1685 
1686  {
1687  for( unsigned int profIdx = 0 ; profIdx < imageHorizontalProfiles.size() ;
1688  ++profIdx )
1689  {
1690  const std::vector< unsigned int>& profile =
1691  imageHorizontalProfiles[ profIdx ];
1692  TERP_TRUE_OR_THROW( profile.size() ==
1693  outRasterPtr->getGrid()->getNumberOfColumns(), "Internal error" )
1694 
1695  const unsigned int centerLineIdx =
1696  imageHorizontalProfilesCenterLines[ profIdx ];
1697  TERP_TRUE_OR_THROW( centerLineIdx <
1698  outRasterPtr->getGrid()->getNumberOfRows(), "Internal error" )
1699 
1700 
1701  for( unsigned int eIdx = 0 ; eIdx < profile.size() ;
1702  ++eIdx )
1703  {
1704  TERP_TRUE_OR_THROW( profile[ eIdx ] <
1705  outRasterPtr->getGrid()->getNumberOfRows(), "Internal error" )
1706 
1707  outRasterPtr->setValue( eIdx, centerLineIdx, 255, 0 );
1708  outRasterPtr->setValue( eIdx, profile[ eIdx ] , 255, 0 );
1709  }
1710  }
1711  }
1712 
1713  {
1714  for( unsigned int profIdx = 0 ; profIdx < imageVerticalProfiles.size() ;
1715  ++profIdx )
1716  {
1717  const std::vector< unsigned int>& profile =
1718  imageVerticalProfiles[ profIdx ];
1719  TERP_TRUE_OR_THROW( profile.size() ==
1720  outRasterPtr->getGrid()->getNumberOfRows(), "Internal error" )
1721 
1722  const unsigned int centerLineIdx =
1723  imageVerticalProfilesCenterLines[ profIdx ];
1724  TERP_TRUE_OR_THROW( centerLineIdx <
1725  outRasterPtr->getGrid()->getNumberOfColumns(), "Internal error" )
1726 
1727  for( unsigned int eIdx = 0 ; eIdx < profile.size() ;
1728  ++eIdx )
1729  {
1730  TERP_TRUE_OR_THROW( profile[ eIdx ] <
1731  outRasterPtr->getGrid()->getNumberOfRows(), "Internal error" )
1732 
1733  outRasterPtr->setValue( centerLineIdx, eIdx, 255, 0 );
1734  outRasterPtr->setValue( profile[ eIdx ], eIdx, 255, 0 );
1735  }
1736  }
1737  }
1738 
1739  return true;
1740  }
1741  } // end namespace rp
1742 } // end namespace te
1743 
std::auto_ptr< te::rst::Raster > m_outputRasterPtr
A pointer the ge generated output raster (label image).
Definition: Segmenter.h:152
bool isActive() const
Verify if the task is active.
bool m_enableProgress
Enable/Disable the progress interface (default:false).
Definition: Segmenter.h:100
virtual AbstractParameters * clone() const =0
Create a clone copy of this instance.
std::vector< unsigned int > m_topCutOffProfile
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:356
std::string m_strategyName
The segmenter strategy name see each te::rp::SegmenterStrategyFactory inherited classes documentation...
Definition: Segmenter.h:98
bool volatile * m_abortSegmentationFlagPtr
Pointer to the abort segmentation flag (default:0)*/.
Definition: Segmenter.h:219
std::map< std::string, std::string > m_rInfo
The necessary information to create the raster (as described in te::raster::RasterFactory).
Definition: Segmenter.h:150
static void segmenterThreadEntry(SegmenterThreadEntryParams *paramsPtr)
Segmenter thread entry.
Definition: Segmenter.cpp:790
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
ColorInterp m_colorInterp
The color interpretation.
Definition: BandProperty.h:140
Raster Processing functions.
Segmenter segments block description class.
bool createCutOffLinesTiff(const std::vector< std::vector< unsigned int > > &imageHorizontalProfiles, const std::vector< unsigned int > &imageHorizontalProfilesCenterLines, const std::vector< std::vector< unsigned int > > &imageVerticalProfiles, const std::vector< unsigned int > &imageVerticalProfilesCenterLines, const std::string &filename)
Definition: Segmenter.cpp:1655
Grid * getGrid()
It returns the raster grid.
Definition: Raster.cpp:94
Segmenter Input Parameters.
Definition: Segmenter.h:80
boost::mutex * m_outputRasterIOMutexPtr
Pointer to the mutex used when accessing the output raster (default:0)*/.
Definition: Segmenter.h:213
bool m_enableBlockMerging
If true, a block merging procedure will be performed (default:true).
Definition: Segmenter.h:94
The parameters passed to the Segmenter::segmenterthreadEntry method.
Definition: Segmenter.h:194
static Raster * make()
It creates and returns an empty raster with default raster driver.
te::rst::Raster const * m_inputRasterPtr
Input raster.
Definition: Segmenter.h:84
unsigned int getLinesNumber() const
The number of current matrix lines.
Definition: Matrix.h:665
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: Segmenter.cpp:71
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
Segmenter Output Parameters.
Definition: Segmenter.h:144
unsigned int GetPhysProcNumber()
Returns the number of physical processors.
unsigned int m_maxSegThreads
The maximum number of concurrent segmenter threads (default:0 - automatically found).
Definition: Segmenter.h:90
double getResolutionY() const
Returns the grid vertical (y-axis) resolution.
Definition: Grid.cpp:261
std::vector< double > const * m_inputRasterGainsPtr
Pointer to a vector of input raster bands gain values */.
Definition: Segmenter.h:231
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
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
const Segmenter::InputParameters & operator=(const Segmenter::InputParameters &params)
Definition: Segmenter.cpp:90
static te::rp::SegmenterStrategy * make(const std::string &factoryKey)
It creates an object with the appropriated factory.
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
#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 m_enableBlockProcessing
If true, the original raster will be splitted into small blocks, each one will be segmented independe...
Definition: Segmenter.h:92
Abstract parameters base interface.
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
Definition: Segmenter.cpp:706
AbstractParameters * clone() const
Create a clone copy of this instance.
Definition: Segmenter.cpp:112
Segmenter::InputParameters m_inputParameters
Segmenter execution parameters.
Definition: Segmenter.h:249
A raster band description.
Definition: Band.h:63
A rectified grid is the spatial support for raster data.
Definition: Grid.h:55
std::vector< double > const * m_inputRasterOffsetsPtr
Pointer to a vector of input raster bands offset values */.
Definition: Segmenter.h:234
bool m_enableThreadedProcessing
If true, threaded processing will be performed (best with multi-core or multi-processor systems (defa...
Definition: Segmenter.h:88
#define ABS(x)
Absolute value.
Definition: Macros.h:402
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
Definition: Segmenter.cpp:739
Segmenter segments IDs manager.
SegmenterIdsManager * m_segmentsIdsManagerPtr
Pointer to the segments Ids manager - (default 0) */.
Definition: Segmenter.h:222
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
SegmenterStrategyParameters * m_segStratParamsPtr
A pointer to the internal specific segmenter strategy parameters or NULL if no parameters are present...
Definition: Segmenter.h:137
std::vector< unsigned int > m_rightCutOffProfile
bool updateBlockCutOffProfiles(const std::vector< std::vector< unsigned int > > &imageHorizontalProfiles, const std::vector< std::vector< unsigned int > > &imageVerticalProfiles, SegmenterSegmentsBlock &segmentsBlock) const
Update the block cutOff profiles using the full image profiles.
Definition: Segmenter.cpp:1521
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: Segmenter.cpp:151
bool m_enableStrategyProgress
Enable/Disable the segmentation strategy to use its own progress interface (default:false). */.
Definition: Segmenter.h:237
const Segmenter::OutputParameters & operator=(const Segmenter::OutputParameters &params)
Definition: Segmenter.cpp:158
double getResolutionX() const
Returns the grid horizontal (x-axis) resolution.
Definition: Grid.cpp:256
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
Definition: Segmenter.cpp:206
Segmenter::OutputParameters * m_outputParametersPtr
A pointer to the global segmenter input execution parameters (default:0). */.
Definition: Segmenter.h:201
unsigned int volatile * m_runningThreadsCounterPtr
Pointer to the running threads counter - default 0) */.
Definition: Segmenter.h:228
boost::mutex * m_inputRasterIOMutexPtr
Pointer to the mutex used when accessing the input raster (default:0)*/.
Definition: Segmenter.h:210
SegmentsBlocksMatrixT * m_segsBlocksMatrixPtr
Pointer to the segments blocks matrix (default:0)*/.
Definition: Segmenter.h:204
unsigned long int GetTotalPhysicalMemory()
Returns the amount of total physical memory (bytes).
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Definition: Raster.cpp:213
const Algorithm & operator=(const Algorithm &)
Definition: Algorithm.cpp:43
Raster segmenter strategy factory base class.
boost::mutex * m_generalMutexPtr
Pointer to a general global mutex (default:0)*/.
Definition: Segmenter.h:207
A raster band description.
Definition: BandProperty.h:61
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits&lt;double&gt;::max().
Definition: BandProperty.h:136
Raster segmentation.
#define MIN(a, b)
Macro that returns min between two values.
A generic template matrix.
Definition: Matrix.h:50
std::vector< unsigned int > m_inputRasterBands
Bands to be processed from the input raster.
Definition: Segmenter.h:86
bool genImageVCutOffProfile(const unsigned int profileCenter, const te::rst::Raster &inRaster, const std::vector< unsigned int > &inRasterBands, const unsigned int pixelNeighborhoodSize, const unsigned int tileNeighborhoodSize, const unsigned int profileAntiSmoothingFactor, std::vector< unsigned int > &profile) const
Generate the vertical cutOff prifles for the entire image..
Definition: Segmenter.cpp:1385
void gridToGeo(const double &col, const double &row, double &x, double &y) const
Get the spatial location of a grid point.
Definition: Grid.cpp:302
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:149
std::vector< unsigned int > m_bottomCutOffProfile
bool calcBestBlockSize(const unsigned int totalImageLines, const unsigned int totalImageCols, const unsigned int minBlockPixels, const unsigned int maxBlockPixels, const double blocksHOverlapSizePercent, const double blocksVOverlapSizePectent, unsigned int &blockWidth, unsigned int &blockHeight, unsigned int &blocksHOverlapSize, unsigned int &blocksVOverlapSize) const
Calc the best sub-image block size for each thread to process.
Definition: Segmenter.cpp:744
bool genImageHCutOffProfile(const unsigned int profileCenter, const te::rst::Raster &inRaster, const std::vector< unsigned int > &inRasterBands, const unsigned int pixelNeighborhoodSize, const unsigned int tileNeighborhoodSize, const unsigned int profileAntiSmoothingFactor, std::vector< unsigned int > &profile) const
Generate the horizontal cutOff prifles for the entire image..
Definition: Segmenter.cpp:1249
unsigned int getColumnsNumber() const
The number of current matrix columns.
Definition: Matrix.h:672
void reset()
Clear all internal allocated objects and reset the algorithm to its initial state.
Definition: Segmenter.cpp:700
Segmenter::InputParameters const * m_inputParametersPtr
A pointer to the global segmenter input execution parameters (default:0). */.
Definition: Segmenter.h:198
Raster Processing algorithm output parameters base interface.
boost::mutex * m_blockProcessedSignalMutexPtr
Pointer to the mutex used by the block processed signal (default:0)*/.
Definition: Segmenter.h:216
bool m_instanceInitialized
Definition: Segmenter.h:247
AbstractParameters * clone() const
Create a clone copy of this instance.
Definition: Segmenter.cpp:169
void reset()
Reset (clear) the active instance data.
Definition: Matrix.h:474
An abstract class for raster data strucutures.
Definition: Raster.h:70
te::common::TaskProgress * m_progressPtr
A pointer to an active task progress tha should be pulsed for each processed block or a null pointer ...
Definition: Segmenter.h:240
BandProperty * getProperty()
Returns the band property.
Definition: Band.cpp:370
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
unsigned long int GetUsedVirtualMemory()
Returns the amount of used virtual memory (bytes) for the current process (physical + swapped)...
int getSRID() const
Returns the grid spatial reference system identifier.
Definition: Grid.cpp:266
unsigned long int GetTotalVirtualMemory()
Returns the amount of total virtual memory (bytes) that can be claimed by the current process (physic...
unsigned int m_maxBlockSize
The input image will be split into blocks with this width for processing, this parameter tells the ma...
Definition: Segmenter.h:96
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
Definition: Segmenter.h:148
void setSegStrategyParams(const SegmenterStrategyParameters &segStratParams)
Set specific segmenter strategy parameters.
Definition: Segmenter.cpp:117
SegmenterStrategyParameters const * getSegStrategyParams() const
Returns a pointer to the internal specific segmenter strategy parameters.
Definition: Segmenter.cpp:130
boost::condition_variable * m_blockProcessedSignalPtr
Pointer to a signal to be emited when a segments block was processed (default:0)*/.
Definition: Segmenter.h:225
Index into a lookup table.
Definition: Enums.h:57
#define MAX(a, b)
Macro that returns max between two values.
std::vector< unsigned int > m_leftCutOffProfile
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
Definition: Raster.cpp:89
Raster Processing algorithm input parameters base interface.