21 #ifndef otbSpectralResponse_hxx
22 #define otbSpectralResponse_hxx
24 #include "itkNumericTraits.h"
34 template <
class TPrecision,
class TValuePrecision>
37 m_SensitivityThreshold = 0.01;
38 m_IntervalComputed =
false;
40 m_UsePosGuess =
false;
43 template <
class TPrecision,
class TValuePrecision>
48 std::ifstream fin(filename);
51 itkExceptionMacro(<<
"Error opening file" << filename);
56 for (
int i = 0; i < NumLigne; ++i)
57 fin.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
62 std::pair<TPrecision, TValuePrecision> currentPair;
64 fin >> currentPair.first;
65 fin >> currentPair.second;
66 currentPair.second = currentPair.second / coefNormalization;
67 if (currentPair.first != itk::NumericTraits<TPrecision>::ZeroValue() && currentPair.second != itk::NumericTraits<TValuePrecision>::ZeroValue())
69 m_Response.push_back(currentPair);
73 std::sort(m_Response.begin(), m_Response.end(),
sort_pair());
75 m_IntervalComputed =
false;
78 template <
class TPrecision,
class TValuePrecision>
82 m_IntervalComputed =
false;
86 template <
class TPrecision,
class TValuePrecision>
89 return m_Response.size();
93 template <
class TPrecision,
class TValuePrecision>
97 if (m_Response.size() <= 1)
99 itkExceptionMacro(<<
"ERROR spectral response need at least 2 value to perform interpolation.");
102 TPrecision lambdaMax = this->GetInterval().second;
103 if (lambda > lambdaMax)
105 typename VectorPairType::const_iterator it = m_Response.begin();
107 while (((*it).first < lambda))
111 if (it == (m_Response.end()))
121 template <
class TPrecision,
class TValuePrecision>
129 if (m_Response.size() <= 1)
131 itkExceptionMacro(<<
"ERROR spectral response need at least 2 value to perform interpolation.");
134 typename VectorPairType::const_iterator beg = m_Response.begin();
135 typename VectorPairType::const_iterator last = m_Response.end();
138 TPrecision lambdaMin = this->GetInterval().first;
139 TPrecision lambdaMax = this->GetInterval().second;
141 if (lambda < lambdaMin)
142 return static_cast<TValuePrecision
>(0.0);
143 if (lambda > lambdaMax)
144 return static_cast<TValuePrecision
>(0.0);
146 typename VectorPairType::const_iterator it;
149 it = beg + m_PosGuess;
153 TPrecision lambda1 = (*beg).first;
154 TValuePrecision SR1 =
static_cast<TValuePrecision
>(0.0);
155 while (((*it).first < lambda))
158 lambda1 = (*it).first;
161 if (it == (m_Response.end()))
163 return static_cast<TValuePrecision
>(0.0);
166 TPrecision lambda2 = (*it).first;
169 if (lambda2 == lambda)
176 TPrecision lambdaDist = lambda - lambda1;
177 TPrecision ratio = lambdaDist / (lambda2 - lambda1);
179 TValuePrecision SR2 = (*it).second;
181 return static_cast<TValuePrecision
>(ratio * SR1 + (1 - ratio) * SR2);
185 template <
class TPrecision,
class TValuePrecision>
205 region.SetSize(size);
206 region.SetIndex(start);
208 image->SetRegions(region);
209 image->SetNumberOfComponentsPerPixel(this->Size());
214 pixel.SetSize(this->Size());
216 for (
unsigned int j = 0; j < this->Size(); ++j)
218 pixel[j] = m_Response[j].second;
222 image->SetPixel(idx, pixel);
226 template <
class TPrecision,
class TValuePrecision>
234 for (
unsigned int j = 0; j < this->Size(); ++j)
236 m_Response[j].second = image->GetPixel(idx)[j];
238 m_IntervalComputed =
false;
241 template <
class TPrecision,
class TValuePrecision>
248 Self& responseCalculator = *
this;
249 for (
double i = m_Response.front().first; i <= m_Response.back().first; i += step)
251 valuesVector.push_back(responseCalculator(i));
255 functionValues->SetFilterFunctionValues(valuesVector);
256 functionValues->SetMinSpectralValue(m_Response.front().first);
257 functionValues->SetMaxSpectralValue(m_Response.back().first);
258 functionValues->SetUserStep(step);
260 return functionValues;
263 template <
class TPrecision,
class TValuePrecision>
266 typename VectorPairType::const_iterator it = m_Response.begin();
268 while ((*it).second <= m_SensitivityThreshold)
271 if (it == (m_Response.end() - 1))
273 m_Interval.first =
static_cast<TPrecision
>(0.0);
274 m_Interval.second =
static_cast<TPrecision
>(0.0);
275 m_IntervalComputed =
true;
279 m_Interval.first = (*it).first;
280 it = (m_Response.end() - 1);
281 while ((*it).second <= m_SensitivityThreshold)
283 if (it == (m_Response.begin()))
285 m_Interval.second = (*it).first;
286 m_IntervalComputed =
true;
292 m_Interval.second = (*it).first;
293 m_IntervalComputed =
true;
296 template <
class TPrecision,
class TValuePrecision>
299 Superclass::PrintSelf(os, indent);
301 os << indent <<
"[Wavelength (micrometers), Reflectance (percent)]" << std::endl;
302 for (
typename VectorPairType::const_iterator it = m_Response.begin(); it != m_Response.end(); ++it)
304 os << indent <<
"Num " << it - m_Response.begin() <<
": [" << (*it).first <<
"," << (*it).second <<
"]" << std::endl;