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 const double gain = ( ( rasterVariance == 0.0 ) ? 0.0 :
587 std::sqrt( (
double)intensityVariance ) / std::sqrt( rasterVariance ) );
588 float* intensityRow = 0;
590 for( row = 0 ; row < nRows ; ++row )
592 intensityRow = intensityData[ row ];
594 for( col = 0 ; col < nCols ; ++col )
597 intensityRow[ col ] = (float)std::min( 1.0, std::max( 0.0, ( ( value - rasterMean ) * gain ) + ((
double)intensityMean) ) );
606 const std::string& rType,
const std::map< std::string, std::string >& rInfo,
607 std::auto_ptr< te::rst::Raster >& outputRasterPtr )
const
619 std::vector< te::rst::BandProperty* > outRasterBandsProperties;
623 outRasterBandsProperties[ 0 ]->m_blkw = nCols;
624 outRasterBandsProperties[ 0 ]->m_blkh = 1;
625 outRasterBandsProperties[ 0 ]->m_nblocksx = 1;
626 outRasterBandsProperties[ 0 ]->m_nblocksy = nRows;
630 outRasterBandsProperties[ 1 ]->m_blkw = nCols;
631 outRasterBandsProperties[ 1 ]->m_blkh = 1;
632 outRasterBandsProperties[ 1 ]->m_nblocksx = 1;
633 outRasterBandsProperties[ 1 ]->m_nblocksy = nRows;
637 outRasterBandsProperties[ 2 ]->m_blkw = nCols;
638 outRasterBandsProperties[ 2 ]->m_blkh = 1;
639 outRasterBandsProperties[ 2 ]->m_nblocksx = 1;
640 outRasterBandsProperties[ 2 ]->m_nblocksy = nRows;
644 outputRasterPtr.reset(
648 outRasterBandsProperties,
653 "Output raster creation error" );
655 const double rgbNormFac = ( rgbMax == rgbMin ) ? 0.0 :
657 const double pi3 =
M_PI / 3.0;
658 const double twoPi3 = 2.0 *
M_PI / 3.0;
659 const double fourPi3 = 4.0 *
M_PI / 3.0;
660 unsigned int row = 0;
661 unsigned int col = 0;
672 for( row = 0 ; row < nRows ; ++row )
674 for( col = 0 ; col < nCols ; ++col )
676 hue = hueData[ row ][ col ];
677 lig = intensityData[ row ][ col ];
678 sat = saturationData[ row ][ col ];
680 if( ( hue == 0.0 ) && ( sat == 0.0 ) )
682 red = green = blue = ( lig * rgbNormFac );
689 blue = lig * ( 1.0 - sat );
690 red = lig * ( 1.0 + ( sat * std::cos( hue ) /
691 std::cos( pi3 - hue ) ) );
692 green = ( 3.0 * lig ) - ( red + blue );
694 else if( hue < fourPi3 )
699 red = lig * ( 1.0 - sat );
700 green = lig * ( 1.0 + ( sat * std::cos( hue ) /
701 std::cos( pi3 - hue ) ) );
702 blue = ( 3.0 * lig ) - ( red + green );
709 green = lig * ( 1.0 - sat );
710 blue = lig * ( 1.0 + ( sat * std::cos( hue ) /
711 std::cos( pi3 - hue ) ) );
712 red = ( 3.0 * lig ) - ( green + blue );
715 red = ( red * rgbNormFac ) + rgbMin;
716 green = ( green * rgbNormFac ) + rgbMin;
717 blue = ( blue * rgbNormFac ) + rgbMin;
720 red =
MIN( red, rgbMax );
721 green =
MIN( green, rgbMax );
722 blue =
MIN( blue, rgbMax );
724 red =
MAX( red, rgbMin );
725 green =
MAX( green, rgbMin );
726 blue =
MAX( blue, rgbMin );
729 greenBand.
setValue( col, row, green );
730 blueBand.
setValue( col, row, blue );
Near neighborhood interpolation method.
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.
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.
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.
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.
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.