~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/modules/photo/src/denoising.cpp

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include "precomp.hpp"
 
43
 
 
44
#include "fast_nlmeans_denoising_invoker.hpp"
 
45
#include "fast_nlmeans_multi_denoising_invoker.hpp"
 
46
#include "fast_nlmeans_denoising_opencl.hpp"
 
47
 
 
48
template<typename ST, typename IT, typename UIT, typename D>
 
49
static void fastNlMeansDenoising_( const Mat& src, Mat& dst, const std::vector<float>& h,
 
50
                                   int templateWindowSize, int searchWindowSize)
 
51
{
 
52
    int hn = (int)h.size();
 
53
    double granularity = (double)std::max(1., (double)dst.total()/(1 << 17));
 
54
 
 
55
    switch (CV_MAT_CN(src.type())) {
 
56
        case 1:
 
57
            parallel_for_(cv::Range(0, src.rows),
 
58
                          FastNlMeansDenoisingInvoker<ST, IT, UIT, D, int>(
 
59
                              src, dst, templateWindowSize, searchWindowSize, &h[0]),
 
60
                          granularity);
 
61
            break;
 
62
        case 2:
 
63
            if (hn == 1)
 
64
                parallel_for_(cv::Range(0, src.rows),
 
65
                              FastNlMeansDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, int>(
 
66
                                  src, dst, templateWindowSize, searchWindowSize, &h[0]),
 
67
                              granularity);
 
68
            else
 
69
                parallel_for_(cv::Range(0, src.rows),
 
70
                              FastNlMeansDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, Vec2i>(
 
71
                                  src, dst, templateWindowSize, searchWindowSize, &h[0]),
 
72
                              granularity);
 
73
            break;
 
74
        case 3:
 
75
            if (hn == 1)
 
76
                parallel_for_(cv::Range(0, src.rows),
 
77
                              FastNlMeansDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, int>(
 
78
                                  src, dst, templateWindowSize, searchWindowSize, &h[0]),
 
79
                              granularity);
 
80
            else
 
81
                parallel_for_(cv::Range(0, src.rows),
 
82
                              FastNlMeansDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, Vec3i>(
 
83
                                  src, dst, templateWindowSize, searchWindowSize, &h[0]),
 
84
                              granularity);
 
85
            break;
 
86
        case 4:
 
87
            if (hn == 1)
 
88
                parallel_for_(cv::Range(0, src.rows),
 
89
                              FastNlMeansDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, int>(
 
90
                                  src, dst, templateWindowSize, searchWindowSize, &h[0]),
 
91
                              granularity);
 
92
            else
 
93
                parallel_for_(cv::Range(0, src.rows),
 
94
                              FastNlMeansDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, Vec4i>(
 
95
                                  src, dst, templateWindowSize, searchWindowSize, &h[0]),
 
96
                              granularity);
 
97
            break;
 
98
        default:
 
99
            CV_Error(Error::StsBadArg,
 
100
                     "Unsupported number of channels! Only 1, 2, 3, and 4 are supported");
 
101
    }
 
102
}
 
103
 
 
104
void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h,
 
105
                               int templateWindowSize, int searchWindowSize)
 
106
{
 
107
    fastNlMeansDenoising(_src, _dst, std::vector<float>(1, h),
 
108
                         templateWindowSize, searchWindowSize);
 
109
}
 
110
 
 
111
void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, const std::vector<float>& h,
 
112
                               int templateWindowSize, int searchWindowSize, int normType)
 
