29 #include "../raster/BandProperty.h"
30 #include "../raster/RasterFactory.h"
31 #include "../raster/Band.h"
32 #include "../raster/Grid.h"
33 #include "../geometry/Envelope.h"
34 #include "../common/progress/TaskProgress.h"
40 #define M_PI 3.14159265358979323846
66 m_lowResRasterPtr = 0;
67 m_lowResRasterRedBandIndex = 0;
68 m_lowResRasterGreenBandIndex = 1;
69 m_lowResRasterBlueBandIndex = 2;
70 m_highResRasterPtr = 0;
71 m_highResRasterBand = 0;
72 m_enableProgress =
false;
122 m_outputRasterPtr.reset();
151 throw( te::rp::Exception )
161 std::auto_ptr< te::common::TaskProgress > progressPtr;
166 progressPtr->setTotalSteps( 4 );
168 progressPtr->setMessage(
"Fusing images" );
176 "Unable to get RGB range" );
180 progressPtr->pulse();
181 if( ! progressPtr->isActive() )
return false;
194 hueData, saturationData ),
"Error loading IHS data" );
198 progressPtr->pulse();
199 if( ! progressPtr->isActive() )
return false;
209 "Intensity channel swap error" );
215 progressPtr->pulse();
216 if( ! progressPtr->isActive() )
return false;
222 hueData, saturationData, outParamsPtr->
m_rType, outParamsPtr->
m_rInfo,
224 "RGB raster creation error" );
228 progressPtr->pulse();
229 if( ! progressPtr->isActive() )
return false;
242 throw( te::rp::Exception )
255 "Invalid low Resolution Raster Pointer" )
264 "Invalid raster band" );
269 "Invalid raster band" );
274 "Invalid raster band" );
279 "Invalid high resolution Raster Pointer" )
288 "Invalid raster band" );
321 rgbMin = std::numeric_limits<double>::max();
322 rgbMax = -1.0 * std::numeric_limits<double>::max();
324 unsigned int row = 0;
325 unsigned int col = 0;
327 double greenValue = 0;
328 double blueValue = 0;
330 for( row = 0 ; row < nRows ; ++row )
332 for( col = 0 ; col < nCols ; ++col )
334 redBand.
getValue( col, row, redValue );
335 greenBand.
getValue( col, row, greenValue );
336 blueBand.
getValue( col, row, blueValue );
338 if( ( redValue != redNoData ) && ( greenValue != greenNoData ) &&
339 ( blueValue != blueNoData ) )
341 if( redValue > rgbMax ) rgbMax = redValue;
342 if( greenValue > rgbMax ) rgbMax = greenValue;
343 if( blueValue > rgbMax ) rgbMax = blueValue;
345 if( redValue < rgbMin ) rgbMin = redValue;
346 if( greenValue < rgbMin ) rgbMin = greenValue;
347 if( blueValue < rgbMin ) rgbMin = blueValue;
367 const double colsRescaleFactor =
370 const double rowsRescaleFactor =
383 if( ! intensityData.
reset( outNRows, outNCols ) )
return false;
384 if( ! hueData.
reset( outNRows, outNCols ) )
return false;
385 if( ! saturationData.
reset( outNRows, outNCols ) )
return false;
389 unsigned int outRow = 0;
390 unsigned int outCol = 0;
393 std::complex< double > redC = 0;
394 std::complex< double > greenC = 0;
395 std::complex< double > blueC = 0;
396 float* intensityRow = 0;
398 float* saturationRow = 0;
401 double redNorm = 0, greenNorm = 0, blueNorm = 0;
402 double rMinusG = 0, rMinusB = 0;
405 const double twoPi = 2.0 * ((double)
M_PI);
406 const double pi2 = ((double)
M_PI) / 2.0;
407 const double rgbNormFac = ( rgbMax == rgbMin ) ? 0.0 :
408 ( 1.0 / ( rgbMax - rgbMin ) );
410 for( outRow = 0 ; outRow < outNRows ; ++outRow )
412 inRow = ((double)outRow) * rowsRescaleFactor;
413 intensityRow = intensityData[ outRow ];
414 hueRow = hueData[ outRow ];
415 saturationRow = saturationData[ outRow ];
417 for( outCol = 0 ; outCol < outNCols ; ++outCol )
419 inCol = ((double)outCol) * colsRescaleFactor;
421 interpol.
getValue( inCol, inRow, redC, redBandIdx );
422 interpol.
getValue( inCol, inRow, greenC, greenBandIdx );
423 interpol.
getValue( inCol, inRow, blueC, blueBandIdx );
425 if( ( redC.real() == redNoData ) || ( greenC.real() == greenNoData ) ||
426 ( blueC.real() == blueNoData ) )
428 intensityRow[ outCol ] = 0.0;
429 hueRow[ outCol ] = 0.0;
430 saturationRow[ outCol ] = 0.0;
434 if( ( redC.real() == greenC.real() ) && ( greenC.real() == blueC.real() ) )
442 hueRow[ outCol ] = 0.0;
443 saturationRow[ outCol ] = 0.0;
444 intensityRow[ outCol ] = (float)( redC.real() * rgbNormFac );
448 redNorm = ( redC.real() - rgbMin ) * rgbNormFac;
449 greenNorm = ( greenC.real() - rgbMin ) * rgbNormFac;
450 blueNorm = ( blueC.real() - rgbMin ) * rgbNormFac;
452 rMinusG = redNorm - greenNorm;
453 rMinusB = redNorm - blueNorm;
455 cosValue = sqrt( ( rMinusG * rMinusG ) + ( rMinusB *
456 ( greenNorm - blueNorm ) ) );
458 if( cosValue == 0.0 )
464 cosValue = ( 0.5 * ( rMinusG + rMinusB ) ) /
466 teta = std::acos( cosValue );
469 assert( ( cosValue >= (-1.0) ) && ( cosValue <= (1.0) ) );
471 if( blueNorm > greenNorm )
473 hueRow[ outCol ] = (float)( twoPi - teta );
477 hueRow[ outCol ] = (float)teta;
480 rgbSum = ( redNorm + greenNorm + blueNorm );
482 saturationRow[ outCol ] = (float)( 1.0 - ( 3 * std::min( std::min( redNorm, greenNorm ), blueNorm ) /
485 intensityRow[ outCol ] = (float)( rgbSum / 3.0 );
495 float& variance )
const
500 if( ( nRows == 0 ) || ( nCols == 0 ) )
return false;
502 unsigned int col = 0;
503 unsigned int row = 0;
504 float const * rowPtr = 0;
508 for( row = 0 ; row < nRows ; ++row )
510 rowPtr = matrix[ row ];
512 for( col = 0 ; col < nCols ; ++col )
514 mean += rowPtr[ col ];
518 mean /= (float)( nCols * nRows );
523 for( row = 0 ; row < nRows ; ++row )
525 rowPtr = matrix[ row ];
527 for( col = 0 ; col < nCols ; ++col )
529 diff = rowPtr[ col ] - mean;
530 variance += ( diff * diff );
542 if( ( nRows == 0 ) || ( nCols == 0 ) )
return false;
549 float intensityMean = 0.0;
550 float intensityVariance = 0.0;
551 getStatistics( intensityData, intensityMean, intensityVariance );
555 double rasterMean = 0;
556 double rasterVariance = 0;
558 unsigned int col = 0;
559 unsigned int row = 0;
565 for( row = 0 ; row < nRows ; ++row )
567 for( col = 0 ; col < nCols ; ++col )
574 rasterMean /= (double)( nCols * nRows );
576 for( row = 0 ; row < nRows ; ++row )
578 for( col = 0 ; col < nCols ; ++col )
581 diff = value - rasterMean;
582 rasterVariance += ( diff * diff );
586 double gain = ( ( rasterVariance == 0.0 ) ? 0.0 :
587 sqrt( intensityVariance / rasterVariance ) );
588 double offset = intensityMean - ( gain * rasterMean );
589 float* intensityRow = 0;
591 for( row = 0 ; row < nRows ; ++row )
593 intensityRow = intensityData[ row ];
595 for( col = 0 ; col < nCols ; ++col )
598 intensityRow[ col ] = (float)std::min( 1.0, std::max( 0.0, ( ( value * gain ) - offset ) ) );
607 const std::string& rType,
const std::map< std::string, std::string >& rInfo,
608 std::auto_ptr< te::rst::Raster >& outputRasterPtr )
const
620 std::vector< te::rst::BandProperty* > outRasterBandsProperties;
635 outputRasterPtr.reset(
639 outRasterBandsProperties,
644 "Output raster creation error" );
646 const double rgbNormFac = ( rgbMax == rgbMin ) ? 0.0 :
648 const double pi3 =
M_PI / 3.0;
649 const double twoPi3 = 2.0 *
M_PI / 3.0;
650 const double fourPi3 = 4.0 *
M_PI / 3.0;
651 unsigned int row = 0;
652 unsigned int col = 0;
663 for( row = 0 ; row < nRows ; ++row )
665 for( col = 0 ; col < nCols ; ++col )
667 hue = hueData[ row ][ col ];
668 lig = intensityData[ row ][ col ];
669 sat = saturationData[ row ][ col ];
671 if( ( hue == 0.0 ) && ( sat == 0.0 ) )
673 red = green = blue = ( lig * rgbNormFac );
680 blue = lig * ( 1.0 - sat );
681 red = lig * ( 1.0 + ( sat * std::cos( hue ) /
682 std::cos( pi3 - hue ) ) );
683 green = ( 3.0 * lig ) - ( red + blue );
685 else if( hue < fourPi3 )
690 red = lig * ( 1.0 - sat );
691 green = lig * ( 1.0 + ( sat * std::cos( hue ) /
692 std::cos( pi3 - hue ) ) );
693 blue = ( 3.0 * lig ) - ( red + green );
700 green = lig * ( 1.0 - sat );
701 blue = lig * ( 1.0 + ( sat * std::cos( hue ) /
702 std::cos( pi3 - hue ) ) );
703 red = ( 3.0 * lig ) - ( green + blue );
706 red = ( red * rgbNormFac ) + rgbMin;
707 green = ( green * rgbNormFac ) + rgbMin;
708 blue = ( blue * rgbNormFac ) + rgbMin;
711 red =
MIN( red, rgbMax );
712 green =
MIN( green, rgbMax );
713 blue =
MIN( blue, rgbMax );
715 red =
MAX( red, rgbMin );
716 green =
MAX( green, rgbMin );
717 blue =
MAX( blue, rgbMin );
720 greenBand.
setValue( col, row, green );
721 blueBand.
setValue( col, row, blue );
const InputParameters & operator=(const InputParameters ¶ms)
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Raster Processing functions.
bool swapIntensity(te::rp::Matrix< float > &intensityData)
Swap the intensity data by the high resolution image data.
Grid * getGrid()
It returns the raster grid.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
static Raster * make()
It creates and returns an empty raster with default raster driver.
unsigned int getLinesNumber() const
The number of current matrix lines.
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
unsigned int m_lowResRasterRedBandIndex
The low-resolution raster red band index (default:0).
void getValue(const double &c, const double &r, std::complex< double > &v, const std::size_t &b)
Get the interpolated value at specific band.
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
It interpolates one pixel based on a selected algorithm. Methods currently available are Nearest Neig...
bool m_enableProgress
Enable/Disable the progress interface (default:false).
#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...
std::auto_ptr< te::rst::Raster > m_outputRasterPtr
The generated output fused raster.
Abstract parameters base interface.
A rectified grid is the spatial support for raster data.
A raster band description.
AbstractParameters * clone() const
Create a clone copy of this instance.
bool getRGBRange(double &rgbMin, double &rgbMax) const
Get the minimum and maximum values from the RGB input image.
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
bool saveIHSData(const double &rgbMin, const double rgbMax, const te::rp::Matrix< float > &intensityData, const te::rp::Matrix< float > &hueData, const te::rp::Matrix< float > &saturationData, const std::string &rType, const std::map< std::string, std::string > &rInfo, std::auto_ptr< te::rst::Raster > &outputRasterPtr) const
Save resampled IHS data as RGB data to the output image.
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
double m_RGBMax
The used RGB maximum value (default:0 - leave zero for automatic detection based on the input images)...
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
te::rst::Raster const * m_lowResRasterPtr
Input low-resolution multi-band raster.
Creation of skeleton imagems.
IHSFusion input parameters.
AbstractParameters * clone() const
Create a clone copy of this instance.
std::map< std::string, std::string > m_rInfo
The necessary information to create the output rasters (as described in te::raster::RasterFactory).
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
const Algorithm & operator=(const Algorithm &)
bool loadIHSData(const double &rgbMin, const double rgbMax, te::rp::Matrix< float > &intensityData, te::rp::Matrix< float > &hueData, te::rp::Matrix< float > &saturationData) const
Load resampled IHS data from the input image.
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
InputParameters m_inputParameters
Input execution parameters.
void reset()
Clear all internal allocated objects and reset the algorithm to its initial state.
A raster band description.
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
#define MIN(a, b)
Macro that returns min between two values.
A generic template matrix.
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
unsigned int m_lowResRasterGreenBandIndex
The low-resolution raster green band index (default:1).
unsigned int getColumnsNumber() const
The number of current matrix columns.
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
Raster Processing algorithm output parameters base interface.
unsigned int m_highResRasterBand
Band to process from the high-resolution raster.
te::rst::Interpolator::Method m_interpMethod
The raster interpolator method (default:NearestNeighbor).
void reset()
Reset (clear) the active instance data.
BandProperty * getProperty()
Returns the band property.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
This class can be used to inform the progress of a task.
int getSRID() const
Returns the grid spatial reference system identifier.
te::rst::Raster const * m_highResRasterPtr
Input high-resolution raster.
IHSFusion output parameters.
bool getStatistics(const te::rp::Matrix< float > &matrix, float &mean, float &variance) const
Get statistics from the given matrix.
An Envelope defines a 2D rectangular region.
const OutputParameters & operator=(const OutputParameters ¶ms)
Near neighborhood interpolation method.
#define MAX(a, b)
Macro that returns max between two values.
bool m_isInitialized
Tells if this instance is initialized.
double m_RGBMin
The used RGB minimum value (default:0 - leave zero for automatic detection based on the input images)...
unsigned int m_lowResRasterBlueBandIndex
The low-resolution raster blue band index (default:2).
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
Raster Processing algorithm input parameters base interface.