ICF 3.1.1.10
Technical documentation of ICF Libraries
CRectDerivativeProcessor.h
Go to the documentation of this file.
1/********************************************************************************
2** This file is part of the ICF Framework. Copyright (C) Witold Gantzke & Kirill Lepskiy
3** ICF Framework may be used under the terms of the LGPL License v. 2.1 by the Free Software Foundation.
4********************************************************************************/
5
6#ifndef iipr_CRectDerivativeProcessor_included
7#define iipr_CRectDerivativeProcessor_included
8
9
10// STL includes
11#include <vector>
12
13// ICF includes
15#include <imeas/IDataSequence.h>
17
18
19namespace iipr
20{
21
22
27{
28public:
30
31 template<typename InData, typename OutData, typename ValueType>
32 static bool CalculateDerivative(const InData* channelData, int samplesCount, double filterLength, OutData* results);
33
34 template<typename ValueType>
35 static bool CalculateDerivative(const imeas::IDataSequence& source, double filterLength, imeas::IDataSequence& results);
36
40 static bool DoDerivativeProcessing(const imeas::IDataSequence& source, double filterLength, imeas::IDataSequence& results, bool doublePrecision = false);
41
45 const QByteArray& GetFilterParamsId() const;
46
51 void SetFilterParamsId(const QByteArray& id);
52
56 void UseDoublePrecision(bool on);
57
58 // reimplemented (iproc::IProcessor)
60 const iprm::IParamsSet* paramsPtr,
61 const istd::IPolymorphic* inputPtr,
62 istd::IChangeable* outputPtr,
63 bool allowAsync = false,
64 iproc::IProgressManager* progressManagerPtr = nullptr);
65
66protected:
68
69private:
70 QByteArray m_filterParamsId;
71 bool m_doublePrecision;
72};
73
74
75// inline methods
76
77inline const QByteArray& CRectDerivativeProcessor::GetFilterParamsId() const
78{
79 return m_filterParamsId;
80}
81
82
83inline void CRectDerivativeProcessor::SetFilterParamsId(const QByteArray& id)
84{
85 m_filterParamsId = id;
86}
87
88
90{
91 m_doublePrecision = on;
92}
93
94
95template<typename InData, typename OutData, typename ValueType>
96bool CRectDerivativeProcessor::CalculateDerivative(const InData* channelData, int samplesCount, double filterLength, OutData* results)
97{
98 if (samplesCount < 2){
99 return false;
100 }
101
102 ValueType halfRealLength = qMax(1.0, filterLength * 0.5);
103
104 int sumOffset = int(halfRealLength);
105 ValueType sumLastAlpha = halfRealLength - sumOffset;
106 ValueType sumLastAlphaInv = 1 - sumLastAlpha;
107
108 int projectionWidth = samplesCount - 1;
109
110 ValueType leftSum = 0;
111 ValueType leftWeight = 0;
112 ValueType rightSum = channelData[0] * sumLastAlpha;
113 ValueType rightWeight = sumLastAlpha;
114
115 for (int x = -sumOffset; x < projectionWidth; ++x){
116 if (x < projectionWidth - sumOffset){
117 rightSum += channelData[x + sumOffset + 1] * sumLastAlpha +
118 channelData[x + sumOffset] * sumLastAlphaInv;
119
120 rightWeight += 1;
121 }
122 else if (x == projectionWidth - sumOffset){
123 rightSum += channelData[x + sumOffset] * sumLastAlphaInv;
124
125 rightWeight += sumLastAlphaInv;
126 }
127
128 if (x >= 0){
129 ValueType diff = channelData[x];
130 leftSum += diff;
131
132 if (x > sumOffset){
133 leftSum -= channelData[x - sumOffset] * sumLastAlphaInv;
134 leftSum -= channelData[x - sumOffset - 1] * sumLastAlpha;
135 }
136 else if (x == sumOffset){
137 leftSum -= channelData[x - sumOffset] * sumLastAlphaInv;
138
139 leftWeight += sumLastAlpha;
140 }
141 else{
142 leftWeight += 1;
143 }
144
145 rightSum -= diff;
146 rightWeight -= 1;
147
148 results[x] = rightSum / rightWeight - leftSum / leftWeight;
149 }
150 }
151
152 return true;
153}
154
155
156template <typename ValueType>
158{
159 int samplesCount = source.GetSamplesCount();
160 int channelsCount = source.GetChannelsCount();
161 if ((samplesCount < 2) || (channelsCount < 1)){
162 return false;
163 }
164
165 ValueType halfRealLength = qMax(1.0, filterLength * 0.5);
166
167 int sumOffset = int(halfRealLength);
168 ValueType sumLastAlpha = halfRealLength - sumOffset;
169 ValueType sumLastAlphaInv = 1 - sumLastAlpha;
170
171 int projectionWidth = samplesCount - 1;
172
173 // Buffer to speed up data access (brings ca. 10%):
174 std::vector<ValueType> channelData(samplesCount);
175
176 for (int channelIndex = 0; channelIndex < channelsCount; ++channelIndex){
177 for (int i = 0; i < samplesCount; ++i){
178 channelData[i] = source.GetSample(i, channelIndex);
179 }
180
181 ValueType leftSum = 0;
182 ValueType leftWeight = 0;
183 ValueType rightSum = channelData[0] * sumLastAlpha;
184 ValueType rightWeight = sumLastAlpha;
185
186 for (int x = -sumOffset; x < projectionWidth; ++x){
187 if (x < projectionWidth - sumOffset){
188 rightSum += channelData[x + sumOffset + 1] * sumLastAlpha + channelData[x + sumOffset] * sumLastAlphaInv;
189
190 rightWeight += 1;
191 }
192 else if (x == projectionWidth - sumOffset){
193 rightSum += channelData[x + sumOffset] * sumLastAlphaInv;
194 rightWeight += sumLastAlphaInv;
195 }
196
197 if (x >= 0){
198 ValueType diff = channelData[x];
199 leftSum += diff;
200
201 if (x > sumOffset){
202 leftSum -= channelData[x - sumOffset] * sumLastAlphaInv;
203 leftSum -= channelData[x - sumOffset - 1] * sumLastAlpha;
204 }
205 else if (x == sumOffset){
206 leftSum -= channelData[x - sumOffset] * sumLastAlphaInv;
207 leftWeight += sumLastAlpha;
208 }
209 else{
210 leftWeight += 1;
211 }
212
213 rightSum -= diff;
214 rightWeight -= 1;
215
216 results.SetSample(x, channelIndex, rightSum / rightWeight - leftSum / leftWeight);
217 }
218 }
219 }
220
221 return true;
222}
223
224
225} // namespace iipr
226
227
228#endif // !iipr_CRectDerivativeProcessor_included
229
230
Calculate derivative of projection using rectangular filter kernel.
void UseDoublePrecision(bool on)
Sets calculation precision to use (true = double, false = float).
void SetFilterParamsId(const QByteArray &id)
Set parameter ID used to extract caliper parameter object from parameter set.
static bool DoDerivativeProcessing(const imeas::IDataSequence &source, double filterLength, imeas::IDataSequence &results, bool doublePrecision=false)
Do extremum features analyze.
static imeas::INumericConstraints * GetFilterConstraints()
const QByteArray & GetFilterParamsId() const
Get parameter ID used to extract caliper parameter object from parameter set.
static bool CalculateDerivative(const InData *channelData, int samplesCount, double filterLength, OutData *results)
virtual iproc::CTaskState DoProcessing(const iprm::IParamsSet *paramsPtr, const istd::IPolymorphic *inputPtr, istd::IChangeable *outputPtr, bool allowAsync=false, iproc::IProgressManager *progressManagerPtr=nullptr)
General definition of sequence contains samples in regular time grid.
virtual void SetSample(int index, int channel, double value)=0
Set sample value at specified index.
virtual double GetSample(int index, int channel=0) const =0
Get sample value at specified index.
virtual int GetSamplesCount() const =0
Get size of this raster sequence.
virtual int GetChannelsCount() const =0
Get number of channels.
Describe additional meta information for set of numeric values.
Set of general parameters.
Definition IParamsSet.h:29
Represent state of asynchronous operation.
Definition CTaskState.h:28
Consume information about progress of some process.
Wrapper of iproc::IProcessor for simple synchrone processor implementations.
Common interface for data model objects, which can be changed.
Definition IChangeable.h:32
Contains the image processing classes.

© Witold Gantzke and Kirill Lepskiy