Commit 1ce966a8 authored by remi cresson's avatar remi cresson
Browse files

ADD: new functor FactorsLabelingFunctor

parent 6b1e0331
......@@ -342,7 +342,6 @@ inline TOutputPixel operator ()(const TInputPixel& input) const
* The functor returns an output pixel of dimension 3 with:
* outputPixel[0] : slope (ordinary least square regression)
* outputPixel[1] : p-value (student coefficient)
* outputPixel[2] : correlation (linear pearson correlation coefficient)
*
*/
template< class TInputPixel, class TOutputPixel>
......@@ -357,9 +356,9 @@ public:
SlopeAndPValueFunctor()
{
/*
* The number of components for the output pixel is 3 (slope, p-value, correlation)
* The number of components for the output pixel is 2 (slope, p-value)
*/
numberOfComponentsPerPixel = 3;
numberOfComponentsPerPixel = 2;
}
// Destructor
......@@ -428,7 +427,7 @@ public:
// pvalue
OutputPixelValueType pvalue = 0.0;
if (correlation < 0.9999999)
if (vcl_abs(correlation) < 1)
{
// degrees of freedom
OutputPixelValueType df = nf - 2;
......@@ -446,7 +445,6 @@ public:
// output pixel
outpixel[0] = slope;
outpixel[1] = pvalue;
outpixel[2] = correlation;
}
return outpixel;
......@@ -474,28 +472,30 @@ protected:
*
* Output value | Definition
* --------------------------------------
* 0 | Very Strong Neg.
* 1 | Strong Neg.
* 2 | Moderate Neg.
* 3 | Very Strong Pos.
* 4 | Strong Pos.
* 5 | Moderate Pos.
* 6 | No Significant
* 0 | No Data
* 1 | Very Strong Neg.
* 2 | Strong Neg.
* 3 | Moderate Neg.
* 4 | Very Strong Pos.
* 5 | Strong Pos.
* 6 | Moderate Pos.
* 7 | No Significant
*
**/
template< class TInputPixel, class TLabelPixel>
class SlopeAndPValueLabelingFunctor
{
public:
enum Def
enum LabelValue
{
VeryStrongNeg,
StrongNeg,
ModerateNeg,
VeryStrongPos,
StrongPos,
ModeratePos,
NoSignificant
NoData,
VeryStrongNeg,
StrongNeg,
ModerateNeg,
VeryStrongPos,
StrongPos,
ModeratePos,
NotSignificant
};
typedef typename TInputPixel::ValueType InputPixelValueType;
......@@ -523,55 +523,48 @@ public:
// Prepare output pixel
TLabelPixel label;
label.SetSize(numberOfComponentsPerPixel);
label.Fill(m_OutputNoDataValue);
// Get slope and p-value
InputPixelValueType slope = input[0];
InputPixelValueType pvalue = input[1];
LabelValue outputLabelValue = NoData;
if (slope != m_InputNoDataValue && pvalue != m_InputNoDataValue)
{
outputLabelValue = NotSignificant;
if (slope < 0)
{
// Slope is negative
if (pvalue <= 0.001)
{
label[0] = static_cast<LabelPixelValueType>(VeryStrongNeg);
outputLabelValue = VeryStrongNeg;
}
else if (0.001 < pvalue && pvalue <= 0.01)
{
label[0] = static_cast<LabelPixelValueType>(StrongNeg);
outputLabelValue = StrongNeg;
}
else if (0.01 < pvalue && pvalue <= 0.05)
{
label[0] = static_cast<LabelPixelValueType>(ModerateNeg);
outputLabelValue = ModerateNeg;
}
else
{
label[0] = static_cast<LabelPixelValueType>(NoSignificant);
}
}
else
} // Slope < 0
else if (slope > 0)
{
// Slope is positive
if (pvalue <= 0.001)
{
label[0] = static_cast<LabelPixelValueType>(VeryStrongPos);
outputLabelValue = VeryStrongPos;
}
else if (0.001 < pvalue && pvalue <= 0.01)
{
label[0] = static_cast<LabelPixelValueType>(StrongPos);
outputLabelValue = StrongPos;
}
else if (0.01 < pvalue && pvalue <= 0.05)
{
label[0] = static_cast<LabelPixelValueType>(ModeratePos);
outputLabelValue = ModeratePos;
}
else
{
label[0] = static_cast<LabelPixelValueType>(NoSignificant);
}
}
}
} // Slope > 0
} // Value is different than no-data
label[0] = static_cast<LabelPixelValueType>(outputLabelValue);
return label;
}
......@@ -580,13 +573,8 @@ public:
void SetInputNoDataValue(InputPixelValueType value) { m_InputNoDataValue = value; }
InputPixelValueType GetInputNoDataValue() const { return m_InputNoDataValue; }
/* Set / Get output no-data value */
void SetOutputNoDataValue(LabelPixelValueType value) { m_OutputNoDataValue = value; }
LabelPixelValueType GetOutputNoDataValue() const { return m_OutputNoDataValue; }
protected:
InputPixelValueType m_InputNoDataValue;
LabelPixelValueType m_OutputNoDataValue;
unsigned int numberOfComponentsPerPixel;
......@@ -695,6 +683,163 @@ protected:
RainfallPixelValueType m_RainfallNoDataValue;
}; // RainfallEstimatedNDVIResiduesFunctor
/**
* \class FactorsLabelingFunctor
*
* \brief Class for computing the label corresponding to the factor.
*
* Input:
* -NDVI Trend (2-bands image: slope and p-value)
* -Rainfall Trend (2-bands image: slope and p-value)
* -NDVI vs Rainfall Correlation coefficient (1-band image)
*
* Output:
* -Label (1-band image)
*
* Output value | Definition
* ----------------------------------------------
* 0 | No data
* 1 | Increase (Climate+Other)
* 2 | Increase (Climate)
* 3 | Increase (Other)
* 4 | Decrease (Climate+Other)
* 5 | Decrease (Climate)
* 6 | Decrease (Other)
* 7 | Not significant
*
**/
template< class TInputPixel, class TLabelPixel>
class FactorsLabelingFunctor
{
public:
enum Labels
{
NoData,
IncreaseBothClimateAndOther,
IncreaseClimate,
IncreaseOther,
DecreaseBothClimateAndOther,
DecreaseClimate,
DecreaseOther,
NotSignificant
};
typedef typename TInputPixel::ValueType InputPixelValueType;
typedef typename TLabelPixel::ValueType LabelPixelValueType;
// Constructor
FactorsLabelingFunctor()
{
numberOfComponentsPerPixel = 1;
}
// Destructor
~FactorsLabelingFunctor(){}
// Purposely not implemented
bool operator!=( const FactorsLabelingFunctor & ) const { return false; }
bool operator==( const FactorsLabelingFunctor & other ) const { return !(*this != other); }
// Get output size
inline unsigned int GetOutputSize(){ return numberOfComponentsPerPixel; }
// Compute output pixel
inline TLabelPixel operator ()(const TInputPixel& ndviTrend, const TInputPixel& rainTrend, const TInputPixel& corr) const
{
// Prepare output pixel
TLabelPixel label;
label.SetSize(numberOfComponentsPerPixel);
// Thresholds
const InputPixelValueType ndviPValThresh = 0.05;
const InputPixelValueType rfPValThresh = 0.05;
const InputPixelValueType corrThresh = 0.5;
// Get values
InputPixelValueType ndviTrendSlope = ndviTrend[0];
InputPixelValueType ndviTrendPValue = ndviTrend[1];
InputPixelValueType rainTrendSlope = rainTrend[0];
InputPixelValueType rainTrendPValue = rainTrend[1];
InputPixelValueType correlation = corr[0];
// Default label value
Labels outputLabelValue = NoData;
if (ndviTrendSlope != m_InputNoDataValue && ndviTrendPValue != m_InputNoDataValue &&
rainTrendSlope != m_InputNoDataValue && rainTrendPValue != m_InputNoDataValue)
{
// Null slope, strong pvalue, ...
outputLabelValue = NotSignificant;
if (ndviTrendPValue < ndviPValThresh)
{
bool corrIsPos = (correlation > corrThresh);
bool rtSlopeIsPos = (rainTrendSlope > 0);
bool rtPValueCond = (rainTrendPValue < rfPValThresh);
// Increase
if (ndviTrendSlope > 0)
{
if (corrIsPos)
{
if (rtSlopeIsPos && rtPValueCond)
{
outputLabelValue = IncreaseBothClimateAndOther;
}
else if ((!rtSlopeIsPos && rtPValueCond) || !rtPValueCond)
{
outputLabelValue = IncreaseClimate;
}
} // correlation > corrThresh
else
{
if (rtPValueCond || (!rtSlopeIsPos && !rtPValueCond))
{
outputLabelValue = IncreaseOther;
}
} // correlation <= corrThresh
} // NDVI slope > 0
else if (ndviTrendSlope < 0)
{
// Decrease
if (corrIsPos)
{
if (rtSlopeIsPos)
{
outputLabelValue = DecreaseClimate;
}
else if (!rtSlopeIsPos && rtPValueCond)
{
outputLabelValue = DecreaseBothClimateAndOther;
}
} // correlation > corrThresh
else
{
if (rtSlopeIsPos || (!rtSlopeIsPos && rtPValueCond))
{
outputLabelValue = DecreaseOther;
}
} // correlation <= corrThresh
} // NDVI slope < 0
} // NDVI p-value < 0.05
} // Different than no-data
label[0] = static_cast<LabelPixelValueType>(outputLabelValue);
return label;
}
/* Set / Get input no-data value */
void SetInputNoDataValue(InputPixelValueType value) { m_InputNoDataValue = value; }
InputPixelValueType GetInputNoDataValue() const { return m_InputNoDataValue; }
protected:
InputPixelValueType m_InputNoDataValue;
unsigned int numberOfComponentsPerPixel;
}; // FactorsLabelingFunctor
} // namespace functor
} // namespace otb
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment