21 #ifndef otbHistogramOfOrientedGradientCovariantImageFunction_hxx
22 #define otbHistogramOfOrientedGradientCovariantImageFunction_hxx
25 #include "itkConstNeighborhoodIterator.h"
26 #include "itkNumericTraits.h"
35 template <
class TInputImage,
class TOutputPrecision,
class TCoordRep>
37 : m_NeighborhoodRadius(8), m_NumberOfOrientationBins(18)
41 template <
class TInputImage,
class TOutputPrecision,
class TCoordRep>
44 this->Superclass::PrintSelf(os, indent);
45 os << indent <<
" Neighborhood radius value : " << m_NeighborhoodRadius << std::endl;
48 template <
class TInputImage,
class TOutputPrecision,
class TCoordRep>
56 if (!this->GetInputImage())
62 if (!this->IsInsideBuffer(index))
68 typename InputImageType::SizeType kernelSize;
69 kernelSize.Fill(m_NeighborhoodRadius);
71 itk::ConstNeighborhoodIterator<InputImageType> it(kernelSize, this->GetInputImage(), this->GetInputImage()->GetBufferedRegion());
74 it.SetLocation(index);
77 typename InputImageType::OffsetType offset;
80 double centerBinRadius =
static_cast<double>(m_NeighborhoodRadius) / 2;
83 double squaredRadius = m_NeighborhoodRadius * m_NeighborhoodRadius;
84 double squaredCenterBinRadius = centerBinRadius * centerBinRadius;
85 double squaredSigma = 0.25 * squaredRadius;
88 std::vector<TOutputPrecision> globalOrientationHistogram(m_NumberOfOrientationBins, 0.);
91 double orientationBinWidth =
otb::CONST_2PI / m_NumberOfOrientationBins;
94 for (
int i = -(
int)m_NeighborhoodRadius; i < (int)m_NeighborhoodRadius; ++i)
96 for (
int j = -(
int)m_NeighborhoodRadius; j < (int)m_NeighborhoodRadius; ++j)
99 double currentSquaredRadius = i * i + j * j;
100 if (currentSquaredRadius < squaredRadius)
104 double gWeight = (1 / std::sqrt(
otb::CONST_2PI * squaredSigma)) * std::exp(-currentSquaredRadius / (2 * squaredSigma));
114 double angle = std::atan2(gradient[1], gradient[0]);
117 TOutputPrecision magnitude = std::sqrt(gradient[0] * gradient[0] + gradient[1] * gradient[1]);
121 unsigned int binIndex = std::floor((
otb::CONST_PI + angle) / orientationBinWidth);
124 if (binIndex == m_NumberOfOrientationBins)
125 binIndex = m_NumberOfOrientationBins - 1;
128 globalOrientationHistogram[binIndex] += magnitude * gWeight;
135 double maxOrientationHistogramValue = globalOrientationHistogram[0];
136 unsigned int maxOrientationHistogramBin = 0;
138 for (
unsigned int i = 1; i < m_NumberOfOrientationBins; ++i)
141 double currentValue = globalOrientationHistogram[i];
144 if (maxOrientationHistogramValue < currentValue)
146 maxOrientationHistogramValue = currentValue;
147 maxOrientationHistogramBin = i;
152 double principalOrientation = maxOrientationHistogramBin * orientationBinWidth -
otb::CONST_PI;
155 std::vector<TOutputPrecision> centerHistogram(m_NumberOfOrientationBins, 0.);
156 std::vector<TOutputPrecision> upperLeftHistogram(m_NumberOfOrientationBins, 0.);
157 std::vector<TOutputPrecision> upperRightHistogram(m_NumberOfOrientationBins, 0.);
158 std::vector<TOutputPrecision> lowerLeftHistogram(m_NumberOfOrientationBins, 0.);
159 std::vector<TOutputPrecision> lowerRightHistogram(m_NumberOfOrientationBins, 0.);
162 for (
int i = -(
int)m_NeighborhoodRadius; i < (int)m_NeighborhoodRadius; ++i)
164 for (
int j = -(
int)m_NeighborhoodRadius; j < (int)m_NeighborhoodRadius; ++j)
167 double currentSquaredRadius = i * i + j * j;
168 if (currentSquaredRadius < squaredRadius)
172 double gWeight = (1 / std::sqrt(
otb::CONST_2PI * squaredSigma)) * std::exp(-currentSquaredRadius / (2 * squaredSigma));
182 double angle = std::atan2(gradient[1], gradient[0]) - principalOrientation;
196 TOutputPrecision magnitude = std::sqrt(gradient[0] * gradient[0] + gradient[1] * gradient[1]);
200 unsigned int binIndex = std::floor((
otb::CONST_PI + angle) / orientationBinWidth);
202 if (binIndex == m_NumberOfOrientationBins)
203 binIndex = m_NumberOfOrientationBins - 1;
206 double angularPosition = std::atan2((
double)j, (
double)i) - principalOrientation;
220 if (currentSquaredRadius < squaredCenterBinRadius)
222 centerHistogram[binIndex] += magnitude * gWeight;
224 else if (angularPosition > 0)
228 upperRightHistogram[binIndex] += magnitude * gWeight;
232 upperLeftHistogram[binIndex] += magnitude * gWeight;
239 lowerRightHistogram[binIndex] += magnitude * gWeight;
243 lowerLeftHistogram[binIndex] += magnitude * gWeight;
248 globalOrientationHistogram[binIndex] += magnitude * gWeight;
254 hog.push_back(centerHistogram);
255 hog.push_back(upperLeftHistogram);
256 hog.push_back(upperRightHistogram);
257 hog.push_back(lowerRightHistogram);
258 hog.push_back(lowerLeftHistogram);
261 for (
typename OutputType::iterator oIt = hog.begin(); oIt != hog.end(); ++oIt)
264 double squaredCumul = 1e-10;
265 for (
typename std::vector<TOutputPrecision>::const_iterator vIt = oIt->begin(); vIt != oIt->end(); ++vIt)
267 squaredCumul += (*vIt) * (*vIt);
269 double scale = 1 / std::sqrt(squaredCumul);
271 for (
typename std::vector<TOutputPrecision>::iterator vIt = oIt->begin(); vIt != oIt->end(); ++vIt)