All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
61  void Contrast::InputParameters::reset() throw( te::rp::Exception )
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_squareCMinInput.clear();
74  m_squareCMaxInput.clear();
75 
76  m_squareRootCMinInput.clear();
77  m_squareRootCMaxInput.clear();
78 
79  m_logCMinInput.clear();
80  m_logCMaxInput.clear();
81 
82  m_sMASCMeanInput.clear();
83  m_sMASCStdInput.clear();
84 
85  m_inRasterPtr = 0;
86  m_inRasterBands.clear();
87  m_enableProgress = false;
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 
102  m_squareCMinInput = params.m_squareCMinInput;
103  m_squareCMaxInput = params.m_squareCMaxInput;
104 
105  m_squareRootCMinInput = params.m_squareRootCMinInput;
106  m_squareRootCMaxInput = params.m_squareRootCMaxInput;
107 
108  m_logCMinInput = params.m_logCMinInput;
109  m_logCMaxInput = params.m_logCMaxInput;
110 
111  m_sMASCMeanInput = params.m_sMASCMeanInput;
112  m_sMASCStdInput = params.m_sMASCStdInput;
113 
114  m_inRasterPtr = params.m_inRasterPtr;
115  m_inRasterBands = params.m_inRasterBands;
116  m_enableProgress = params.m_enableProgress;
117 
118  return *this;
119  }
120 
122  {
123  return new InputParameters( *this );
124  }
125 
127  {
128  reset();
129  }
130 
132  {
133  reset();
134  operator=( other );
135  }
136 
138  {
139  reset();
140  }
141 
142  void Contrast::OutputParameters::reset() throw( te::rp::Exception )
143  {
144  m_outRasterPtr = 0;
145  m_createdOutRasterPtr.reset();
146  m_outRasterBands.clear();
147  m_createdOutRasterDSType.clear();
148  m_createdOutRasterInfo.clear();
149  }
150 
152  const Contrast::OutputParameters& params )
153  {
154  reset();
155 
156  m_outRasterPtr = params.m_outRasterPtr;
157  m_outRasterBands = params.m_outRasterBands;
158  m_createdOutRasterDSType = params.m_createdOutRasterDSType;
159  m_createdOutRasterInfo = params.m_createdOutRasterInfo;
160 
161  return *this;
162  }
163 
165  {
166  return new OutputParameters( *this );
167  }
168 
170  {
171  reset();
172  }
173 
175  {
176  }
177 
179  throw( te::rp::Exception )
180  {
181  TERP_TRUE_OR_RETURN_FALSE( m_isInitialized, "Algoritm not initialized" );
182 
183  // Initializing the output raster
184 
185  m_outputParametersPtr = dynamic_cast<
186  Contrast::OutputParameters* >( &outputParams );
187  TERP_TRUE_OR_RETURN_FALSE( m_outputParametersPtr, "Invalid parameters" );
188 
190  {
192 
193  std::vector< te::rst::BandProperty* > bandsProperties;
194  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
195  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
196  {
197  assert( m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] <
199 
200  bandsProperties.push_back( new te::rst::BandProperty(
203  inRasterBandsIdx ] )->getProperty() ) ) );
204 
205  m_outputParametersPtr->m_outRasterBands.push_back( inRasterBandsIdx );
206  }
207 
212  bandsProperties,
214  0,
215  0 ) );
217  "Output raster creation error" );
218 
221  }
222  else
223  {
229  {
230  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
231  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
232  {
234  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] <
236  "Invalid output raster band" )
237  }
238  }
239  else
240  {
241  TERP_LOG_AND_RETURN_FALSE( "Invalid output raster" );
242  }
243  }
244 
245  // Executing the contrast on the selected bands
246 
247  switch( m_inputParameters.m_type )
248  {
250  {
251  return execLinearContrast();
252  break;
253  }
255  {
257  break;
258  }
260  {
261  return execSquareContrast();
262  break;
263  }
265  {
266  return execSquareRootContrast();
267  break;
268  }
270  {
271  return execLogContrast();
272  break;
273  }
275  {
276  return execSetMeanAndStdContrast();
277  break;
278  }
280  {
282  break;
283  }
284  default :
285  {
286  TERP_LOG_AND_THROW( "Invalid contrast type" );
287  break;
288  }
289  }
290  }
291 
292  void Contrast::reset() throw( te::rp::Exception )
293  {
296  m_isInitialized = false;
297  }
298 
300  throw( te::rp::Exception )
301  {
302  reset();
303 
304  Contrast::InputParameters const* inputParamsPtr = dynamic_cast<
305  Contrast::InputParameters const* >( &inputParams );
306  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr, "Invalid parameters" );
307 
308  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_inRasterPtr,
309  "Invalid raster pointer" );
312  "Invalid raster" );
313 
314  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_inRasterBands.size() > 0,
315  "Invalid bands number" );
316 
317  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
318  inputParamsPtr->m_inRasterBands.size() ; ++inRasterBandsIdx )
319  {
321  inputParamsPtr->m_inRasterBands[ inRasterBandsIdx ] <
322  inputParamsPtr->m_inRasterPtr->getNumberOfBands(),
323  "Invalid input raster band" );
324  }
325 
326  // Checking contrast specifi parameters
327 
328  switch( inputParamsPtr->m_type )
329  {
331  {
332  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_lCMinInput.size() ==
333  inputParamsPtr->m_inRasterBands.size(),
334  "Invalid parameter m_lCMinInput" );
335  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_lCMaxInput.size() ==
336  inputParamsPtr->m_inRasterBands.size(),
337  "Invalid parameter m_lCMaxInput" );
338 
339  break;
340  }
342  {
343  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_hECMaxInput.size() ==
344  inputParamsPtr->m_inRasterBands.size(),
345  "Invalid parameter m_hECMaxInput" );
346 
347  break;
348  }
350  {
351  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_squareCMinInput.size() ==
352  inputParamsPtr->m_inRasterBands.size(),
353  "Invalid parameter m_squareCMinInput" );
354  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_squareCMaxInput.size() ==
355  inputParamsPtr->m_inRasterBands.size(),
356  "Invalid parameter m_squareCMaxInput" );
357 
358  break;
359  }
361  {
362  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_squareRootCMinInput.size() ==
363  inputParamsPtr->m_inRasterBands.size(),
364  "Invalid parameter m_squareRootCMinInput" );
365  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_squareRootCMaxInput.size() ==
366  inputParamsPtr->m_inRasterBands.size(),
367  "Invalid parameter m_squareRootRCMaxInput" );
368 
369  break;
370  }
372  {
373  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_logCMinInput.size() ==
374  inputParamsPtr->m_inRasterBands.size(),
375  "Invalid parameter m_logCMinInput" );
376  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_logCMaxInput.size() ==
377  inputParamsPtr->m_inRasterBands.size(),
378  "Invalid parameter m_logCMaxInput" );
379 
380  break;
381  }
383  {
384  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_sMASCMeanInput.size() ==
385  inputParamsPtr->m_inRasterBands.size(),
386  "Invalid parameter m_sMASCMeanInput" );
387  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr->m_sMASCStdInput.size() ==
388  inputParamsPtr->m_inRasterBands.size(),
389  "Invalid parameter m_sMASCStdInput" );
390  break;
391  }
393  {
394  break;
395  }
396  default :
397  {
398  TERP_LOG_AND_THROW( "Invalid contrast type" );
399  break;
400  }
401  }
402 
403  m_inputParameters = *inputParamsPtr;
404  m_isInitialized = true;
405 
406  return true;
407  }
408 
410  {
411  return m_isInitialized;
412  }
413 
415  {
418 
419  const bool enableGlobalProgress = m_inputParameters.m_enableProgress &&
420  ( m_inputParameters.m_inRasterBands.size() > 1 );
421  std::auto_ptr< te::common::TaskProgress > progressPtr;
422  if( enableGlobalProgress )
423  {
424  progressPtr.reset( new te::common::TaskProgress );
425  progressPtr->setMessage( "Contrast" );
426  progressPtr->setTotalSteps( m_inputParameters.m_inRasterBands.size() );
427  }
428 
429  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
430  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
431  {
432  te::rst::Band const* inRasterBandPtr = m_inputParameters.m_inRasterPtr->getBand(
433  m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] );
435  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] );
436 
437  double outRangeMin = 0.0;
438  double outRangeMax = 0.0;
439  GetDataTypeRange( outRasterBandPtr->getProperty()->getType(),
440  outRangeMin, outRangeMax );
441  const double outRasterRange = outRangeMax - outRangeMin;
442 
443  const double inRasterRange = m_inputParameters.m_lCMaxInput[ inRasterBandsIdx ] -
444  m_inputParameters.m_lCMinInput[ inRasterBandsIdx ];
445 
446  if( inRasterRange != 0.0 )
447  {
448  m_offSetGainRemap_gain = outRasterRange / inRasterRange;
449  m_offSetGainRemap_offset1 = (-1.0) * m_inputParameters.m_lCMinInput[ inRasterBandsIdx ];
450  m_offSetGainRemap_offset2 = outRangeMin;
451  }
452  else
453  {
457  }
458 
459  if( ! remapBandLevels( *inRasterBandPtr, *outRasterBandPtr,
461  (!enableGlobalProgress) ) )
462  {
463  return false;
464  }
465 
466  if( enableGlobalProgress )
467  {
468  progressPtr->pulse();
469  if( ! progressPtr->isActive() ) return false;
470  }
471  }
472 
473  return true;
474  }
475 
477  {
480 
481  const te::rst::RasterSummary* rsummary =
484 
485  double value;
486  double newvalue;
487  unsigned int N = m_inputParameters.m_inRasterPtr->getNumberOfRows() *
489 
490  std::auto_ptr< te::common::TaskProgress > progressPtr;
492  {
493  progressPtr.reset( new te::common::TaskProgress );
494  progressPtr->setMessage( "Contrast" );
495  progressPtr->setTotalSteps( m_inputParameters.m_inRasterBands.size() );
496  }
497 
498  for( unsigned int b = 0 ; b < m_inputParameters.m_inRasterBands.size() ; b++ )
499  {
500  const double lutfactor =
501  m_inputParameters.m_hECMaxInput[ b ] / (double) N;
502 
503  unsigned int niband = m_inputParameters.m_inRasterBands[b];
504  unsigned int noband = m_outputParametersPtr->m_outRasterBands[b];
505 
506  const te::rst::Band* iband = m_inputParameters.m_inRasterPtr->getBand(niband);
508 
509  double outRangeMin = 0.0;
510  double outRangeMax = 0.0;
511  GetDataTypeRange( oband->getProperty()->getType(),
512  outRangeMin, outRangeMax );
513 
518 
519  std::map<double, double> lut;
520  const double minp = rsummary->at(niband).m_minVal->real();
521  const double maxp = rsummary->at(niband).m_maxVal->real();
522  for (double pixel = minp; pixel <= maxp; pixel++)
523  {
524  newvalue = 0.0;
525  for (double nj = minp; nj <= pixel; nj++)
526  newvalue += rsummary->at(niband).m_histogramR->operator[](nj);
527  lut[pixel] = lutfactor * newvalue;
528  }
529 
530  while (ibandit != ibanditend)
531  {
532  value = lut[ *ibandit ];
533  value = std::max( outRangeMin, value );
534  value = std::min( outRangeMax, value );
535  oband->setValue(ibandit.getColumn(), ibandit.getRow(), value);
536  ++ibandit;
537  }
538 
540  {
541  progressPtr->pulse();
542  if( ! progressPtr->isActive() ) return false;
543  }
544  }
545 
546  return true;
547  }
548 
550  {
553 
554  const bool enableGlobalProgress = m_inputParameters.m_enableProgress &&
555  ( m_inputParameters.m_inRasterBands.size() > 1 );
556  std::auto_ptr< te::common::TaskProgress > progressPtr;
557  if( enableGlobalProgress )
558  {
559  progressPtr.reset( new te::common::TaskProgress );
560  progressPtr->setMessage( "Contrast" );
561  progressPtr->setTotalSteps( m_inputParameters.m_inRasterBands.size() );
562  }
563 
564  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
565  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
566  {
567  te::rst::Band const* inRasterBandPtr = m_inputParameters.m_inRasterPtr->getBand(
568  m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] );
570  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] );
571 
572  double outRangeMin = 0.0;
573  double outRangeMax = 0.0;
574  GetDataTypeRange( outRasterBandPtr->getProperty()->getType(),
575  outRangeMin, outRangeMax );
576  const double outRasterRange = outRangeMax - outRangeMin;
577 
578  const double inRasterRange = m_inputParameters.m_squareCMaxInput[ inRasterBandsIdx ] -
579  m_inputParameters.m_squareCMinInput[ inRasterBandsIdx ];
580 
581  if( inRasterRange != 0.0 )
582  {
583  m_squareRemap_factor = outRasterRange / std::pow( inRasterRange, 2.0 );
584  }
585  else
586  {
587  m_squareRemap_factor = 0.0;
588  }
589 
590  if( ! remapBandLevels( *inRasterBandPtr, *outRasterBandPtr,
592  (!enableGlobalProgress) ) )
593  {
594  return false;
595  }
596 
597  if( enableGlobalProgress )
598  {
599  progressPtr->pulse();
600  if( ! progressPtr->isActive() ) return false;
601  }
602  }
603 
604  return true;
605  }
606 
608  {
611 
612  const bool enableGlobalProgress = m_inputParameters.m_enableProgress &&
613  ( m_inputParameters.m_inRasterBands.size() > 1 );
614  std::auto_ptr< te::common::TaskProgress > progressPtr;
615  if( enableGlobalProgress )
616  {
617  progressPtr.reset( new te::common::TaskProgress );
618  progressPtr->setMessage( "Contrast" );
619  progressPtr->setTotalSteps( m_inputParameters.m_inRasterBands.size() );
620  }
621 
622  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
623  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
624  {
625  te::rst::Band const* inRasterBandPtr = m_inputParameters.m_inRasterPtr->getBand(
626  m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] );
628  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] );
629 
630  double outRangeMin = 0.0;
631  double outRangeMax = 0.0;
632  GetDataTypeRange( outRasterBandPtr->getProperty()->getType(),
633  outRangeMin, outRangeMax );
634  const double outRasterRange = outRangeMax - outRangeMin;
635 
636  const double inRasterRange = m_inputParameters.m_squareRootCMaxInput[ inRasterBandsIdx ] -
637  m_inputParameters.m_squareRootCMinInput[ inRasterBandsIdx ];
638 
639  if( inRasterRange != 0.0 )
640  {
641  m_squareRootRemap_gain = outRasterRange / std::sqrt( inRasterRange );
642  }
643  else
644  {
646  }
647 
648  if( ! remapBandLevels( *inRasterBandPtr, *outRasterBandPtr,
650  (!enableGlobalProgress) ) )
651  {
652  return false;
653  }
654 
655  if( enableGlobalProgress )
656  {
657  progressPtr->pulse();
658  if( ! progressPtr->isActive() ) return false;
659  }
660  }
661 
662  return true;
663  }
664 
666  {
669 
670  const bool enableGlobalProgress = m_inputParameters.m_enableProgress &&
671  ( m_inputParameters.m_inRasterBands.size() > 1 );
672  std::auto_ptr< te::common::TaskProgress > progressPtr;
673  if( enableGlobalProgress )
674  {
675  progressPtr.reset( new te::common::TaskProgress );
676  progressPtr->setMessage( "Contrast" );
677  progressPtr->setTotalSteps( m_inputParameters.m_inRasterBands.size() );
678  }
679 
680  for( unsigned int inRasterBandsIdx = 0 ; inRasterBandsIdx <
681  m_inputParameters.m_inRasterBands.size() ; ++inRasterBandsIdx )
682  {
683  te::rst::Band const* inRasterBandPtr = m_inputParameters.m_inRasterPtr->getBand(
684  m_inputParameters.m_inRasterBands[ inRasterBandsIdx ] );
686  m_outputParametersPtr->m_outRasterBands[ inRasterBandsIdx ] );
687 
688  double outRangeMin = 0.0;
689  double outRangeMax = 0.0;
690  GetDataTypeRange( outRasterBandPtr->getProperty()->getType(),
691  outRangeMin, outRangeMax );
692  const double outRasterRange = outRangeMax - outRangeMin;
693 
694  const double inRasterRange = m_inputParameters.m_logCMaxInput[ inRasterBandsIdx ] -
695  m_inputParameters.m_logCMinInput[ inRasterBandsIdx ];
696 
697  m_logRemap_offset = -1.0 * m_inputParameters.m_logCMinInput[ inRasterBandsIdx ];
698 
699  if( inRasterRange != 0.0 )
700  {
701  m_logRemap_gain = outRasterRange / std::log10( inRasterRange + 1.0 );
702  }
703  else
704  {
705  m_logRemap_gain = 0.0;
706  }
707 
708  if( ! remapBandLevels( *inRasterBandPtr, *outRasterBandPtr,
710  (!enableGlobalProgress) ) )
711  {
712  return false;
713  }
714 
715  if( enableGlobalProgress )
716  {
717  progressPtr->pulse();
718  if( ! progressPtr->isActive() ) return false;
719  }
720  }
721 
722  return true;
723  }
724 
726  {
729 
730  const te::rst::RasterSummary* rsummary =
734 
735  std::auto_ptr< te::common::TaskProgress > progressPtr;
737  {
738  progressPtr.reset( new te::common::TaskProgress );
739  progressPtr->setMessage( "Contrast" );
740  progressPtr->setTotalSteps( m_inputParameters.m_inRasterBands.size() *
742  }
743 
744  for( unsigned int b = 0 ; b < m_inputParameters.m_inRasterBands.size() ; b++ )
745  {
746  unsigned int niband = m_inputParameters.m_inRasterBands[b];
747  unsigned int noband = m_outputParametersPtr->m_outRasterBands[b];
748 
749  const te::rst::Band* iband = m_inputParameters.m_inRasterPtr->getBand(niband);
751 
752  double outRangeMin = 0.0;
753  double outRangeMax = 0.0;
754  GetDataTypeRange( oband->getProperty()->getType(),
755  outRangeMin, outRangeMax );
756 
761 
762  const double meanp = rsummary->at(niband).m_meanVal->real();
763  const double stdp = rsummary->at(niband).m_stdVal->real();
764  const double offset = m_inputParameters.m_sMASCMeanInput[ b ] /
766  const double c1 = m_inputParameters.m_sMASCStdInput[ b ] / stdp;
767  const double c2 = offset * m_inputParameters.m_sMASCStdInput[ b ];
768 
769  double value;
770  double newvalue;
771 
772  for (unsigned r = 0; r < iband->getRaster()->getNumberOfRows(); r++)
773  {
774  for (unsigned c = 0; c < iband->getRaster()->getNumberOfColumns(); c++)
775  {
776  iband->getValue(c, r, value);
777  newvalue = (value - meanp) * c1 + c2;
778  newvalue = std::max( outRangeMin, newvalue );
779  newvalue = std::min( outRangeMax, newvalue );
780  oband->setValue(c, r, newvalue);
781  }
782 
784  {
785  progressPtr->pulse();
786  if( ! progressPtr->isActive() ) return false;
787  }
788  }
789  }
790 
791  return true;
792  }
793 
795  {
798 
799  // Progress interface
800 
801  std::auto_ptr< te::common::TaskProgress > progressPtr;
803  {
804  progressPtr.reset( new te::common::TaskProgress );
805  progressPtr->setMessage( "Contrast" );
806  progressPtr->setTotalSteps( m_inputParameters.m_inRasterBands.size() +
807  2 );
808  }
809 
810  // Compute PCA space raster
811 
812  std::auto_ptr< te::rst::Raster > pcaRasterPtr;
813  boost::numeric::ublas::matrix< double > pcaMatrix;
814 
815  {
816  te::rst::Grid* gridPtr = new te::rst::Grid(
818  std::vector< te::rst::BandProperty * > bandProperties;
819  std::vector< unsigned int > pcaRasterBands;
820 
821  for( unsigned int bandIdx = 0 ; bandIdx <
822  m_inputParameters.m_inRasterBands.size() ; ++bandIdx )
823  {
824  bandProperties.push_back( new te::rst::BandProperty(
826  bandProperties[ bandIdx ]->m_type = te::dt::DOUBLE_TYPE;
827 
828  pcaRasterBands.push_back( bandIdx );
829  }
830 
831  try
832  {
833  pcaRasterPtr.reset( new te::mem::ExpansibleRaster( 25, gridPtr,
834  bandProperties ) );
835  }
836  catch( te::common::Exception& e )
837  {
839  }
840 
843  pcaMatrix, *pcaRasterPtr, pcaRasterBands, 0 ),
844  "Principal components generation error" );
845 
846 // te::rp::Copy2DiskRaster( *pcaRasterPtr, "pcaRaster.tif" );
847  }
848 
850  {
851  progressPtr->pulse();
852  if( ! progressPtr->isActive() ) return false;
853  }
854 
855  // The reference for enhancement: mean and std dev from the first PCA band
856 
857  double pca0MeanValue = 0;
859  *pcaRasterPtr->getBand( 0 ), 0, pca0MeanValue ),
860  "Mean value calcule error" );
861 
862  double pca0StdDevValue = 0;
864  *pcaRasterPtr->getBand( 0 ), 0, &pca0MeanValue,
865  pca0StdDevValue ), "StdDev value calcule error" );
866 
867  // Enhancing PCA
868 
869  for( unsigned int pcaBandIdx = 1 ; pcaBandIdx <
870  m_inputParameters.m_inRasterBands.size() ; ++pcaBandIdx )
871  {
872  te::rst::Band& pcaBand = *pcaRasterPtr->getBand( pcaBandIdx );
873 
874  double meanValue = 0;
875  TERP_TRUE_OR_RETURN_FALSE( te::rp::GetMeanValue( pcaBand, 0, meanValue ),
876  "Mean value calcule error" );
877 
878  double stdDevValue = 0;
879  TERP_TRUE_OR_RETURN_FALSE( te::rp::GetStdDevValue( pcaBand, 0, &meanValue,
880  stdDevValue ), "StdDev value calcule error" );
881 
882  m_offSetGainRemap_offset1 = -1.0 * meanValue;
883  m_offSetGainRemap_gain = ( stdDevValue == 0.0 ) ? 0.0 : ( pca0StdDevValue /
884  stdDevValue );
885  m_offSetGainRemap_offset2 = pca0MeanValue;
886 
887  if( ! remapBandLevels( pcaBand, pcaBand,
889  {
890  return false;
891  }
892 
894  {
895  progressPtr->pulse();
896  if( ! progressPtr->isActive() ) return false;
897  }
898  }
899 
900  // Generating the output enhanced raster
901 
905  "Inverse PCA error" );
906 
908  {
909  progressPtr->pulse();
910  if( ! progressPtr->isActive() ) return false;
911  }
912 
913  return true;
914  }
915 
916  bool Contrast::remapBandLevels( const te::rst::Band& inRasterBand,
917  te::rst::Band& outRasterBand, RemapFuncPtrT remapFuncPtr,
918  const bool enableProgress )
919  {
920  const unsigned int inBlkWidthPixels = inRasterBand.getProperty()->m_blkw;
921  const unsigned int inBlkHeightPixels = inRasterBand.getProperty()->m_blkh;
922  const unsigned int outBlkWidthPixels = outRasterBand.getProperty()->m_blkw;
923  const unsigned int outBlkHeightPixels = outRasterBand.getProperty()->m_blkh;
924  double outRangeMin = 0.0;
925  double outRangeMax = 0.0;
926  GetDataTypeRange( outRasterBand.getProperty()->getType(),
927  outRangeMin, outRangeMax );
928 
929  std::auto_ptr< te::common::TaskProgress > progressPtr;
930  if( enableProgress )
931  {
932  progressPtr.reset( new te::common::TaskProgress );
933  progressPtr->setMessage( "Contrast" );
934  }
935 
936  if( ( inBlkWidthPixels == outBlkWidthPixels ) &&
937  ( inBlkHeightPixels == outBlkHeightPixels ) )
938  { // block version
939  const unsigned int blockSizePixels = inBlkWidthPixels *
940  inBlkHeightPixels;
941  const unsigned int xBlocksNmb = inRasterBand.getProperty()->m_nblocksx;
942  const unsigned int yBlocksNmb = inRasterBand.getProperty()->m_nblocksy;
943  unsigned char* inputBuffer = new unsigned char[ inRasterBand.getBlockSize() ];
944  unsigned char* outputBuffer = new unsigned char[ outRasterBand.getBlockSize() ];
945  double* inDoublesBuffer = new double[ blockSizePixels ];
946  double* outDoublesBuffer = new double[ blockSizePixels ];
947  const int inputVectorDataType = inRasterBand.getProperty()->getType();
948  const int outputVectorDataType = outRasterBand.getProperty()->getType();
949  unsigned int blockXIndex = 0;
950  unsigned int blockOffset = 0;
951  double outValue = 0;
952 
953  if( enableProgress ) progressPtr->setTotalSteps( yBlocksNmb * xBlocksNmb );
954 
955  for( unsigned int blockYIndex = 0 ; blockYIndex < yBlocksNmb ;
956  ++blockYIndex )
957  {
958  for( blockXIndex = 0 ; blockXIndex < xBlocksNmb ;
959  ++blockXIndex )
960  {
961  inRasterBand.read( blockXIndex, blockYIndex, inputBuffer );
962 
963  Convert2DoublesVector( inputBuffer, inputVectorDataType,
964  blockSizePixels, inDoublesBuffer );
965 
966  for( blockOffset = 0 ; blockOffset < blockSizePixels ; ++blockOffset )
967  {
968  (this->*remapFuncPtr)( inDoublesBuffer[blockOffset],
969  outValue);
970  outDoublesBuffer[blockOffset] = std::max( outRangeMin, std::min(
971  outRangeMax, outValue ) );
972  }
973 
974  ConvertDoublesVector( outDoublesBuffer, blockSizePixels,
975  outputVectorDataType, outputBuffer );
976 
977  outRasterBand.write( blockXIndex, blockYIndex, outputBuffer );
978 
979  if( enableProgress )
980  {
981  progressPtr->pulse();
982  if( ! progressPtr->isActive() ) return false;
983  }
984  }
985  }
986 
987  delete[] inputBuffer;
988  delete[] outputBuffer;
989  delete[] inDoublesBuffer;
990  delete[] outDoublesBuffer;
991  }
992  else
993  { // pixel by pixel version
994  const unsigned int linesNumber = m_inputParameters.m_inRasterPtr->getNumberOfRows();
995  const unsigned int columnsNumber = m_inputParameters.m_inRasterPtr->getNumberOfColumns();
996 
997  if( enableProgress ) progressPtr->setTotalSteps( linesNumber );
998 
999  unsigned int col = 0;
1000  double inputValue = 0;
1001  double outputValue = 0;
1002 
1003  for( unsigned int line = 0 ; line < linesNumber ; ++line )
1004  {
1005  for( col = 0 ; col < columnsNumber ; ++col )
1006  {
1007  inRasterBand.getValue( col, line, inputValue );
1008  (this->*remapFuncPtr)( inputValue, outputValue );
1009  outRasterBand.setValue( col, line, std::max( outRangeMin, std::min(
1010  outRangeMax, outputValue ) ) );
1011  }
1012 
1013  if( enableProgress )
1014  {
1015  progressPtr->pulse();
1016  if( ! progressPtr->isActive() ) return false;
1017  }
1018  }
1019  }
1020 
1021  return true;
1022  }
1023 
1024  } // end namespace rp
1025 } // end namespace te
1026 
bool GetMeanValue(const te::rst::Band &band, const unsigned int maxThreads, double &meanValue)
Get the mean of band pixel values.
Definition: Functions.cpp:1086
std::vector< double > m_logCMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:146
std::vector< double > m_lCMinInput
The contrast minimum input greyscale value of each band.
Definition: Contrast.h:102
double m_squareRemap_factor
Definition: Contrast.h:302
bool m_isInitialized
Tells if this instance is initialized.
Definition: Contrast.h:240
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:188
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
ContrastType m_type
The contrast type to be applied.
Definition: Contrast.h:87
A raster band description.
Definition: BandProperty.h:61
void squareRemap(const double &inValue, double &outValue)
Remap on gray level using a square.
Definition: Contrast.h:330
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Definition: Raster.cpp:213
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
virtual const char * what() const
It outputs the exception message.
Definition: Exception.cpp:58
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:133
void logRemap(const double &inValue, double &outValue)
Remap on gray level using a log.
Definition: Contrast.h:352
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: Contrast.cpp:61
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)...
Definition: Functions.h:180
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
Raster Processing algorithm output parameters base interface.
std::vector< double > m_squareRootCMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:135
const OutputParameters & operator=(const OutputParameters &params)
Definition: Contrast.cpp:151
virtual void read(int x, int y, void *buffer) const =0
It reads a data block to the specified buffer.
AbstractParameters * clone() const
Create a clone copy of this instance.
Definition: Contrast.cpp:164
const InputParameters & operator=(const InputParameters &params)
Definition: Contrast.cpp:90
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.
Definition: Functions.cpp:1504
This class implements an iterator to "navigate" over a single band (const).
Definition: BandIterator.h:211
std::vector< double > m_logCMinInput
The contrast minimum input greyscale value of each band.
Definition: Contrast.h:144
static ConstBandIterator begin(const Band *b)
Returns an iterator referring to the first value of the band.
Definition: BandIterator.h:592
Raster Processing functions.
bool execDecorrelationEnhancement()
Execute the decorrelation enhancement contrast following the internal parameters. ...
Definition: Contrast.cpp:794
#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
void squareRootRemap(const double &inValue, double &outValue)
Remap on gray level using a square root.
Definition: Contrast.h:341
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
Definition: Raster.cpp:89
Contrast enhancement.
bool execSquareContrast()
Execute a square contrast following the internal parameters.
Definition: Contrast.cpp:549
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.
Definition: Raster.cpp:208
#define TERP_LOG_AND_THROW(message)
Logs a error message and throws.
Definition: Macros.h:138
std::vector< unsigned int > m_outRasterBands
Bands to be processed from the output raster.
Definition: Contrast.h:192
Calculate the standard deviation value.
Definition: Enums.h:42
BandProperty * getProperty()
Returns the band property.
Definition: Band.cpp:428
SummaryTypes
Types for the BandSummary.
Definition: Enums.h:38
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
virtual Raster * getRaster() const =0
Returns the associated raster.
Contrast::InputParameters m_inputParameters
Contrast input execution parameters.
Definition: Contrast.h:237
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:93
void Convert2DoublesVector(void *inputVector, const int inputVectorDataType, unsigned int inputVectorSize, double *outputVector)
Convert vector elements.
Definition: Functions.cpp:331
std::vector< double > m_hECMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:113
bool execSquareRootContrast()
Execute a square root contrast following the internal parameters.
Definition: Contrast.cpp:607
A raster band description.
Definition: Band.h:63
Grid * getGrid()
It returns the raster grid.
Definition: Raster.cpp:94
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
std::vector< double > m_sMASCStdInput
The standard deviation to be applied in each band.
Definition: Contrast.h:157
double m_offSetGainRemap_offset1
Definition: Contrast.h:297
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
std::auto_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:190
double m_logRemap_offset
Definition: Contrast.h:310
Abstract parameters base interface.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
Definition: Contrast.cpp:142
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false.
Definition: Macros.h:236
double m_logRemap_gain
Definition: Contrast.h:309
bool execHistogramEqualizationContrast()
Execute the histogram equalization contrast following the internal parameters.
Definition: Contrast.cpp:476
std::vector< double > m_squareCMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:124
double m_squareRootRemap_gain
Definition: Contrast.h:306
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
Definition: Contrast.cpp:299
bool execLogContrast()
Execute a log contrast following the internal parameters.
Definition: Contrast.cpp:665
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.
Definition: Contrast.cpp:409
double m_offSetGainRemap_gain
Definition: Contrast.h:299
std::vector< double > m_lCMaxInput
The contrast maximum input greyscale value of each band.
Definition: Contrast.h:104
static Raster * make()
It creates and returns an empty raster with default raster driver.
AbstractParameters * clone() const
Create a clone copy of this instance.
Definition: Contrast.cpp:121
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
Definition: Contrast.cpp:178
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.
Definition: Functions.cpp:1594
std::vector< double > m_sMASCMeanInput
The mean greyscale to be applied in each band.
Definition: Contrast.h:155
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:194
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
void(Contrast::* RemapFuncPtrT)(const double &inValue, double &outValue)
Type definition for a remapping function pointer.
Definition: Contrast.h:234
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.
Definition: Contrast.cpp:292
void offSetGainRemap(const double &inValue, double &outValue)
Remap on gray level using an offset and gain.
Definition: Contrast.h:318
Contrast::OutputParameters * m_outputParametersPtr
Contrast input execution parameters.
Definition: Contrast.h:238
A rectified grid is the spatial support for raster data.
Definition: Grid.h:68
Contrast output parameters.
Definition: Contrast.h:184
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:196
Calculate the mean value.
Definition: Enums.h:43
virtual int getBlockSize() const
It returns the number of bytes ocuppied by a data block.
Definition: Band.cpp:630
double m_offSetGainRemap_offset2
Definition: Contrast.h:298
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.
Definition: Functions.cpp:1211
Calculate the histogram for the real part.
Definition: Enums.h:44
bool execSetMeanAndStdContrast()
Execute the histogram equalization contrast following the internal parameters.
Definition: Contrast.cpp:725
bool execLinearContrast()
Execute a linear contrast following the internal parameters.
Definition: Contrast.cpp:414
std::vector< double > m_squareCMinInput
The contrast minimum input greyscale value of each band.
Definition: Contrast.h:122
void ConvertDoublesVector(double *inputVector, unsigned int inputVectorSize, const int outputVectorDataType, void *outputVector)
Convert a doubles vector.
Definition: Functions.cpp:443
bool remapBandLevels(const te::rst::Band &inRasterBand, te::rst::Band &outRasterBand, RemapFuncPtrT remapFuncPtr, const bool enableProgress)
Band gray levels remap using a remap function.
Definition: Contrast.cpp:916
static ConstBandIterator end(const Band *b)
Returns an iterator referring to after the end of the iterator.
Definition: BandIterator.h:597