113
{
 
114
    int hn = (int)h.size(), type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
 
115
    CV_Assert(hn == 1 || hn == cn);
 
116
 
 
117
    Size src_size = _src.size();
 
118
    CV_OCL_RUN(_src.dims() <= 2 && (_src.isUMat() || _dst.isUMat()) &&
 
119
               src_size.width > 5 && src_size.height > 5, // low accuracy on small sizes
 
120
               ocl_fastNlMeansDenoising(_src, _dst, &h[0], hn,
 
121
                                        templateWindowSize, searchWindowSize, normType))
 
122
 
 
123
    Mat src = _src.getMat();
 
124
    _dst.create(src_size, src.type());
 
125
    Mat dst = _dst.getMat();
 
126
 
 
127
    switch (normType) {
 
128
        case NORM_L2:
 
129
#ifdef HAVE_TEGRA_OPTIMIZATION
 
130
            if(hn == 1 && tegra::useTegra() &&
 
131
               tegra::fastNlMeansDenoising(src, dst, h[0], templateWindowSize, searchWindowSize))
 
132
                return;
 
133
#endif
 
134
            switch (depth) {
 
135
                case CV_8U:
 
136
                    fastNlMeansDenoising_<uchar, int, unsigned, DistSquared>(src, dst, h,
 
137
                                                                             templateWindowSize,
 
138
                                                                             searchWindowSize);
 
139
                    break;
 
140
                default:
 
141
                    CV_Error(Error::StsBadArg,
 
142
                             "Unsupported depth! Only CV_8U is supported for NORM_L2");
 
143
            }
 
144
            break;
 
145
        case NORM_L1:
 
146
            switch (depth) {
 
147
                case CV_8U:
 
148
                    fastNlMeansDenoising_<uchar, int, unsigned, DistAbs>(src, dst, h,
 
149
                                                                         templateWindowSize,
 
150
                                                                         searchWindowSize);
 
151
                    break;
 
152
                case CV_16U:
 
153
                    fastNlMeansDenoising_<ushort, int64, uint64, DistAbs>(src, dst, h,
 
154
                                                                          templateWindowSize,
 
155
                                                                          searchWindowSize);
 
156
                    break;
 
157
                default:
 
158
                    CV_Error(Error::StsBadArg,
 
159
                             "Unsupported depth! Only CV_8U and CV_16U are supported for NORM_L1");
 
160
            }
 
161
            break;
 
162
        default:
 
163
            CV_Error(Error::StsBadArg,
 
164
                     "Unsupported norm type! Only NORM_L2 and NORM_L1 are supported");
 
165
    }
 
166
}
 
167
 
 
168
void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst,
 
169
                                      float h, float hForColorComponents,
 
170
                                      int templateWindowSize, int searchWindowSize)
 
171
{
 
172
    int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
 
173
    Size src_size = _src.size();
 
174
    if (type != CV_8UC3 && type != CV_8UC4)
 
175
    {
 
176
        CV_Error(Error::StsBadArg, "Type of input image should be CV_8UC3 or CV_8UC4!");
 
177
        return;
 
178
    }
 
179
 
 
180
    CV_OCL_RUN(_src.dims() <= 2 && (_dst.isUMat() || _src.isUMat()) &&
 
181
                src_size.width > 5 && src_size.height > 5, // low accuracy on small sizes
 
182
                ocl_fastNlMeansDenoisingColored(_src, _dst, h, hForColorComponents,
 
183
                                                templateWindowSize, searchWindowSize))
 
184
 
 
185
    Mat src = _src.getMat();
 
186
    _dst.create(src_size, type);
 
187
    Mat dst = _dst.getMat();
 
188
 
 
189
    Mat src_lab;
 
190
    cvtColor(src, src_lab, COLOR_LBGR2Lab);
 
191
 
 
192
    Mat l(src_size, CV_MAKE_TYPE(depth, 1));
 
193
    Mat ab(src_size, CV_MAKE_TYPE(depth, 2));
 
194
    Mat l_ab[] = { l, ab };
 
195
    int from_to[] = { 0,0, 1,1, 2,2 };
 
196
    mixChannels(&src_lab, 1, l_ab, 2, from_to, 3);
 
197
 
 
198
    fastNlMeansDenoising(l, l, h, templateWindowSize, searchWindowSize);
 
199
    fastNlMeansDenoising(ab, ab, hForColorComponents, templateWindowSize, searchWindowSize);
 
200
 
 
201
    Mat l_ab_denoised[] = { l, ab };
 
202
    Mat dst_lab(src_size, CV_MAKE_TYPE(depth, 3));
 
203
    mixChannels(l_ab_denoised, 2, &dst_lab, 1, from_to, 3);
 
204
 
 
205
    cvtColor(dst_lab, dst, COLOR_Lab2LBGR, cn);
 
206
}
 
