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.