Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp
16347 views
1
/*M///////////////////////////////////////////////////////////////////////////////////////
2
//
3
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
//
5
// By downloading, copying, installing or using the software you agree to this license.
6
// If you do not agree to this license, do not download, install,
7
// copy or use the software.
8
//
9
//
10
// Intel License Agreement
11
// For Open Source Computer Vision Library
12
//
13
// Copyright (C) 2000, Intel Corporation, all rights reserved.
14
// Third party copyrights are property of their respective icvers.
15
//
16
// Redistribution and use in source and binary forms, with or without modification,
17
// are permitted provided that the following conditions are met:
18
//
19
// * Redistribution's of source code must retain the above copyright notice,
20
// this list of conditions and the following disclaimer.
21
//
22
// * Redistribution's in binary form must reproduce the above copyright notice,
23
// this list of conditions and the following disclaimer in the documentation
24
// and/or other materials provided with the distribution.
25
//
26
// * The name of Intel Corporation may not be used to endorse or promote products
27
// derived from this software without specific prior written permission.
28
//
29
// This software is provided by the copyright holders and contributors "as is" and
30
// any express or implied warranties, including, but not limited to, the implied
31
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32
// In no event shall the Intel Corporation or contributors be liable for any direct,
33
// indirect, incidental, special, exemplary, or consequential damages
34
// (including, but not limited to, procurement of substitute goods or services;
35
// loss of use, data, or profits; or business interruption) however caused
36
// and on any theory of liability, whether in contract, strict liability,
37
// or tort (including negligence or otherwise) arising in any way out of
38
// the use of this software, even if advised of the possibility of such damage.
39
//
40
//M*/
41
42
#ifndef __OPENCV_FAST_NLMEANS_DENOISING_INVOKER_COMMONS_HPP__
43
#define __OPENCV_FAST_NLMEANS_DENOISING_INVOKER_COMMONS_HPP__
44
45
using namespace cv;
46
47
// std::isnan is a part of C++11 and it is not supported in MSVS2010/2012
48
#if defined _MSC_VER && _MSC_VER < 1800 /* MSVC 2013 */
49
#include <float.h>
50
namespace std {
51
template <typename T> bool isnan(T value) { return _isnan(value) != 0; }
52
}
53
#endif
54
55
template <typename T> struct pixelInfo_
56
{
57
static const int channels = 1;
58
typedef T sampleType;
59
};
60
61
template <typename ET, int n> struct pixelInfo_<Vec<ET, n> >
62
{
63
static const int channels = n;
64
typedef ET sampleType;
65
};
66
67
template <typename T> struct pixelInfo: public pixelInfo_<T>
68
{
69
typedef typename pixelInfo_<T>::sampleType sampleType;
70
71
static inline sampleType sampleMax()
72
{
73
return std::numeric_limits<sampleType>::max();
74
}
75
76
static inline sampleType sampleMin()
77
{
78
return std::numeric_limits<sampleType>::min();
79
}
80
81
static inline size_t sampleBytes()
82
{
83
return sizeof(sampleType);
84
}
85
86
static inline size_t sampleBits()
87
{
88
return 8*sampleBytes();
89
}
90
};
91
92
class DistAbs
93
{
94
template <typename T> struct calcDist_
95
{
96
static inline int f(const T a, const T b)
97
{
98
return std::abs((int)(a-b));
99
}
100
};
101
102
template <typename ET> struct calcDist_<Vec<ET, 2> >
103
{
104
static inline int f(const Vec<ET, 2> a, const Vec<ET, 2> b)
105
{
106
return std::abs((int)(a[0]-b[0])) + std::abs((int)(a[1]-b[1]));
107
}
108
};
109
110
template <typename ET> struct calcDist_<Vec<ET, 3> >
111
{
112
static inline int f(const Vec<ET, 3> a, const Vec<ET, 3> b)
113
{
114
return
115
std::abs((int)(a[0]-b[0])) +
116
std::abs((int)(a[1]-b[1])) +
117
std::abs((int)(a[2]-b[2]));
118
}
119
};
120
121
template <typename ET> struct calcDist_<Vec<ET, 4> >
122
{
123
static inline int f(const Vec<ET, 4> a, const Vec<ET, 4> b)
124
{
125
return
126
std::abs((int)(a[0]-b[0])) +
127
std::abs((int)(a[1]-b[1])) +
128
std::abs((int)(a[2]-b[2])) +
129
std::abs((int)(a[3]-b[3]));
130
}
131
};
132
133
template <typename T, typename WT> struct calcWeight_
134
{
135
static inline WT f(double dist, const float *h, WT fixed_point_mult)
136
{
137
double w = std::exp(-dist*dist / (h[0]*h[0] * pixelInfo<T>::channels));
138
if (std::isnan(w)) w = 1.0; // Handle h = 0.0
139
140
static const double WEIGHT_THRESHOLD = 0.001;
141
WT weight = (WT)cvRound(fixed_point_mult * w);
142
if (weight < WEIGHT_THRESHOLD * fixed_point_mult) weight = 0;
143
144
return weight;
145
}
146
};
147
148
template <typename T, typename ET, int n> struct calcWeight_<T, Vec<ET, n> >
149
{
150
static inline Vec<ET, n> f(double dist, const float *h, ET fixed_point_mult)
151
{
152
Vec<ET, n> res;
153
for (int i=0; i<n; i++)
154
res[i] = calcWeight<T, ET>(dist, &h[i], fixed_point_mult);
155
return res;
156
}
157
};
158
159
public:
160
template <typename T> static inline int calcDist(const T a, const T b)
161
{
162
return calcDist_<T>::f(a, b);
163
}
164
165
template <typename T>
166
static inline int calcDist(const Mat& m, int i1, int j1, int i2, int j2)
167
{
168
const T a = m.at<T>(i1, j1);
169
const T b = m.at<T>(i2, j2);
170
return calcDist<T>(a,b);
171
}
172
173
template <typename T>
174
static inline int calcUpDownDist(T a_up, T a_down, T b_up, T b_down)
175
{
176
return calcDist<T>(a_down, b_down) - calcDist<T>(a_up, b_up);
177
};
178
179
template <typename T, typename WT>
180
static inline WT calcWeight(double dist, const float *h,
181
typename pixelInfo<WT>::sampleType fixed_point_mult)
182
{
183
return calcWeight_<T, WT>::f(dist, h, fixed_point_mult);
184
}
185
186
template <typename T>
187
static inline int maxDist()
188
{
189
return (int)pixelInfo<T>::sampleMax() * pixelInfo<T>::channels;
190
}
191
};
192
193
class DistSquared
194
{
195
template <typename T> struct calcDist_
196
{
197
static inline int f(const T a, const T b)
198
{
199
return (int)(a-b) * (int)(a-b);
200
}
201
};
202
203
template <typename ET> struct calcDist_<Vec<ET, 2> >
204
{
205
static inline int f(const Vec<ET, 2> a, const Vec<ET, 2> b)
206
{
207
return (int)(a[0]-b[0])*(int)(a[0]-b[0]) + (int)(a[1]-b[1])*(int)(a[1]-b[1]);
208
}
209
};
210
211
template <typename ET> struct calcDist_<Vec<ET, 3> >
212
{
213
static inline int f(const Vec<ET, 3> a, const Vec<ET, 3> b)
214
{
215
return
216
(int)(a[0]-b[0])*(int)(a[0]-b[0]) +
217
(int)(a[1]-b[1])*(int)(a[1]-b[1]) +
218
(int)(a[2]-b[2])*(int)(a[2]-b[2]);
219
}
220
};
221
222
template <typename ET> struct calcDist_<Vec<ET, 4> >
223
{
224
static inline int f(const Vec<ET, 4> a, const Vec<ET, 4> b)
225
{
226
return
227
(int)(a[0]-b[0])*(int)(a[0]-b[0]) +
228
(int)(a[1]-b[1])*(int)(a[1]-b[1]) +
229
(int)(a[2]-b[2])*(int)(a[2]-b[2]) +
230
(int)(a[3]-b[3])*(int)(a[3]-b[3]);
231
}
232
};
233
234
template <typename T> struct calcUpDownDist_
235
{
236
static inline int f(T a_up, T a_down, T b_up, T b_down)
237
{
238
int A = a_down - b_down;
239
int B = a_up - b_up;
240
return (A-B)*(A+B);
241
}
242
};
243
244
template <typename ET, int n> struct calcUpDownDist_<Vec<ET, n> >
245
{
246
private:
247
typedef Vec<ET, n> T;
248
public:
249
static inline int f(T a_up, T a_down, T b_up, T b_down)
250
{
251
return calcDist<T>(a_down, b_down) - calcDist<T>(a_up, b_up);
252
}
253
};
254
255
template <typename T, typename WT> struct calcWeight_
256
{
257
static inline WT f(double dist, const float *h, WT fixed_point_mult)
258
{
259
double w = std::exp(-dist / (h[0]*h[0] * pixelInfo<T>::channels));
260
if (std::isnan(w)) w = 1.0; // Handle h = 0.0
261
262
static const double WEIGHT_THRESHOLD = 0.001;
263
WT weight = (WT)cvRound(fixed_point_mult * w);
264
if (weight < WEIGHT_THRESHOLD * fixed_point_mult) weight = 0;
265
266
return weight;
267
}
268
};
269
270
template <typename T, typename ET, int n> struct calcWeight_<T, Vec<ET, n> >
271
{
272
static inline Vec<ET, n> f(double dist, const float *h, ET fixed_point_mult)
273
{
274
Vec<ET, n> res;
275
for (int i=0; i<n; i++)
276
res[i] = calcWeight<T, ET>(dist, &h[i], fixed_point_mult);
277
return res;
278
}
279
};
280
281
public:
282
template <typename T> static inline int calcDist(const T a, const T b)
283
{
284
return calcDist_<T>::f(a, b);
285
}
286
287
template <typename T>
288
static inline int calcDist(const Mat& m, int i1, int j1, int i2, int j2)
289
{
290
const T a = m.at<T>(i1, j1);
291
const T b = m.at<T>(i2, j2);
292
return calcDist<T>(a,b);
293
}
294
295
template <typename T>
296
static inline int calcUpDownDist(T a_up, T a_down, T b_up, T b_down)
297
{
298
return calcUpDownDist_<T>::f(a_up, a_down, b_up, b_down);
299
};
300
301
template <typename T, typename WT>
302
static inline WT calcWeight(double dist, const float *h,
303
typename pixelInfo<WT>::sampleType fixed_point_mult)
304
{
305
return calcWeight_<T, WT>::f(dist, h, fixed_point_mult);
306
}
307
308
template <typename T>
309
static inline int maxDist()
310
{
311
return (int)pixelInfo<T>::sampleMax() * (int)pixelInfo<T>::sampleMax() *
312
pixelInfo<T>::channels;
313
}
314
};
315
316
template <typename T, typename IT, typename WT> struct incWithWeight_
317
{
318
static inline void f(IT* estimation, IT* weights_sum, WT weight, T p)
319
{
320
estimation[0] += (IT)weight * p;
321
weights_sum[0] += (IT)weight;
322
}
323
};
324
325
template <typename ET, typename IT, typename WT> struct incWithWeight_<Vec<ET, 2>, IT, WT>
326
{
327
static inline void f(IT* estimation, IT* weights_sum, WT weight, Vec<ET, 2> p)
328
{
329
estimation[0] += (IT)weight * p[0];
330
estimation[1] += (IT)weight * p[1];
331
weights_sum[0] += (IT)weight;
332
}
333
};
334
335
template <typename ET, typename IT, typename WT> struct incWithWeight_<Vec<ET, 3>, IT, WT>
336
{
337
static inline void f(IT* estimation, IT* weights_sum, WT weight, Vec<ET, 3> p)
338
{
339
estimation[0] += (IT)weight * p[0];
340
estimation[1] += (IT)weight * p[1];
341
estimation[2] += (IT)weight * p[2];
342
weights_sum[0] += (IT)weight;
343
}
344
};
345
346
template <typename ET, typename IT, typename WT> struct incWithWeight_<Vec<ET, 4>, IT, WT>
347
{
348
static inline void f(IT* estimation, IT* weights_sum, WT weight, Vec<ET, 4> p)
349
{
350
estimation[0] += (IT)weight * p[0];
351
estimation[1] += (IT)weight * p[1];
352
estimation[2] += (IT)weight * p[2];
353
estimation[3] += (IT)weight * p[3];
354
weights_sum[0] += (IT)weight;
355
}
356
};
357
358
template <typename ET, typename IT, typename EW> struct incWithWeight_<Vec<ET, 2>, IT, Vec<EW, 2> >
359
{
360
static inline void f(IT* estimation, IT* weights_sum, Vec<EW, 2> weight, Vec<ET, 2> p)
361
{
362
estimation[0] += (IT)weight[0] * p[0];
363
estimation[1] += (IT)weight[1] * p[1];
364
weights_sum[0] += (IT)weight[0];
365
weights_sum[1] += (IT)weight[1];
366
}
367
};
368
369
template <typename ET, typename IT, typename EW> struct incWithWeight_<Vec<ET, 3>, IT, Vec<EW, 3> >
370
{
371
static inline void f(IT* estimation, IT* weights_sum, Vec<EW, 3> weight, Vec<ET, 3> p)
372
{
373
estimation[0] += (IT)weight[0] * p[0];
374
estimation[1] += (IT)weight[1] * p[1];
375
estimation[2] += (IT)weight[2] * p[2];
376
weights_sum[0] += (IT)weight[0];
377
weights_sum[1] += (IT)weight[1];
378
weights_sum[2] += (IT)weight[2];
379
}
380
};
381
382
template <typename ET, typename IT, typename EW> struct incWithWeight_<Vec<ET, 4>, IT, Vec<EW, 4> >
383
{
384
static inline void f(IT* estimation, IT* weights_sum, Vec<EW, 4> weight, Vec<ET, 4> p)
385
{
386
estimation[0] += (IT)weight[0] * p[0];
387
estimation[1] += (IT)weight[1] * p[1];
388
estimation[2] += (IT)weight[2] * p[2];
389
estimation[3] += (IT)weight[3] * p[3];
390
weights_sum[0] += (IT)weight[0];
391
weights_sum[1] += (IT)weight[1];
392
weights_sum[2] += (IT)weight[2];
393
weights_sum[3] += (IT)weight[3];
394
}
395
};
396
397
template <typename T, typename IT, typename WT>
398
static inline void incWithWeight(IT* estimation, IT* weights_sum, WT weight, T p)
399
{
400
incWithWeight_<T, IT, WT>::f(estimation, weights_sum, weight, p);
401
}
402
403
template <typename IT, typename UIT, int nc, int nw> struct divByWeightsSum_
404
{
405
static inline void f(IT* estimation, IT* weights_sum);
406
};
407
408
template <typename IT, typename UIT> struct divByWeightsSum_<IT, UIT, 1, 1>
409
{
410
static inline void f(IT* estimation, IT* weights_sum)
411
{
412
estimation[0] = (static_cast<UIT>(estimation[0]) + weights_sum[0]/2) / weights_sum[0];
413
}
414
};
415
416
template <typename IT, typename UIT, int n> struct divByWeightsSum_<IT, UIT, n, 1>
417
{
418
static inline void f(IT* estimation, IT* weights_sum)
419
{
420
for (size_t i = 0; i < n; i++)
421
estimation[i] = (static_cast<UIT>(estimation[i]) + weights_sum[0]/2) / weights_sum[0];
422
}
423
};
424
425
template <typename IT, typename UIT, int n> struct divByWeightsSum_<IT, UIT, n, n>
426
{
427
static inline void f(IT* estimation, IT* weights_sum)
428
{
429
for (size_t i = 0; i < n; i++)
430
estimation[i] = (static_cast<UIT>(estimation[i]) + weights_sum[i]/2) / weights_sum[i];
431
}
432
};
433
434
template <typename IT, typename UIT, int nc, int nw>
435
static inline void divByWeightsSum(IT* estimation, IT* weights_sum)
436
{
437
divByWeightsSum_<IT, UIT, nc, nw>::f(estimation, weights_sum);
438
}
439
440
template <typename T, typename IT> struct saturateCastFromArray_
441
{
442
static inline T f(IT* estimation)
443
{
444
return saturate_cast<T>(estimation[0]);
445
}
446
};
447
448
template <typename ET, typename IT> struct saturateCastFromArray_<Vec<ET, 2>, IT>
449
{
450
static inline Vec<ET, 2> f(IT* estimation)
451
{
452
Vec<ET, 2> res;
453
res[0] = saturate_cast<ET>(estimation[0]);
454
res[1] = saturate_cast<ET>(estimation[1]);
455
return res;
456
}
457
};
458
459
template <typename ET, typename IT> struct saturateCastFromArray_<Vec<ET, 3>, IT>
460
{
461
static inline Vec<ET, 3> f(IT* estimation)
462
{
463
Vec<ET, 3> res;
464
res[0] = saturate_cast<ET>(estimation[0]);
465
res[1] = saturate_cast<ET>(estimation[1]);
466
res[2] = saturate_cast<ET>(estimation[2]);
467
return res;
468
}
469
};
470
471
template <typename ET, typename IT> struct saturateCastFromArray_<Vec<ET, 4>, IT>
472
{
473
static inline Vec<ET, 4> f(IT* estimation)
474
{
475
Vec<ET, 4> res;
476
res[0] = saturate_cast<ET>(estimation[0]);
477
res[1] = saturate_cast<ET>(estimation[1]);
478
res[2] = saturate_cast<ET>(estimation[2]);
479
res[3] = saturate_cast<ET>(estimation[3]);
480
return res;
481
}
482
};
483
484
template <typename T, typename IT> static inline T saturateCastFromArray(IT* estimation)
485
{
486
return saturateCastFromArray_<T, IT>::f(estimation);
487
}
488
489
#endif
490
491