207
 
 
208
static void fastNlMeansDenoisingMultiCheckPreconditions(
 
209
                               const std::vector<Mat>& srcImgs,
 
210
                               int imgToDenoiseIndex, int temporalWindowSize,
 
211
                               int templateWindowSize, int searchWindowSize)
 
212
{
 
213
    int src_imgs_size = static_cast<int>(srcImgs.size());
 
214
    if (src_imgs_size == 0)
 
215
    {
 
216
        CV_Error(Error::StsBadArg, "Input images vector should not be empty!");
 
217
    }
 
218
 
 
219
    if (temporalWindowSize % 2 == 0 ||
 
220
        searchWindowSize % 2 == 0 ||
 
221
        templateWindowSize % 2 == 0) {
 
222
        CV_Error(Error::StsBadArg, "All windows sizes should be odd!");
 
223
    }
 
224
 
 
225
    int temporalWindowHalfSize = temporalWindowSize / 2;
 
226
    if (imgToDenoiseIndex - temporalWindowHalfSize < 0 ||
 
227
        imgToDenoiseIndex + temporalWindowHalfSize >= src_imgs_size)
 
228
    {
 
229
        CV_Error(Error::StsBadArg,
 
230
            "imgToDenoiseIndex and temporalWindowSize "
 
231
            "should be chosen corresponding srcImgs size!");
 
232
    }
 
233
 
 
234
    for (int i = 1; i < src_imgs_size; i++)
 
235
        if (srcImgs[0].size() != srcImgs[i].size() || srcImgs[0].type() != srcImgs[i].type())
 
236
        {
 
237
            CV_Error(Error::StsBadArg, "Input images should have the same size and type!");
 
238
        }
 
239
}
 
240
 
 
241
template<typename ST, typename IT, typename UIT, typename D>
 
242
static void fastNlMeansDenoisingMulti_( const std::vector<Mat>& srcImgs, Mat& dst,
 
243
                                        int imgToDenoiseIndex, int temporalWindowSize,
 
244
                                        const std::vector<float>& h,
 
245
                                        int templateWindowSize, int searchWindowSize)
 
