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