src/terralib/rp/Contrast.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/rp/Contrast.cpp
22 
23  \brief Contrast enhancement.
24 */
25 
26 // TerraLib
27 #include "../raster/Raster.h"
28 #include "../raster/Band.h"
29 #include "../raster/BandIterator.h"
30 #include "../raster/BandProperty.h"
31 #include "../raster/Grid.h"
32 #include "../raster/RasterProperty.h"
33 #include "../raster/RasterSummaryManager.h"
34 #include "../raster/RasterFactory.h"
35 #include "../memory/ExpansibleRaster.h"
36 #include "../common/progress/TaskProgress.h"
37 #include "Contrast.h"
38 #include "Functions.h"
39 #include "Macros.h"
40 
41 // STL
42 #include <cfloat>
43 
44 // Boost
45 #include <boost/concept_check.hpp>
46 
47 namespace te
48 {
49  namespace rp
50  {
52  {
53  reset();
54  }
55 
57  {
58  reset();
59  }
60 
62  {
64 
65  m_lCMinInput.clear();
66  m_lCMaxInput.clear();
67 
68  m_hECMaxInput.clear();
69 
70  m_squareCMinInput.clear();
71  m_squareCMaxInput.clear();
72 
73  m_squareRootCMinInput.clear();
74  m_squareRootCMaxInput.clear();
75 
76  m_logCMinInput.clear();
77  m_logCMaxInput.clear();
78 
79  m_sMASCMeanInput.clear();
80  m_sMASCStdInput.clear();
81 
82  m_inRasterPtr = nullptr;
83  m_inRasterBands.clear();
84  m_enableProgress = false;
85 
86  m_outRangeMin = -1.0 * std::numeric_limits<double>::max();
87  m_outRangeMax = std::numeric_limits<double>::max();
88  }
89 
91  const Contrast::InputParameters& params )
92  {
93  reset();
94 
95  m_type = params.m_type;
96 
97  m_lCMinInput = params.m_lCMinInput;
98  m_lCMaxInput = params.m_lCMaxInput;
99 
100  m_hECMaxInput = params.m_hECMaxInput;
101 
104 
107 
110 
113 
114  m_inRasterPtr = params.m_inRasterPtr;
117 
118  m_outRangeMin = params.m_outRangeMin;
119  m_outRangeMax = params.m_outRangeMax;
120 
121  return *this;
122  }
123 
125  {
126  return new InputParameters( *this );
127  }
128 
130  {
131  reset();
132  }
133 
135  {
136  reset();
137  operator=( other );
138  }
139 
141  {
142  reset();
143  }
144 
146  {
147  m_outRasterPtr = nullptr;
148  m_createdOutRasterPtr.reset();
149  m_outRasterBands.clear();
150  m_createdOutRasterDSType.clear();
151  m_createdOutRasterInfo.clear();
152  }
153 
155  const Contrast::OutputParameters& params )
156  {
157  reset();
158 
159  m_outRasterPtr = params.m_outRasterPtr;
160  m_outRasterBands = params.m_outRasterBands;
161  m_createdOutRasterDSType = params.m_createdOutRasterDSType;
162  m_createdOutRasterInfo = params.m_createdOutRasterInfo;
163 
164  return *this;
165  }
166 
168  {
169  return new OutputParameters( *this );
170  }
171 
173  {
174  reset();
175  }
176 
177  Contrast::~Contrast() = default;
178 
180  throw( te::rp::Exception )
181  {
182  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( m_isInitialized, "Algoritm not initialized" );
183 
184  // Initializing the output raster
185 
186  m_outputParametersPtr = dynamic_cast<
187  Contrast::OutputParameters* >( &outputParams );
189 
190  if( m_outputParametersPtr->m_outRasterPtr == nullptr )
191  {
193 
194  std::vector< te::rst::BandProperty* > bandsProperties;
195  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
196  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
197  {
198  assert( m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] <
200 
201  bandsProperties.push_back( new te::rst::BandProperty(
204  inRasterBandsIdx ] )->getProperty() ) ) );
205 
206  m_outputParametersPtr->m_outRasterBands.push_back( inRasterBandsIdx );
207  }
208 
213  bandsProperties,
215  nullptr,
216  nullptr ) );
218  "Output raster creation error" );
219 
222  }
223  else
224  {
230  {
231  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
232  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
233  {
235  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] <
237  "Invalid output raster band" )
238  }
239  }
240  else
241  {
242  TERP_INSTANCE_LOG_AND_RETURN_FALSE( "Invalid output raster" );
243  }
244  }
245 
246  // Executing the contrast on the selected bands
247 
248  switch( m_inputParameters.m_type )
249  {
251  {
252  return execLinearContrast();
253  break;
254  }
256  {
258  break;
259  }
261  {
262  return execSquareContrast();
263  break;
264  }
266  {
267  return execSquareRootContrast();
268  break;
269  }
271  {
272  return execLogContrast();
273  break;
274  }
276  {
277  return execSetMeanAndStdContrast();
278  break;
279  }
281  {
283  break;
284  }
285  default :
286  {
287  TERP_LOG_AND_THROW( "Invalid contrast type" );
288  break;
289  }
290  }
291  }
292 
293  void Contrast::reset() throw( te::rp::Exception )
294  {
296 
298  m_outputParametersPtr = nullptr;
299  m_isInitialized = false;
300  }
301 
303  throw( te::rp::Exception )
304  {
305  reset();
306 
307  Contrast::InputParameters const* inputParamsPtr = dynamic_cast<
308  Contrast::InputParameters const* >( &inputParams );
309  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr, "Invalid parameters" );
310 
312  "Invalid raster pointer" );
315  "Invalid raster" );
316 
317  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_inRasterBands.size() > 0,
318  "Invalid bands number" );
319 
320  if (inputParamsPtr->m_outRangeMin != ( -1.0 * std::numeric_limits<double>::max() ) &&
321  inputParamsPtr->m_outRangeMax != std::numeric_limits<double>::max())
322  {
325  }
326 
327  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
328  inputParamsPtr->m_inRasterBands.size() ; ++inRasterBandsIdx )
329  {
331  inputParamsPtr->m_inRasterBands[ inRasterBandsIdx ] <
332  inputParamsPtr->m_inRasterPtr->getNumberOfBands(),
333  "Invalid input raster band" );
334  }
335 
336  // Checking contrast specifi parameters
337 
338  switch( inputParamsPtr->m_type )
339  {
341  {
342  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_lCMinInput.size() ==
343  inputParamsPtr->m_inRasterBands.size(),
344  "Invalid parameter m_lCMinInput" );
345  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_lCMaxInput.size() ==
346  inputParamsPtr->m_inRasterBands.size(),
347  "Invalid parameter m_lCMaxInput" );
348 
349  break;
350  }
352  {
353  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_hECMaxInput.size() ==
354  inputParamsPtr->m_inRasterBands.size(),
355  "Invalid parameter m_hECMaxInput" );
356 
357  break;
358  }
360  {
361  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_squareCMinInput.size() ==
362  inputParamsPtr->m_inRasterBands.size(),
363  "Invalid parameter m_squareCMinInput" );
364  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_squareCMaxInput.size() ==
365  inputParamsPtr->m_inRasterBands.size(),
366  "Invalid parameter m_squareCMaxInput" );
367 
368  break;
369  }
371  {
373  inputParamsPtr->m_inRasterBands.size(),
374  "Invalid parameter m_squareRootCMinInput" );
376  inputParamsPtr->m_inRasterBands.size(),
377  "Invalid parameter m_squareRootRCMaxInput" );
378 
379  break;
380  }
382  {
383  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_logCMinInput.size() ==
384  inputParamsPtr->m_inRasterBands.size(),
385  "Invalid parameter m_logCMinInput" );
386  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_logCMaxInput.size() ==
387  inputParamsPtr->m_inRasterBands.size(),
388  "Invalid parameter m_logCMaxInput" );
389 
390  break;
391  }
393  {
394  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_sMASCMeanInput.size() ==
395  inputParamsPtr->m_inRasterBands.size(),
396  "Invalid parameter m_sMASCMeanInput" );
397  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_sMASCStdInput.size() ==
398  inputParamsPtr->m_inRasterBands.size(),
399  "Invalid parameter m_sMASCStdInput" );
400  break;
401  }
403  {
404  break;
405  }
406  default :
407  {
408  TERP_LOG_AND_THROW( "Invalid contrast type" );
409  break;
410  }
411  }
412 
413  m_inputParameters = *inputParamsPtr;
414  m_isInitialized = true;
415 
416  return true;
417  }
418 
420  {
421  return m_isInitialized;
422  }
423 
425  const double& inRangeMin, const double& inRangeMax,
426  const double& outRangeMin, const double& outRangeMax,
427  double& gain, double& offset1, double& offset2 )
428  {
429  const double outRange = outRangeMax - outRangeMin;
430  const double inRange = inRangeMax - inRangeMin;
431  TERP_TRUE_OR_RETURN_FALSE( outRange >= 0.0, "Invalid values range" );
432  TERP_TRUE_OR_RETURN_FALSE( inRange >= 0.0, "Invalid values range" );
433 
434  switch( type )
435  {
437  {
438  if( inRange == 0.0 )
439  {
440  gain = 1.0;
441  }
442  else
443  {
444  gain = outRange / inRange;
445  }
446 
447  offset1 = (-1.0) * inRangeMin;
448  offset2 = outRangeMin;
449 
450  break;
451  }
453  {
454  if( inRange == 0.0 )
455  {
456  gain = 0.0;
457  }
458  else
459  {
460  gain = outRange / std::pow( inRange, 2.0 );
461  }
462 
463  offset1 = 0.0;
464  offset2 = 0.0;
465 
466  break;
467  }
469  {
470  if( inRange == 0.0 )
471  {
472  gain = 0.0;
473  }
474  else
475  {
476  gain = outRange / std::sqrt( inRange );
477  }
478 
479  offset1 = 0.0;
480  offset2 = 0.0;
481 
482  break;
483  }
485  {
486  if( inRange == 0.0 )
487  {
488  gain = 0.0;
489  }
490  else
491  {
492  gain = outRange / std::log10( inRange + 1.0 );
493  }
494 
495  offset1 = -1.0 * inRangeMin;
496  offset2 = 0.0;
497 
498  break;
499  }
500  default :
501  {
502  TERP_LOG_AND_RETURN_FALSE( "Invalid contrast type" );
503  break;
504  }
505  }
506 
507  return true;
508  }
509 
511  {
514 
515  const bool enableGlobalProgress = m_inputParameters.m_enableProgress &&
516  ( m_inputParameters.m_inRasterBands.size() > 1 );
517  std::unique_ptr< te::common::TaskProgress > progressPtr;
518  if( enableGlobalProgress )
519  {
520  progressPtr.reset( new te::common::TaskProgress );
521  progressPtr->setMessage( "Contrast" );
522  progressPtr->setTotalSteps( static_cast<int>(m_inputParameters.m_inRasterBands.size()) );
523  }
524 
525  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
526  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
527  {
528  te::rst::Band const* inRasterBandPtr = m_inputParameters.m_inRasterPtr->getBand(
529  m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] );
531  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] );
532 
533 
534  if (m_inputParameters.m_outRangeMin == ( -1.0 * std::numeric_limits<double>::max() ) &&
535  m_inputParameters.m_outRangeMax == std::numeric_limits<double>::max())
536  {
537  GetDataTypeRange(outRasterBandPtr->getProperty()->getType(),
539  }
540 
542  m_inputParameters.m_lCMinInput[ inRasterBandsIdx ],
543  m_inputParameters.m_lCMaxInput[ inRasterBandsIdx ],
549  )
550  {
551  return false;
552  }
553 
554  if( ! remapBandLevels( *inRasterBandPtr, *outRasterBandPtr,
556  (!enableGlobalProgress) ) )
557  {
558  return false;
559  }
560 
561  if( enableGlobalProgress )
562  {
563  progressPtr->pulse();
564  if( ! progressPtr->isActive() ) return false;
565  }
566  }
567 
568  return true;
569  }
570 
572  {
575 
576  te::rst::RasterSummary const * const rasterSummaryPtr =
579 
580  double newvalue = 0;
581  unsigned int totalPixelsNumber = m_inputParameters.m_inRasterPtr->getNumberOfRows() *
583 
584  const bool enableGlobalProgress = m_inputParameters.m_enableProgress &&
585  ( m_inputParameters.m_inRasterBands.size() > 1 );
586  std::unique_ptr< te::common::TaskProgress > progressPtr;
587  if( enableGlobalProgress )
588  {
589  progressPtr.reset( new te::common::TaskProgress );
590  progressPtr->setMessage( "Contrast" );
591  progressPtr->setTotalSteps( static_cast<int>(m_inputParameters.m_inRasterBands.size()) );
592  }
593 
594  for( unsigned int b = 0 ; b < m_inputParameters.m_inRasterBands.size() ; b++ )
595  {
596  const unsigned int inputBandIdx = m_inputParameters.m_inRasterBands[b];
597  const unsigned int outputBandIdx = m_outputParametersPtr->m_outRasterBands[b];
598  const te::rst::Band& inputBand = *m_inputParameters.m_inRasterPtr->getBand(inputBandIdx);
599  te::rst::Band& outputBand = *m_outputParametersPtr->m_outRasterPtr->getBand(outputBandIdx);
600 
601  // lut
602 
603 // const double lutfactor =
604 // m_inputParameters.m_hECMaxInput[ b ] / (double) totalPixelsNumber;
605  const int inputDataType = inputBand.getProperty()->getType();
606  const int outputDataType = outputBand.getProperty()->getType();
607 
608  if (m_inputParameters.m_outRangeMin == ( -1.0 * std::numeric_limits<double>::max() ) &&
609  m_inputParameters.m_outRangeMax == std::numeric_limits<double>::max())
610  {
613  }
614 
615  const double minp = rasterSummaryPtr->at(inputBandIdx).m_minVal->real();
616  const double maxp = rasterSummaryPtr->at(inputBandIdx).m_maxVal->real();
617 
618  const bool isRealValuesBand = ( inputDataType == te::dt::FLOAT_TYPE ) ||
619  ( inputDataType == te::dt::DOUBLE_TYPE );
620 
621  const double pixelValueStep = isRealValuesBand ? ( ( maxp - minp ) /
622  ((double)te::rst::RasterSummaryManager::getInstance().getRealValuesRasterHistSize() ) )
623  : 1.0;
624 
625  // cdf
626 
628 
629  if( isRealValuesBand )
630  {
631  for (double pixel = minp; pixel <= maxp; pixel += pixelValueStep )
632  {
633  newvalue = 0.0;
634 
635  for (double nj = minp; nj <= pixel; nj++)
636  {
637  newvalue += rasterSummaryPtr->at(inputBandIdx).m_histogramR->lower_bound( nj )->second;
638  }
639 
640  m_histogramEqualizationRemap_cdf[pixel] = newvalue;
641  }
642  }
643  else
644  {
645  for (double pixel = minp; pixel <= maxp; pixel += pixelValueStep )
646  {
647  newvalue = 0.0;
648 
649  for (double nj = minp; nj <= pixel; nj++)
650  {
651  newvalue += rasterSummaryPtr->at(inputBandIdx).m_histogramR->operator[](nj);
652  }
653 
654  m_histogramEqualizationRemap_cdf[pixel] = newvalue;
655  }
656  }
657 
659 
661  / ((double)totalPixelsNumber );
662 
663  if( ! remapBandLevels( inputBand, outputBand,
665  (!enableGlobalProgress) ) )
666  {
667  return false;
668  }
669 
670  if( enableGlobalProgress )
671  {
672  progressPtr->pulse();
673  if( ! progressPtr->isActive() ) return false;
674  }
675  }
676 
677  return true;
678  }
679 
681  {
684 
685  const bool enableGlobalProgress = m_inputParameters.m_enableProgress &&
686  ( m_inputParameters.m_inRasterBands.size() > 1 );
687  std::unique_ptr< te::common::TaskProgress > progressPtr;
688  if( enableGlobalProgress )
689  {
690  progressPtr.reset( new te::common::TaskProgress );
691  progressPtr->setMessage( "Contrast" );
692  progressPtr->setTotalSteps( static_cast<int>(m_inputParameters.m_inRasterBands.size()) );
693  }
694 
695  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
696  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
697  {
698  te::rst::Band const* inRasterBandPtr = m_inputParameters.m_inRasterPtr->getBand(
699  m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] );
701  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] );
702 
703  if (m_inputParameters.m_outRangeMin == ( -1.0 * std::numeric_limits<double>::max() ) &&
704  m_inputParameters.m_outRangeMax == std::numeric_limits<double>::max())
705  {
706  GetDataTypeRange(outRasterBandPtr->getProperty()->getType(),
708  }
709 
711  m_inputParameters.m_squareCMinInput[ inRasterBandsIdx ],
712  m_inputParameters.m_squareCMaxInput[ inRasterBandsIdx ],
718  )
719  {
720  return false;
721  }
722 
723  if( ! remapBandLevels( *inRasterBandPtr, *outRasterBandPtr,
725  (!enableGlobalProgress) ) )
726  {
727  return false;
728  }
729 
730  if( enableGlobalProgress )
731  {
732  progressPtr->pulse();
733  if( ! progressPtr->isActive() ) return false;
734  }
735  }
736 
737  return true;
738  }
739 
741  {
744 
745  const bool enableGlobalProgress = m_inputParameters.m_enableProgress &&
746  ( m_inputParameters.m_inRasterBands.size() > 1 );
747  std::unique_ptr< te::common::TaskProgress > progressPtr;
748  if( enableGlobalProgress )
749  {
750  progressPtr.reset( new te::common::TaskProgress );
751  progressPtr->setMessage( "Contrast" );
752  progressPtr->setTotalSteps( static_cast<int>(m_inputParameters.m_inRasterBands.size()) );
753  }
754 
755  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
756  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
757  {
758  te::rst::Band const* inRasterBandPtr = m_inputParameters.m_inRasterPtr->getBand(
759  m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] );
761  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] );
762 
763  if (m_inputParameters.m_outRangeMin == ( -1.0 * std::numeric_limits<double>::max() ) &&
764  m_inputParameters.m_outRangeMax == std::numeric_limits<double>::max())
765  {
766  GetDataTypeRange(outRasterBandPtr->getProperty()->getType(),
768  }
769 
771  m_inputParameters.m_squareRootCMinInput[ inRasterBandsIdx ],
772  m_inputParameters.m_squareRootCMaxInput[ inRasterBandsIdx ],
778  )
779  {
780  return false;
781  }
782 
783  if( ! remapBandLevels( *inRasterBandPtr, *outRasterBandPtr,
785  (!enableGlobalProgress) ) )
786  {
787  return false;
788  }
789 
790  if( enableGlobalProgress )
791  {
792  progressPtr->pulse();
793  if( ! progressPtr->isActive() ) return false;
794  }
795  }
796 
797  return true;
798  }
799 
801  {
804 
805  const bool enableGlobalProgress = m_inputParameters.m_enableProgress &&
806  ( m_inputParameters.m_inRasterBands.size() > 1 );
807  std::unique_ptr< te::common::TaskProgress > progressPtr;
808  if( enableGlobalProgress )
809  {
810  progressPtr.reset( new te::common::TaskProgress );
811  progressPtr->setMessage( "Contrast" );
812  progressPtr->setTotalSteps( static_cast<int>(m_inputParameters.m_inRasterBands.size()) );
813  }
814 
815  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
816  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
817  {
818  te::rst::Band const* inRasterBandPtr = m_inputParameters.m_inRasterPtr->getBand(
819  m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] );
821  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] );
822 
823  if (m_inputParameters.m_outRangeMin == ( -1.0 * std::numeric_limits<double>::max() ) &&
824  m_inputParameters.m_outRangeMax == std::numeric_limits<double>::max())
825  {
826  GetDataTypeRange(outRasterBandPtr->getProperty()->getType(),
828  }
829 
831  m_inputParameters.m_logCMinInput[ inRasterBandsIdx ],
832  m_inputParameters.m_logCMaxInput[ inRasterBandsIdx ],
838  )
839  {
840  return false;
841  }
842 
843  if( ! remapBandLevels( *inRasterBandPtr, *outRasterBandPtr,
845  (!enableGlobalProgress) ) )
846  {
847  return false;
848  }
849 
850  if( enableGlobalProgress )
851  {
852  progressPtr->pulse();
853  if( ! progressPtr->isActive() ) return false;
854  }
855  }
856 
857  return true;
858  }
859 
861  {
864 
865  const te::rst::RasterSummary* rsummary =
869 
870  std::unique_ptr< te::common::TaskProgress > progressPtr;
872  {
873  progressPtr.reset( new te::common::TaskProgress );
874  progressPtr->setMessage( "Contrast" );
875  progressPtr->setTotalSteps( static_cast<int>(m_inputParameters.m_inRasterBands.size() *
877  }
878 
879  for( unsigned int b = 0 ; b < m_inputParameters.m_inRasterBands.size() ; b++ )
880  {
881  unsigned int niband = m_inputParameters.m_inRasterBands[b];
882  unsigned int noband = m_outputParametersPtr->m_outRasterBands[b];
883 
884  const te::rst::Band* iband = m_inputParameters.m_inRasterPtr->getBand(niband);
886 
887  if (m_inputParameters.m_outRangeMin == ( -1.0 * std::numeric_limits<double>::max() ) &&
888  m_inputParameters.m_outRangeMax == std::numeric_limits<double>::max())
889  {
892  }
893 
898 
899  const double meanp = rsummary->at(niband).m_meanVal->real();
900  const double stdp = rsummary->at(niband).m_stdVal->real();
901  const double offset = m_inputParameters.m_sMASCMeanInput[ b ] /
903  const double c1 = m_inputParameters.m_sMASCStdInput[ b ] / stdp;
904  const double c2 = offset * m_inputParameters.m_sMASCStdInput[ b ];
905 
906  double value;
907  double newvalue;
908 
909  for (unsigned r = 0; r < iband->getRaster()->getNumberOfRows(); r++)
910  {
911  for (unsigned c = 0; c < iband->getRaster()->getNumberOfColumns(); c++)
912  {
913  iband->getValue(c, r, value);
914  newvalue = (value - meanp) * c1 + c2;
915  newvalue = std::max(m_inputParameters.m_outRangeMin, newvalue);
916  newvalue = std::min(m_inputParameters.m_outRangeMax, newvalue);
917  oband->setValue(c, r, newvalue);
918  }
919 
921  {
922  progressPtr->pulse();
923  if( ! progressPtr->isActive() ) return false;
924  }
925  }
926  }
927 
928  return true;
929  }
930 
932  {
935 
936  // Progress interface
937 
938  std::unique_ptr< te::common::TaskProgress > progressPtr;
940  {
941  progressPtr.reset( new te::common::TaskProgress );
942  progressPtr->setMessage( "Contrast" );
943  progressPtr->setTotalSteps( static_cast<int>(m_inputParameters.m_inRasterBands.size() +
944  2) );
945  }
946 
947  // Compute PCA space raster
948 
949  std::unique_ptr< te::rst::Raster > pcaRasterPtr;
950  boost::numeric::ublas::matrix< double > pcaMatrix;
951 
952  {
953  te::rst::Grid* gridPtr = new te::rst::Grid(
955  std::vector< te::rst::BandProperty * > bandProperties;
956  std::vector< unsigned int > pcaRasterBands;
957 
958  for( unsigned int bandIdx = 0 ; bandIdx <
959  m_inputParameters.m_inRasterBands.size() ; ++bandIdx )
960  {
961  bandProperties.push_back( new te::rst::BandProperty(
963  bandProperties[ bandIdx ]->m_type = te::dt::DOUBLE_TYPE;
964 
965  pcaRasterBands.push_back( bandIdx );
966  }
967 
968  try
969  {
970  pcaRasterPtr.reset( new te::mem::ExpansibleRaster( 25, gridPtr,
971  bandProperties ) );
972  }
973  catch( te::common::Exception& e )
974  {
976  }
977 
980  pcaMatrix, *pcaRasterPtr, pcaRasterBands, 0 ),
981  "Principal components generation error" );
982 
983 // te::rp::Copy2DiskRaster( *pcaRasterPtr, "pcaRaster.tif" );
984  }
985 
987  {
988  progressPtr->pulse();
989  if( ! progressPtr->isActive() ) return false;
990  }
991 
992  // The reference for enhancement: mean and std dev from the first PCA band
993 
994  double pca0MeanValue = 0;
996  *pcaRasterPtr->getBand( 0 ), 0, pca0MeanValue ),
997  "Mean value calcule error" );
998 
999  double pca0StdDevValue = 0;
1001  *pcaRasterPtr->getBand( 0 ), 0, &pca0MeanValue,
1002  pca0StdDevValue ), "StdDev value calcule error" );
1003 
1004  // Enhancing PCA
1005 
1006  for( unsigned int pcaBandIdx = 1 ; pcaBandIdx <
1007  m_inputParameters.m_inRasterBands.size() ; ++pcaBandIdx )
1008  {
1009  te::rst::Band& pcaBand = *pcaRasterPtr->getBand( pcaBandIdx );
1010 
1011  double meanValue = 0;
1012  TERP_TRUE_OR_RETURN_FALSE( te::rp::GetMeanValue( pcaBand, 0, meanValue ),
1013  "Mean value calcule error" );
1014 
1015  double stdDevValue = 0;
1016  TERP_TRUE_OR_RETURN_FALSE( te::rp::GetStdDevValue( pcaBand, 0, &meanValue,
1017  stdDevValue ), "StdDev value calcule error" );
1018 
1019  m_decorrelationEnhancementRemap_offset1 = -1.0 * meanValue;
1021  m_decorrelationEnhancementRemap_gain = ( stdDevValue == 0.0 ) ? 0.0 : ( pca0StdDevValue /
1022  stdDevValue );
1023 
1024  if( ! remapBandLevels( pcaBand, pcaBand,
1026  {
1027  return false;
1028  }
1029 
1031  {
1032  progressPtr->pulse();
1033  if( ! progressPtr->isActive() ) return false;
1034  }
1035  }
1036 
1037  // Generating the output enhanced raster
1038 
1040  pcaMatrix, *m_outputParametersPtr->m_outRasterPtr,
1042  "Inverse PCA error" );
1043 
1045  {
1046  progressPtr->pulse();
1047  if( ! progressPtr->isActive() ) return false;
1048  }
1049 
1050  return true;
1051  }
1052 
1053  bool Contrast::remapBandLevels( const te::rst::Band& inRasterBand,
1054  te::rst::Band& outRasterBand, RemapFuncPtrT remapFuncPtr,
1055  const bool enableProgress )
1056  {
1057  const unsigned int inBlkWidthPixels = inRasterBand.getProperty()->m_blkw;
1058  const unsigned int inBlkHeightPixels = inRasterBand.getProperty()->m_blkh;
1059  const unsigned int outBlkWidthPixels = outRasterBand.getProperty()->m_blkw;
1060  const unsigned int outBlkHeightPixels = outRasterBand.getProperty()->m_blkh;
1061 
1062  if (m_inputParameters.m_outRangeMin == ( -1.0 * std::numeric_limits<double>::max() ) &&
1063  m_inputParameters.m_outRangeMax == std::numeric_limits<double>::max())
1064  {
1065  GetDataTypeRange(outRasterBand.getProperty()->getType(),
1067  }
1068 
1069  std::unique_ptr< te::common::TaskProgress > progressPtr;
1070  if( enableProgress )
1071  {
1072  progressPtr.reset( new te::common::TaskProgress );
1073  progressPtr->setMessage( "Contrast" );
1074  }
1075 
1076  if( ( inBlkWidthPixels == outBlkWidthPixels ) &&
1077  ( inBlkHeightPixels == outBlkHeightPixels ) )
1078  { // block version
1079  const unsigned int blockSizePixels = inBlkWidthPixels *
1080  inBlkHeightPixels;
1081  const unsigned int xBlocksNmb = inRasterBand.getProperty()->m_nblocksx;
1082  const unsigned int yBlocksNmb = inRasterBand.getProperty()->m_nblocksy;
1083  unsigned char* inputBuffer = new unsigned char[ inRasterBand.getBlockSize() ];
1084  unsigned char* outputBuffer = new unsigned char[ outRasterBand.getBlockSize() ];
1085  double* inDoublesBuffer = new double[ blockSizePixels ];
1086  double* outDoublesBuffer = new double[ blockSizePixels ];
1087  const int inputVectorDataType = inRasterBand.getProperty()->getType();
1088  const int outputVectorDataType = outRasterBand.getProperty()->getType();
1089  unsigned int blockXIndex = 0;
1090  unsigned int blockOffset = 0;
1091  double outValue = 0;
1092 
1093  if( enableProgress ) progressPtr->setTotalSteps( yBlocksNmb * xBlocksNmb );
1094 
1095  for( unsigned int blockYIndex = 0 ; blockYIndex < yBlocksNmb ;
1096  ++blockYIndex )
1097  {
1098  for( blockXIndex = 0 ; blockXIndex < xBlocksNmb ;
1099  ++blockXIndex )
1100  {
1101  inRasterBand.read( blockXIndex, blockYIndex, inputBuffer );
1102 
1103  Convert2DoublesVector( inputBuffer, inputVectorDataType,
1104  blockSizePixels, inDoublesBuffer );
1105 
1106  for( blockOffset = 0 ; blockOffset < blockSizePixels ; ++blockOffset )
1107  {
1108  (this->*remapFuncPtr)( inDoublesBuffer[blockOffset],
1109  outValue);
1110  outDoublesBuffer[blockOffset] = std::max(m_inputParameters.m_outRangeMin, std::min(
1111  m_inputParameters.m_outRangeMax, outValue));
1112  }
1113 
1114  ConvertDoublesVector( outDoublesBuffer, blockSizePixels,
1115  outputVectorDataType, outputBuffer );
1116 
1117  outRasterBand.write( blockXIndex, blockYIndex, outputBuffer );
1118 
1119  if( enableProgress )
1120  {
1121  progressPtr->pulse();
1122  if( ! progressPtr->isActive() ) return false;
1123  }
1124  }
1125  }
1126 
1127  delete[] inputBuffer;
1128  delete[] outputBuffer;
1129  delete[] inDoublesBuffer;
1130  delete[] outDoublesBuffer;
1131  }
1132  else
1133  { // pixel by pixel version
1134  const unsigned int linesNumber = m_inputParameters.m_inRasterPtr->getNumberOfRows();
1135  const unsigned int columnsNumber = m_inputParameters.m_inRasterPtr->getNumberOfColumns();
1136 
1137  if( enableProgress ) progressPtr->setTotalSteps( linesNumber );
1138 
1139  unsigned int col = 0;
1140  double inputValue = 0;
1141  double outputValue = 0;
1142 
1143  for( unsigned int line = 0 ; line < linesNumber ; ++line )
1144  {
1145  for( col = 0 ; col < columnsNumber ; ++col )
1146  {
1147  inRasterBand.getValue( col, line, inputValue );
1148  (this->*remapFuncPtr)( inputValue, outputValue );
1149  outRasterBand.setValue(col, line, std::max(m_inputParameters.m_outRangeMin, std::min(
1150  m_inputParameters.m_outRangeMax, outputValue)));
1151  }
1152 
1153  if( enableProgress )
1154  {
1155  progressPtr->pulse();
1156  if( ! progressPtr->isActive() ) return false;
1157  }
1158  }
1159  }
1160 
1161  return true;
1162  }
1163 
1164  } // end namespace rp
1165 } // end namespace te
1166 
double m_decorrelationEnhancementRemap_offset2
Definition: Contrast.h:334
bool GetMeanValue(const te::rst::Band &band, const unsigned int maxThreads, double &meanValue)
Get the mean of band pixel values.
std::vector< double > m_logCMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:150
std::vector< double > m_lCMinInput
The contrast minimum input greyscale value of each band.
Definition: Contrast.h:106
bool m_isInitialized
Tells if this instance is initialized.
Definition: Contrast.h:260
te::rst::Raster * m_outRasterPtr
A pointer to a valid initiated raster instance where the result must be written, leave NULL to create...
Definition: Contrast.h:192
double m_outRangeMin
Minimum value of data type range (default: -1.0 * std::numeric_limits<double>::max() )...
Definition: Contrast.h:93
double m_squareRemap_gain
Definition: Contrast.h:322
ContrastType m_type
The contrast type to be applied.
Definition: Contrast.h:87
A raster band description.
Definition: BandProperty.h:61
Base exception class for plugin module.
void squareRemap(const double &inValue, double &outValue)
Remap on gray level using a square.
Definition: Contrast.h:359
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
virtual const char * what() const
It outputs the exception message.
int m_nblocksy
The number of blocks in y.
Definition: BandProperty.h:146
std::vector< double > m_squareRootCMinInput
The contrast minimum input greyscale value of each band.
Definition: Contrast.h:137
void logRemap(const double &inValue, double &outValue)
Remap on gray level using a log.
Definition: Contrast.h:381
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
void TERPEXPORT GetDataTypeRange(const int dataType, double &min, double &max)
Returns the real data type range (all values that can be represented by the given data type)...
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
static bool getGainAndOffset(const InputParameters::ContrastType &type, const double &inRangeMin, const double &inRangeMax, const double &outRangeMin, const double &outRangeMax, double &gain, double &offset1, double &offset2)
Returns gain and offset values for contrast types (when applicable).
Raster Processing algorithm output parameters base interface.
std::vector< double > m_squareRootCMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:139
const OutputParameters & operator=(const OutputParameters &params)
double m_histogramEqualizationRemap_gain
Definition: Contrast.h:338
AbstractParameters * clone() const
Create a clone copy of this instance.
const InputParameters & operator=(const InputParameters &params)
double m_histogramEqualizationRemap_cDFMin
Definition: Contrast.h:337
double m_decorrelationEnhancementRemap_gain
Definition: Contrast.h:332
bool DirectPrincipalComponents(const te::rst::Raster &inputRaster, const std::vector< unsigned int > &inputRasterBands, boost::numeric::ublas::matrix< double > &pcaMatrix, te::rst::Raster &pcaRaster, const std::vector< unsigned int > &pcaRasterBands, const unsigned int maxThreads)
Generate all principal components from the given input raster.
This class implements an iterator to "navigate" over a single band (const).
Definition: BandIterator.h:219
std::vector< double > m_logCMinInput
The contrast minimum input greyscale value of each band.
Definition: Contrast.h:148
double m_decorrelationEnhancementRemap_offset1
Definition: Contrast.h:333
static ConstBandIterator begin(const Band *b)
Returns an iterator referring to the first value of the band.
Definition: BandIterator.h:629
bool execDecorrelationEnhancement()
Execute the decorrelation enhancement contrast following the internal parameters. ...
#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:185
unsigned int line
void squareRootRemap(const double &inValue, double &outValue)
Remap on gray level using a square root.
Definition: Contrast.h:370
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
Contrast enhancement.
int b
Definition: TsRtree.cpp:32
bool execSquareContrast()
Execute a square contrast following the internal parameters.
Contrast input parameters.
Definition: Contrast.h:65
static RasterSummaryManager & getInstance()
It returns a reference to the singleton instance.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
#define TERP_LOG_AND_THROW(message)
Logs a error message and throws.
Definition: Macros.h:139
std::vector< unsigned int > m_outRasterBands
Bands to be processed from the output raster.
Definition: Contrast.h:196
Calculate the standard deviation value.
double m_outRangeMax
Maximum value of data type range (default: std::numeric_limits<double>::max().
Definition: Contrast.h:95
BandProperty * getProperty()
Returns the band property.
SummaryTypes
Types for the BandSummary.
URI C++ Library.
Definition: Attributes.h:37
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
std::map< double, double > m_histogramEqualizationRemap_cdf
Definition: Contrast.h:339
void DecorrelationEnhancementRemap(const double &inValue, double &outValue)
Remap on gray level using two offsets and gain.
Definition: Contrast.h:391
Contrast::InputParameters m_inputParameters
Contrast input execution parameters.
Definition: Contrast.h:257
virtual void write(int x, int y, void *buffer)=0
It writes a data block from the specified buffer.
std::vector< unsigned int > m_inRasterBands
Bands to be processed from the input raster.
Definition: Contrast.h:91
boost::ptr_vector< BandSummary > RasterSummary
RasterSummary is just a typedef of a boost::ptr_vector.
Definition: RasterSummary.h:44
bool m_enableProgress
Enable/Disable the progress interface (default:false).
Definition: Contrast.h:97
void Convert2DoublesVector(void *inputVector, const int inputVectorDataType, unsigned int inputVectorSize, double *outputVector)
Convert vector elements.
std::vector< double > m_hECMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:117
bool execSquareRootContrast()
Execute a square root contrast following the internal parameters.
A raster band description.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
Grid * getGrid()
It returns the raster grid.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
std::vector< double > m_sMASCStdInput
The standard deviation to be applied in each band.
Definition: Contrast.h:161
double m_offSetGainRemap_offset1
Definition: Contrast.h:317
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
double m_logRemap_offset
Definition: Contrast.h:329
Abstract parameters base interface.
virtual void read(int x, int y, void *buffer) const =0
It reads a data block to the specified buffer.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false.
Definition: Macros.h:269
double m_logRemap_gain
Definition: Contrast.h:328
std::unique_ptr< te::rst::Raster > m_createdOutRasterPtr
A pointer to the created output raster instance, or an empty pointer empty if the result must be writ...
Definition: Contrast.h:194
bool execHistogramEqualizationContrast()
Execute the histogram equalization contrast following the internal parameters.
std::vector< double > m_squareCMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:128
double m_squareRootRemap_gain
Definition: Contrast.h:325
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
void(Contrast::* RemapFuncPtrT)(const double &inValue, double &outValue)
Type definition for a remapping function pointer.
Definition: Contrast.h:254
bool execLogContrast()
Execute a log contrast following the internal parameters.
A raster (stored in memory and eventually swapped to disk) where it is possible to dynamically add li...
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
double m_offSetGainRemap_gain
Definition: Contrast.h:319
std::vector< double > m_lCMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:108
static Raster * make()
It creates and returns an empty raster with default raster driver.
AbstractParameters * clone() const
Create a clone copy of this instance.
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
bool InversePrincipalComponents(const te::rst::Raster &pcaRaster, const boost::numeric::ublas::matrix< double > &pcaMatrix, te::rst::Raster &outputRaster, const std::vector< unsigned int > &outputRasterBands, const unsigned int maxThreads)
Regenerate the original raster from its principal components.
virtual Raster * getRaster() const =0
Returns the associated raster.
std::vector< double > m_sMASCMeanInput
The mean greyscale to be applied in each band.
Definition: Contrast.h:159
Raster Processing algorithm input parameters base interface.
std::string m_createdOutRasterDSType
Output raster data source type (as described in te::raster::RasterFactory ), leave empty if the resul...
Definition: Contrast.h:198
Raster Processing functions.
int getType() const
It returns the data type of the elements in the band.
Definition: BandProperty.h:113
te::rst::Raster const * m_inRasterPtr
Input raster.
Definition: Contrast.h:89
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
void reset()
Clear all internal allocated objects and reset the algorithm to its initial state.
void offSetGainRemap(const double &inValue, double &outValue)
Remap on gray level using an offset and gain.
Definition: Contrast.h:347
virtual void reset() _NOEXCEPT_OP(false)
Clear all internal allocated objects and reset the algorithm to its initial state.
void histogramEqualizationRemap(const double &inValue, double &outValue)
Remap on gray level using two offsets and gain.
Definition: Contrast.h:403
Contrast::OutputParameters * m_outputParametersPtr
Contrast input execution parameters.
Definition: Contrast.h:258
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
Contrast output parameters.
Definition: Contrast.h:188
std::map< std::string, std::string > m_createdOutRasterInfo
The necessary information to create the raster (as described in te::raster::RasterFactory), leave empty if the result must be written to the raster pointed m_outRasterPtr.
Definition: Contrast.h:200
#define TERP_INSTANCE_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged, the current instance erro...
Definition: Macros.h:200
Calculate the mean value.
virtual int getBlockSize() const
It returns the number of bytes ocuppied by a data block.
double m_offSetGainRemap_offset2
Definition: Contrast.h:318
unsigned int col
bool GetStdDevValue(const te::rst::Band &band, const unsigned int maxThreads, double const *const meanValuePtr, double &stdDevValue)
Get the standard deviation of band pixel values.
Calculate the histogram for the real part.
bool execSetMeanAndStdContrast()
Execute the histogram equalization contrast following the internal parameters.
bool execLinearContrast()
Execute a linear contrast following the internal parameters.
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
std::vector< double > m_squareCMinInput
The contrast minimum input greyscale value of each band.
Definition: Contrast.h:126
void ConvertDoublesVector(double *inputVector, unsigned int inputVectorSize, const int outputVectorDataType, void *outputVector)
Convert a doubles vector.
bool remapBandLevels(const te::rst::Band &inRasterBand, te::rst::Band &outRasterBand, RemapFuncPtrT remapFuncPtr, const bool enableProgress)
Band gray levels remap using a remap function.
#define TERP_INSTANCE_LOG_AND_RETURN_FALSE(message)
Logs a warning message, update the current instance error messsage and return false.
Definition: Macros.h:279
static ConstBandIterator end(const Band *b)
Returns an iterator referring to after the end of the iterator.
Definition: BandIterator.h:634