246
{
 
247
    int hn = (int)h.size();
 
248
    double granularity = (double)std::max(1., (double)dst.total()/(1 << 16));
 
249
 
 
250
    switch (srcImgs[0].type())
 
251
    {
 
252
        case CV_8U:
 
253
            parallel_for_(cv::Range(0, srcImgs[0].rows),
 
254
                          FastNlMeansMultiDenoisingInvoker<uchar, IT, UIT, D, int>(
 
255
                              srcImgs, imgToDenoiseIndex, temporalWindowSize,
 
256
                              dst, templateWindowSize, searchWindowSize, &h[0]),
 
257
                          granularity);
 
258
            break;
 
259
        case CV_8UC2:
 
260
            if (hn == 1)
 
261
                parallel_for_(cv::Range(0, srcImgs[0].rows),
 
262
                              FastNlMeansMultiDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, int>(
 
263
                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
 
264
                                  dst, templateWindowSize, searchWindowSize, &h[0]),
 
265
                              granularity);
 
266
            else
 
267
                parallel_for_(cv::Range(0, srcImgs[0].rows),
 
268
                              FastNlMeansMultiDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, Vec2i>(
 
269
                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
 
270
                                  dst, templateWindowSize, searchWindowSize, &h[0]),
 
271
                              granularity);
 
272
            break;
 
273
        case CV_8UC3:
 
274
            if (hn == 1)
 
275
                parallel_for_(cv::Range(0, srcImgs[0].rows),
 
276
                              FastNlMeansMultiDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, int>(
 
277
                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
 
278
                                  dst, templateWindowSize, searchWindowSize, &h[0]),
 
279
                              granularity);
 
280
            else
 
281
                parallel_for_(cv::Range(0, srcImgs[0].rows),
 
282
                              FastNlMeansMultiDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, Vec3i>(
 
283
                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
 
284
                                  dst, templateWindowSize, searchWindowSize, &h[0]),
 
285
                              granularity);
 
286
            break;
 
287
        case CV_8UC4:
 
288
            if (hn == 1)
 
289
                parallel_for_(cv::Range(0, srcImgs[0].rows),
 
290
                              FastNlMeansMultiDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, int>(
 
291
                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
 
292
                                  dst, templateWindowSize, searchWindowSize, &h[0]),
 
293
                              granularity);
 
294
            else
 
295
                parallel_for_(cv::Range(0, srcImgs[0].rows),
 
296
                              FastNlMeansMultiDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, Vec4i>(
 
297
                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
 
298
                                  dst, templateWindowSize, searchWindowSize, &h[0]),
 
299
                              granularity);
 
300
            break;
 
301
        default:
 
302
            CV_Error(Error::StsBadArg,
 
303
                "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported");
 
304
    }
 
305
}
 
306
 
 
307
void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
 
308
                                    int imgToDenoiseIndex, int temporalWindowSize,
 
309
                                    float h, int templateWindowSize, int searchWindowSize)
 
310
{
 
311
    fastNlMeansDenoisingMulti(_srcImgs, _dst, imgToDenoiseIndex, temporalWindowSize,
 
312
                              std::vector<float>(1, h), templateWindowSize, searchWindowSize);
 
313
}
 
314
 
 
315
void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
 
316
                                    int imgToDenoiseIndex, int temporalWindowSize,
 
317
                                    const std::vector<float>& h,
 
318
                                    int templateWindowSize, int searchWindowSize, int normType)
 
319
{
 
320
    std::vector<Mat> srcImgs;
 
321
    _srcImgs.getMatVector(srcImgs);
 
322
 
 
323
    fastNlMeansDenoisingMultiCheckPreconditions(
 
324
        srcImgs, imgToDenoiseIndex,
 
325
        temporalWindowSize, templateWindowSize, searchWindowSize);
 
326
 
 
327
    int hn = (int)h.size();
 
328
    int type = srcImgs[0].type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
 
329
    CV_Assert(hn == 1 || hn == cn);
 
330
 
 
331
    _dst.create(srcImgs[0].size(), srcImgs[0].type());
 
332
    Mat dst = _dst.getMat();
 
333
 
 
334
    switch (normType) {
 
335
        case NORM_L2:
 
336
            switch (depth) {
 
337
                case CV_8U:
 
338
                    fastNlMeansDenoisingMulti_<uchar, int, unsigned,
 
339
                                               DistSquared>(srcImgs, dst,
 
340
                                                            imgToDenoiseIndex, temporalWindowSize,
 
341
                                                            h,
 
342
                                                            templateWindowSize, searchWindowSize);
 
343
                    break;
 
344
                default:
 
345
                    CV_Error(Error::StsBadArg,
 
346
                             "Unsupported depth! Only CV_8U is supported for NORM_L2");
 
347
            }
 
348
            break;
 
349
        case NORM_L1:
 
350
            switch (depth) {
 
351
                case CV_8U:
 
352
                    fastNlMeansDenoisingMulti_<uchar, int, unsigned,
 
353
                                               DistAbs>(srcImgs, dst,
 
354
                                                        imgToDenoiseIndex, temporalWindowSize,
 
355
                                                        h,
 
356
                                                        templateWindowSize, searchWindowSize);
 
357
                    break;
 
358
                case CV_16U:
 
359
                    fastNlMeansDenoisingMulti_<ushort, int64, uint64,
 
360
                                               DistAbs>(srcImgs, dst,
 
361
                                                        imgToDenoiseIndex, temporalWindowSize,
 
362
                                                        h,
 
363
                                                        templateWindowSize, searchWindowSize);
 
364
                    break;
 
365
                default:
 
366
                    CV_Error(Error::StsBadArg,
 
367
                             "Unsupported depth! Only CV_8U and CV_16U are supported for NORM_L1");
 
368
            }
 
369
            break;
 
370
        default:
 
371
            CV_Error(Error::StsBadArg,
 
372
                     "Unsupported norm type! Only NORM_L2 and NORM_L1 are supported");
 
373
    }
 
374
}
 
