CRectDerivativeProcessor.h
Go to the documentation of this file.
1 #ifndef iipr_CRectDerivativeProcessor_included
2 #define iipr_CRectDerivativeProcessor_included
3 
4 
5 // STL includes
6 #include <vector>
7 
8 // ACF includes
10 
11 // ACF-Solutions includes
12 #include <imeas/IDataSequence.h>
13 
14 
15 namespace iipr
16 {
17 
18 
23 {
24 public:
26 
27  template<typename InData, typename OutData, typename ValueType>
28  static bool CalculateDerivative(const InData* channelData, int samplesCount, double filterLength, OutData* results);
29 
30  template<typename ValueType>
31  static bool CalculateDerivative(const imeas::IDataSequence& source, double filterLength, imeas::IDataSequence& results);
32 
36  static bool DoDerivativeProcessing(const imeas::IDataSequence& source, double filterLength, imeas::IDataSequence& results, bool doublePrecision = false);
37 
41  const QByteArray& GetFilterParamsId() const;
42 
47  void SetFilterParamsId(const QByteArray& id);
48 
52  void UseDoublePrecision(bool on);
53 
54  // reimplemented (iproc::IProcessor)
55  virtual int DoProcessing(
56  const iprm::IParamsSet* paramsPtr,
57  const istd::IPolymorphic* inputPtr,
58  istd::IChangeable* outputPtr,
59  ibase::IProgressManager* progressManagerPtr = NULL);
60 
61 private:
62  QByteArray m_filterParamsId;
63  bool m_doublePrecision;
64 };
65 
66 
67 // inline methods
68 
69 inline const QByteArray& CRectDerivativeProcessor::GetFilterParamsId() const
70 {
71  return m_filterParamsId;
72 }
73 
74 
75 inline void CRectDerivativeProcessor::SetFilterParamsId(const QByteArray& id)
76 {
77  m_filterParamsId = id;
78 }
79 
80 
82 {
83  m_doublePrecision = on;
84 }
85 
86 
87 template<typename InData, typename OutData, typename ValueType>
88 bool CRectDerivativeProcessor::CalculateDerivative(const InData* channelData, int samplesCount, double filterLength, OutData* results)
89 {
90  if (samplesCount < 2){
91  return false;
92  }
93 
94  ValueType halfRealLength = qMax(1.0, filterLength * 0.5);
95 
96  int sumOffset = int(halfRealLength);
97  ValueType sumLastAlpha = halfRealLength - sumOffset;
98  ValueType sumLastAlphaInv = 1 - sumLastAlpha;
99 
100  int projectionWidth = samplesCount - 1;
101 
102  ValueType leftSum = 0;
103  ValueType leftWeight = 0;
104  ValueType rightSum = channelData[0] * sumLastAlpha;
105  ValueType rightWeight = sumLastAlpha;
106 
107  for (int x = -sumOffset; x < projectionWidth; ++x){
108  if (x < projectionWidth - sumOffset){
109  rightSum += channelData[x + sumOffset + 1] * sumLastAlpha +
110  channelData[x + sumOffset] * sumLastAlphaInv;
111 
112  rightWeight += 1;
113  }
114  else if (x == projectionWidth - sumOffset){
115  rightSum += channelData[x + sumOffset] * sumLastAlphaInv;
116 
117  rightWeight += sumLastAlphaInv;
118  }
119 
120  if (x >= 0){
121  ValueType diff = channelData[x];
122  leftSum += diff;
123 
124  if (x > sumOffset){
125  leftSum -= channelData[x - sumOffset] * sumLastAlphaInv;
126  leftSum -= channelData[x - sumOffset - 1] * sumLastAlpha;
127  }
128  else if (x == sumOffset){
129  leftSum -= channelData[x - sumOffset] * sumLastAlphaInv;
130 
131  leftWeight += sumLastAlpha;
132  }
133  else{
134  leftWeight += 1;
135  }
136 
137  rightSum -= diff;
138  rightWeight -= 1;
139 
140  results[x] = rightSum / rightWeight - leftSum / leftWeight;
141  }
142  }
143 
144  return true;
145 }
146 
147 
148 template <typename ValueType>
150 {
151  int samplesCount = source.GetSamplesCount();
152  int channelsCount = source.GetChannelsCount();
153  if ((samplesCount < 2) || (channelsCount < 1)){
154  return false;
155  }
156 
157  ValueType halfRealLength = qMax(1.0, filterLength * 0.5);
158 
159  int sumOffset = int(halfRealLength);
160  ValueType sumLastAlpha = halfRealLength - sumOffset;
161  ValueType sumLastAlphaInv = 1 - sumLastAlpha;
162 
163  int projectionWidth = samplesCount - 1;
164 
165  // Buffer to speed up data access (brings ca. 10%):
166  std::vector<ValueType> channelData(samplesCount);
167 
168  for (int channelIndex = 0; channelIndex < channelsCount; ++channelIndex){
169  for (int i = 0; i < samplesCount; ++i){
170  channelData[i] = source.GetSample(i, channelIndex);
171  }
172 
173  ValueType leftSum = 0;
174  ValueType leftWeight = 0;
175  ValueType rightSum = channelData[0] * sumLastAlpha;
176  ValueType rightWeight = sumLastAlpha;
177 
178  for (int x = -sumOffset; x < projectionWidth; ++x){
179  if (x < projectionWidth - sumOffset){
180  rightSum += channelData[x + sumOffset + 1] * sumLastAlpha + channelData[x + sumOffset] * sumLastAlphaInv;
181 
182  rightWeight += 1;
183  }
184  else if (x == projectionWidth - sumOffset){
185  rightSum += channelData[x + sumOffset] * sumLastAlphaInv;
186  rightWeight += sumLastAlphaInv;
187  }
188 
189  if (x >= 0){
190  ValueType diff = channelData[x];
191  leftSum += diff;
192 
193  if (x > sumOffset){
194  leftSum -= channelData[x - sumOffset] * sumLastAlphaInv;
195  leftSum -= channelData[x - sumOffset - 1] * sumLastAlpha;
196  }
197  else if (x == sumOffset){
198  leftSum -= channelData[x - sumOffset] * sumLastAlphaInv;
199  leftWeight += sumLastAlpha;
200  }
201  else{
202  leftWeight += 1;
203  }
204 
205  rightSum -= diff;
206  rightWeight -= 1;
207 
208  results.SetSample(x, channelIndex, rightSum / rightWeight - leftSum / leftWeight);
209  }
210  }
211  }
212 
213  return true;
214 }
215 
216 
217 } // namespace iipr
218 
219 
220 #endif // !iipr_CRectDerivativeProcessor_included
221 
222 
virtual int GetChannelsCount() const =0
Get number of channels.
static bool CalculateDerivative(const InData *channelData, int samplesCount, double filterLength, OutData *results)
void UseDoublePrecision(bool on)
Sets calculation precision to use (true = double, false = float).
virtual int GetSamplesCount() const =0
Get size of this raster sequence.
Wrapper of iproc::IProcessor for simple synchrone processor implementations.
const QByteArray & GetFilterParamsId() const
Get parameter ID used to extract caliper parameter object from parameter set.
virtual double GetSample(int index, int channel=0) const =0
Get sample value at specified index.
virtual void SetSample(int index, int channel, double value)=0
Set sample value at specified index.
#define NULL
static bool DoDerivativeProcessing(const imeas::IDataSequence &source, double filterLength, imeas::IDataSequence &results, bool doublePrecision=false)
Do extremum features analyze.
Calculate derivative of projection using rectangular filter kernel.
virtual int DoProcessing(const iprm::IParamsSet *paramsPtr, const istd::IPolymorphic *inputPtr, istd::IChangeable *outputPtr, ibase::IProgressManager *progressManagerPtr=NULL)
void SetFilterParamsId(const QByteArray &id)
Set parameter ID used to extract caliper parameter object from parameter set.
General definition of sequence contains samples in regular time grid.
Definition: IDataSequence.h:20

© 2007-2017 Witold Gantzke and Kirill Lepskiy