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 ( std::sqrt( intensityVariance ) / std::sqrt( rasterVariance ) ) );
588 double offset = ( ( rasterVariance == 0.0 ) ? 0.0 : ( 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 );
std::map< std::string, std::string > m_rInfo
The necessary information to create the output rasters (as described in te::raster::RasterFactory).
Creation of skeleton imagems.
std::string m_rType
Output raster data source type (as described in te::raster::RasterFactory ).
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
std::auto_ptr< te::rst::Raster > m_outputRasterPtr
The generated output fused raster.
A raster band description.
AbstractParameters * clone() const
Create a clone copy of this instance.
int getSRID() const
Returns the grid spatial reference system identifier.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
IHSFusion output parameters.
It interpolates one pixel based on a selected algorithm. Methods currently available are Nearest Neig...
This class can be used to inform the progress of a task.
Raster Processing algorithm output parameters base interface.
#define MIN(a, b)
Macro that returns min between two values.
void getValue(const double &c, const double &r, std::complex< double > &v, const std::size_t &b)
Get the interpolated value at specific band.
bool getRGBRange(double &rgbMin, double &rgbMax) const
Get the minimum and maximum values from the RGB input image.
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits::max().
#define MAX(a, b)
Macro that returns max between two values.
Raster Processing functions.
#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...
const Algorithm & operator=(const Algorithm &)
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
An Envelope defines a 2D rectangular region.
unsigned int getNumberOfRows() const
Returns the raster number of rows.
unsigned int getColumnsNumber() const
The number of current matrix columns.
BandProperty * getProperty()
Returns the band property.
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.
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
InputParameters m_inputParameters
Input execution parameters.
A raster band description.
Grid * getGrid()
It returns the raster grid.
void reset()
Reset (clear) the active instance data.
virtual void setValue(unsigned int c, unsigned int r, const double value)=0
Sets the cell attribute value.
const OutputParameters & operator=(const OutputParameters ¶ms)
Abstract parameters base interface.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
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 swapIntensity(te::rp::Matrix< float > &intensityData)
Swap the intensity data by the high resolution image data.
A generic template matrix.
static Raster * make()
It creates and returns an empty raster with default raster driver.
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
void reset()
Clear all internal allocated objects and reset the algorithm to its initial state.
Near neighborhood interpolation method.
A rectified grid is the spatial support for raster data.
bool getStatistics(const te::rp::Matrix< float > &matrix, float &mean, float &variance) const
Get statistics from the given matrix.
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
unsigned int getLinesNumber() const
The number of current matrix lines.
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
bool m_isInitialized
Tells if this instance is initialized.