375
 
 
376
void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
 
377
                                           int imgToDenoiseIndex, int temporalWindowSize,
 
378
                                           float h, float hForColorComponents,
 
379
                                           int templateWindowSize, int searchWindowSize)
 
380
{
 
381
    std::vector<Mat> srcImgs;
 
382
    _srcImgs.getMatVector(srcImgs);
 
383
 
 
384
    fastNlMeansDenoisingMultiCheckPreconditions(
 
385
        srcImgs, imgToDenoiseIndex,
 
386
        temporalWindowSize, templateWindowSize, searchWindowSize);
 
387
 
 
388
    _dst.create(srcImgs[0].size(), srcImgs[0].type());
 
389
    Mat dst = _dst.getMat();
 
390
 
 
391
    int type = srcImgs[0].type(), depth = CV_MAT_DEPTH(type);
 
392
    int src_imgs_size = static_cast<int>(srcImgs.size());
 
393
 
 
394
    if (type != CV_8UC3)
 
395
    {
 
396
        CV_Error(Error::StsBadArg, "Type of input images should be CV_8UC3!");
 
397
        return;
 
398
    }
 
399
 
 
400
    int from_to[] = { 0,0, 1,1, 2,2 };
 
401
 
 
402
    // TODO convert only required images
 
403
    std::vector<Mat> src_lab(src_imgs_size);
 
404
    std::vector<Mat> l(src_imgs_size);
 
405
    std::vector<Mat> ab(src_imgs_size);
 
406
    for (int i = 0; i < src_imgs_size; i++)
 
407
    {
 
408
        src_lab[i] = Mat::zeros(srcImgs[0].size(), type);
 
409
        l[i] = Mat::zeros(srcImgs[0].size(), CV_MAKE_TYPE(depth, 1));
 
410
        ab[i] = Mat::zeros(srcImgs[0].size(), CV_MAKE_TYPE(depth, 2));
 
411
        cvtColor(srcImgs[i], src_lab[i], COLOR_LBGR2Lab);
 
412
 
 
413
        Mat l_ab[] = { l[i], ab[i] };
 
414
        mixChannels(&src_lab[i], 1, l_ab, 2, from_to, 3);
 
415
    }
 
416
 
 
417
    Mat dst_l;
 
418
    Mat dst_ab;
 
419
 
 
420
    fastNlMeansDenoisingMulti(
 
421
        l, dst_l, imgToDenoiseIndex, temporalWindowSize,
 
422
        h, templateWindowSize, searchWindowSize);
 
423
 
 
424
    fastNlMeansDenoisingMulti(
 
425
        ab, dst_ab, imgToDenoiseIndex, temporalWindowSize,
 
426
        hForColorComponents, templateWindowSize, searchWindowSize);
 
427
 
 
428
    Mat l_ab_denoised[] = { dst_l, dst_ab };
 
429
    Mat dst_lab(srcImgs[0].size(), srcImgs[0].type());
 
430
    mixChannels(l_ab_denoised, 2, &dst_lab, 1, from_to, 3);
 
431
 
 
432
    cvtColor(dst_lab, dst, COLOR_Lab2LBGR);
 
433
}