CLAHE Python bindings
[profile/ivi/opencv.git] / modules / ocl / perf / perf_imgproc.cpp
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 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
14 // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // @Authors
18 //    Fangfang Bai, fangfang@multicorewareinc.com
19 //    Jin Ma,       jin@multicorewareinc.com
20 //
21 // Redistribution and use in source and binary forms, with or without modification,
22 // are permitted provided that the following conditions are met:
23 //
24 //   * Redistribution's of source code must retain the above copyright notice,
25 //     this list of conditions and the following disclaimer.
26 //
27 //   * Redistribution's in binary form must reproduce the above copyright notice,
28 //     this list of conditions and the following disclaimer in the documentation
29 //     and/or other oclMaterials provided with the distribution.
30 //
31 //   * The name of the copyright holders may not be used to endorse or promote products
32 //     derived from this software without specific prior written permission.
33 //
34 // This software is provided by the copyright holders and contributors as is and
35 // any express or implied warranties, including, but not limited to, the implied
36 // warranties of merchantability and fitness for a particular purpose are disclaimed.
37 // In no event shall the Intel Corporation or contributors be liable for any direct,
38 // indirect, incidental, special, exemplary, or consequential damages
39 // (including, but not limited to, procurement of substitute goods or services;
40 // loss of use, data, or profits; or business interruption) however caused
41 // and on any theory of liability, whether in contract, strict liability,
42 // or tort (including negligence or otherwise) arising in any way out of
43 // the use of this software, even if advised of the possibility of such damage.
44 //
45 //M*/
46 #include "precomp.hpp"
47
48 ///////////// equalizeHist ////////////////////////
49 PERFTEST(equalizeHist)
50 {
51     Mat src, dst, ocl_dst;
52     int all_type[] = {CV_8UC1};
53     std::string type_name[] = {"CV_8UC1"};
54
55     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
56     {
57         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
58         {
59             SUBTEST << size << 'x' << size << "; " << type_name[j] ;
60
61             gen(src, size, size, all_type[j], 0, 256);
62
63             equalizeHist(src, dst);
64
65             CPU_ON;
66             equalizeHist(src, dst);
67             CPU_OFF;
68
69             ocl::oclMat d_src(src);
70             ocl::oclMat d_dst;
71             ocl::oclMat d_hist;
72             ocl::oclMat d_buf;
73
74             WARMUP_ON;
75             ocl::equalizeHist(d_src, d_dst);
76             WARMUP_OFF;
77
78             GPU_ON;
79             ocl::equalizeHist(d_src, d_dst);
80             GPU_OFF;
81
82             GPU_FULL_ON;
83             d_src.upload(src);
84             ocl::equalizeHist(d_src, d_dst);
85             d_dst.download(ocl_dst);
86             GPU_FULL_OFF;
87
88             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.1);
89         }
90
91     }
92 }
93 /////////// CopyMakeBorder //////////////////////
94 PERFTEST(CopyMakeBorder)
95 {
96     Mat src, dst, ocl_dst;
97     ocl::oclMat d_dst;
98
99     int bordertype = BORDER_CONSTANT;
100     int all_type[] = {CV_8UC1, CV_8UC4};
101     std::string type_name[] = {"CV_8UC1", "CV_8UC4"};
102
103     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
104     {
105         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
106         {
107             SUBTEST << size << 'x' << size << "; " << type_name[j] ;
108
109
110             gen(src, size, size, all_type[j], 0, 256);
111
112             copyMakeBorder(src, dst, 7, 5, 5, 7, bordertype, cv::Scalar(1.0));
113
114             CPU_ON;
115             copyMakeBorder(src, dst, 7, 5, 5, 7, bordertype, cv::Scalar(1.0));
116             CPU_OFF;
117
118             ocl::oclMat d_src(src);
119
120             WARMUP_ON;
121             ocl::copyMakeBorder(d_src, d_dst, 7, 5, 5, 7, bordertype, cv::Scalar(1.0));
122             WARMUP_OFF;
123
124             GPU_ON;
125             ocl::copyMakeBorder(d_src, d_dst, 7, 5, 5, 7, bordertype, cv::Scalar(1.0));
126             GPU_OFF;
127
128             GPU_FULL_ON;
129             d_src.upload(src);
130             ocl::copyMakeBorder(d_src, d_dst, 7, 5, 5, 7, bordertype, cv::Scalar(1.0));
131             d_dst.download(ocl_dst);
132             GPU_FULL_OFF;
133
134             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 0.0);
135         }
136
137     }
138 }
139 ///////////// cornerMinEigenVal ////////////////////////
140 PERFTEST(cornerMinEigenVal)
141 {
142     Mat src, dst, ocl_dst;
143     ocl::oclMat d_dst;
144
145     int blockSize = 7, apertureSize = 1 + 2 * (rand() % 4);
146     int borderType = BORDER_REFLECT;
147     int all_type[] = {CV_8UC1, CV_32FC1};
148     std::string type_name[] = {"CV_8UC1", "CV_32FC1"};
149
150     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
151     {
152         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
153         {
154             SUBTEST << size << 'x' << size << "; " << type_name[j] ;
155
156             gen(src, size, size, all_type[j], 0, 256);
157
158             cornerMinEigenVal(src, dst, blockSize, apertureSize, borderType);
159
160             CPU_ON;
161             cornerMinEigenVal(src, dst, blockSize, apertureSize, borderType);
162             CPU_OFF;
163
164             ocl::oclMat d_src(src);
165
166             WARMUP_ON;
167             ocl::cornerMinEigenVal(d_src, d_dst, blockSize, apertureSize, borderType);
168             WARMUP_OFF;
169
170             GPU_ON;
171             ocl::cornerMinEigenVal(d_src, d_dst, blockSize, apertureSize, borderType);
172             GPU_OFF;
173
174             GPU_FULL_ON;
175             d_src.upload(src);
176             ocl::cornerMinEigenVal(d_src, d_dst, blockSize, apertureSize, borderType);
177             d_dst.download(ocl_dst);
178             GPU_FULL_OFF;
179
180             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0);
181         }
182
183     }
184 }
185 ///////////// cornerHarris ////////////////////////
186 PERFTEST(cornerHarris)
187 {
188     Mat src, dst, ocl_dst;
189     ocl::oclMat d_src, d_dst;
190
191     int all_type[] = {CV_8UC1, CV_32FC1};
192     std::string type_name[] = {"CV_8UC1", "CV_32FC1"};
193
194     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
195     {
196         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
197         {
198             SUBTEST << size << 'x' << size << "; " << type_name[j] << " ; BORDER_REFLECT";
199
200             gen(src, size, size, all_type[j], 0, 1);
201
202             cornerHarris(src, dst, 5, 7, 0.1, BORDER_REFLECT);
203
204             CPU_ON;
205             cornerHarris(src, dst, 5, 7, 0.1, BORDER_REFLECT);
206             CPU_OFF;
207
208             d_src.upload(src);
209
210             WARMUP_ON;
211             ocl::cornerHarris(d_src, d_dst, 5, 7, 0.1, BORDER_REFLECT);
212             WARMUP_OFF;
213
214             GPU_ON;
215             ocl::cornerHarris(d_src, d_dst, 5, 7, 0.1, BORDER_REFLECT);
216             GPU_OFF;
217
218             GPU_FULL_ON;
219             d_src.upload(src);
220             ocl::cornerHarris(d_src, d_dst, 5, 7, 0.1, BORDER_REFLECT);
221             d_dst.download(ocl_dst);
222             GPU_FULL_OFF;
223
224             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0);
225         }
226
227
228     }
229 }
230 ///////////// integral ////////////////////////
231 PERFTEST(integral)
232 {
233     Mat src, sum, ocl_sum;
234     ocl::oclMat d_src, d_sum, d_buf;
235
236     int all_type[] = {CV_8UC1};
237     std::string type_name[] = {"CV_8UC1"};
238
239     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
240     {
241         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
242         {
243             SUBTEST << size << 'x' << size << "; " << type_name[j]  ;
244
245             gen(src, size, size, all_type[j], 0, 256);
246
247             integral(src, sum);
248
249             CPU_ON;
250             integral(src, sum);
251             CPU_OFF;
252
253             d_src.upload(src);
254
255             WARMUP_ON;
256             ocl::integral(d_src, d_sum);
257             WARMUP_OFF;
258
259             GPU_ON;
260             ocl::integral(d_src, d_sum);
261             GPU_OFF;
262
263             GPU_FULL_ON;
264             d_src.upload(src);
265             ocl::integral(d_src, d_sum);
266             d_sum.download(ocl_sum);
267             GPU_FULL_OFF;
268
269             if(sum.type() == ocl_sum.type()) //we won't test accuracy when cpu function overlow
270                 TestSystem::instance().ExpectedMatNear(sum, ocl_sum, 0.0);
271
272         }
273
274     }
275 }
276 ///////////// WarpAffine ////////////////////////
277 PERFTEST(WarpAffine)
278 {
279     Mat src, dst, ocl_dst;
280     ocl::oclMat d_src, d_dst;
281
282     static const double coeffs[2][3] =
283     {
284         {cos(CV_PI / 6), -sin(CV_PI / 6), 100.0},
285         {sin(CV_PI / 6), cos(CV_PI / 6), -100.0}
286     };
287     Mat M(2, 3, CV_64F, (void *)coeffs);
288     int interpolation = INTER_NEAREST;
289
290     int all_type[] = {CV_8UC1, CV_8UC4};
291     std::string type_name[] = {"CV_8UC1", "CV_8UC4"};
292
293
294     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
295     {
296         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
297         {
298             SUBTEST << size << 'x' << size << "; " << type_name[j] ;
299
300             gen(src, size, size, all_type[j], 0, 256);
301             gen(dst, size, size, all_type[j], 0, 256);
302             Size size1 = Size(size, size);
303
304             warpAffine(src, dst, M, size1, interpolation);
305
306             CPU_ON;
307             warpAffine(src, dst, M, size1, interpolation);
308             CPU_OFF;
309
310             d_src.upload(src);
311
312             WARMUP_ON;
313             ocl::warpAffine(d_src, d_dst, M, size1, interpolation);
314             WARMUP_OFF;
315
316             GPU_ON;
317             ocl::warpAffine(d_src, d_dst, M, size1, interpolation);
318             GPU_OFF;
319
320             GPU_FULL_ON;
321             d_src.upload(src);
322             ocl::warpAffine(d_src, d_dst, M, size1, interpolation);
323             d_dst.download(ocl_dst);
324             GPU_FULL_OFF;
325
326             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0);
327         }
328
329     }
330 }
331 ///////////// WarpPerspective ////////////////////////
332 PERFTEST(WarpPerspective)
333 {
334     Mat src, dst, ocl_dst;
335     ocl::oclMat d_src, d_dst;
336
337     static const double coeffs[3][3] =
338     {
339         {cos(CV_PI / 6), -sin(CV_PI / 6), 100.0},
340         {sin(CV_PI / 6), cos(CV_PI / 6), -100.0},
341         {0.0, 0.0, 1.0}
342     };
343     Mat M(3, 3, CV_64F, (void *)coeffs);
344     int interpolation = INTER_LINEAR;
345
346     int all_type[] = {CV_8UC1, CV_8UC4};
347     std::string type_name[] = {"CV_8UC1", "CV_8UC4"};
348
349     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
350     {
351         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
352         {
353             SUBTEST << size << 'x' << size << "; " << type_name[j] ;
354
355             gen(src, size, size, all_type[j], 0, 256);
356             gen(dst, size, size, all_type[j], 0, 256);
357             Size size1 = Size(size, size);
358
359             warpPerspective(src, dst, M, size1, interpolation);
360
361             CPU_ON;
362             warpPerspective(src, dst, M, size1, interpolation);
363             CPU_OFF;
364
365             d_src.upload(src);
366
367             WARMUP_ON;
368             ocl::warpPerspective(d_src, d_dst, M, size1, interpolation);
369             WARMUP_OFF;
370
371             GPU_ON;
372             ocl::warpPerspective(d_src, d_dst, M, size1, interpolation);
373             GPU_OFF;
374
375             GPU_FULL_ON;
376             d_src.upload(src);
377             ocl::warpPerspective(d_src, d_dst, M, size1, interpolation);
378             d_dst.download(ocl_dst);
379             GPU_FULL_OFF;
380
381             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0);
382         }
383
384     }
385 }
386
387 ///////////// resize ////////////////////////
388 PERFTEST(resize)
389 {
390     Mat src, dst, ocl_dst;
391     ocl::oclMat d_src, d_dst;
392
393
394     int all_type[] = {CV_8UC1, CV_8UC4};
395     std::string type_name[] = {"CV_8UC1", "CV_8UC4"};
396
397     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
398     {
399         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
400         {
401             SUBTEST << size << 'x' << size << "; " << type_name[j] << " ; up";
402
403             gen(src, size, size, all_type[j], 0, 256);
404
405             resize(src, dst, Size(), 2.0, 2.0);
406
407             CPU_ON;
408             resize(src, dst, Size(), 2.0, 2.0);
409             CPU_OFF;
410
411             d_src.upload(src);
412
413             WARMUP_ON;
414             ocl::resize(d_src, d_dst, Size(), 2.0, 2.0);
415             WARMUP_OFF;
416
417             GPU_ON;
418             ocl::resize(d_src, d_dst, Size(), 2.0, 2.0);
419             GPU_OFF;
420
421             GPU_FULL_ON;
422             d_src.upload(src);
423             ocl::resize(d_src, d_dst, Size(), 2.0, 2.0);
424             d_dst.download(ocl_dst);
425             GPU_FULL_OFF;
426
427             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0);
428         }
429
430     }
431
432     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
433     {
434         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
435         {
436             SUBTEST << size << 'x' << size << "; " << type_name[j] << " ; down";
437
438             gen(src, size, size, all_type[j], 0, 256);
439
440             resize(src, dst, Size(), 0.5, 0.5);
441
442             CPU_ON;
443             resize(src, dst, Size(), 0.5, 0.5);
444             CPU_OFF;
445
446             d_src.upload(src);
447
448             WARMUP_ON;
449             ocl::resize(d_src, d_dst, Size(), 0.5, 0.5);
450             WARMUP_OFF;
451
452             GPU_ON;
453             ocl::resize(d_src, d_dst, Size(), 0.5, 0.5);
454             GPU_OFF;
455
456             GPU_FULL_ON;
457             d_src.upload(src);
458             ocl::resize(d_src, d_dst, Size(), 0.5, 0.5);
459             d_dst.download(ocl_dst);
460             GPU_FULL_OFF;
461
462             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0);
463         }
464
465     }
466 }
467 ///////////// threshold////////////////////////
468 PERFTEST(threshold)
469 {
470     Mat src, dst, ocl_dst;
471     ocl::oclMat d_src, d_dst;
472
473     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
474     {
475         SUBTEST << size << 'x' << size << "; 8UC1; THRESH_BINARY";
476
477         gen(src, size, size, CV_8U, 0, 100);
478
479         threshold(src, dst, 50.0, 0.0, THRESH_BINARY);
480
481         CPU_ON;
482         threshold(src, dst, 50.0, 0.0, THRESH_BINARY);
483         CPU_OFF;
484
485         d_src.upload(src);
486
487         WARMUP_ON;
488         ocl::threshold(d_src, d_dst, 50.0, 0.0, THRESH_BINARY);
489         WARMUP_OFF;
490
491         GPU_ON;
492         ocl::threshold(d_src, d_dst, 50.0, 0.0, THRESH_BINARY);
493         GPU_OFF;
494
495         GPU_FULL_ON;
496         d_src.upload(src);
497         ocl::threshold(d_src, d_dst, 50.0, 0.0, THRESH_BINARY);
498         d_dst.download(ocl_dst);
499         GPU_FULL_OFF;
500
501         TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0);
502     }
503
504     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
505     {
506         SUBTEST << size << 'x' << size << "; 32FC1; THRESH_TRUNC [NPP]";
507
508         gen(src, size, size, CV_32FC1, 0, 100);
509
510         threshold(src, dst, 50.0, 0.0, THRESH_TRUNC);
511
512         CPU_ON;
513         threshold(src, dst, 50.0, 0.0, THRESH_TRUNC);
514         CPU_OFF;
515
516         d_src.upload(src);
517
518         WARMUP_ON;
519         ocl::threshold(d_src, d_dst, 50.0, 0.0, THRESH_TRUNC);
520         WARMUP_OFF;
521
522         GPU_ON;
523         ocl::threshold(d_src, d_dst, 50.0, 0.0, THRESH_TRUNC);
524         GPU_OFF;
525
526         GPU_FULL_ON;
527         d_src.upload(src);
528         ocl::threshold(d_src, d_dst, 50.0, 0.0, THRESH_TRUNC);
529         d_dst.download(ocl_dst);
530         GPU_FULL_OFF;
531
532         TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0);
533     }
534 }
535 ///////////// meanShiftFiltering////////////////////////
536 COOR do_meanShift(int x0, int y0, uchar *sptr, uchar *dptr, int sstep, cv::Size size, int sp, int sr, int maxIter, float eps, int *tab)
537 {
538
539     int isr2 = sr * sr;
540     int c0, c1, c2, c3;
541     int iter;
542     uchar *ptr = NULL;
543     uchar *pstart = NULL;
544     int revx = 0, revy = 0;
545     c0 = sptr[0];
546     c1 = sptr[1];
547     c2 = sptr[2];
548     c3 = sptr[3];
549     // iterate meanshift procedure
550     for(iter = 0; iter < maxIter; iter++ )
551     {
552         int count = 0;
553         int s0 = 0, s1 = 0, s2 = 0, sx = 0, sy = 0;
554
555         //mean shift: process pixels in window (p-sigmaSp)x(p+sigmaSp)
556         int minx = x0 - sp;
557         int miny = y0 - sp;
558         int maxx = x0 + sp;
559         int maxy = y0 + sp;
560
561         //deal with the image boundary
562         if(minx < 0) minx = 0;
563         if(miny < 0) miny = 0;
564         if(maxx >= size.width) maxx = size.width - 1;
565         if(maxy >= size.height) maxy = size.height - 1;
566         if(iter == 0)
567         {
568             pstart = sptr;
569         }
570         else
571         {
572             pstart = pstart + revy * sstep + (revx << 2); //point to the new position
573         }
574         ptr = pstart;
575         ptr = ptr + (miny - y0) * sstep + ((minx - x0) << 2); //point to the start in the row
576
577         for( int y = miny; y <= maxy; y++, ptr += sstep - ((maxx - minx + 1) << 2))
578         {
579             int rowCount = 0;
580             int x = minx;
581 #if CV_ENABLE_UNROLLED
582             for( ; x + 4 <= maxx; x += 4, ptr += 16)
583             {
584                 int t0, t1, t2;
585                 t0 = ptr[0], t1 = ptr[1], t2 = ptr[2];
586                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
587                 {
588                     s0 += t0;
589                     s1 += t1;
590                     s2 += t2;
591                     sx += x;
592                     rowCount++;
593                 }
594                 t0 = ptr[4], t1 = ptr[5], t2 = ptr[6];
595                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
596                 {
597                     s0 += t0;
598                     s1 += t1;
599                     s2 += t2;
600                     sx += x + 1;
601                     rowCount++;
602                 }
603                 t0 = ptr[8], t1 = ptr[9], t2 = ptr[10];
604                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
605                 {
606                     s0 += t0;
607                     s1 += t1;
608                     s2 += t2;
609                     sx += x + 2;
610                     rowCount++;
611                 }
612                 t0 = ptr[12], t1 = ptr[13], t2 = ptr[14];
613                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
614                 {
615                     s0 += t0;
616                     s1 += t1;
617                     s2 += t2;
618                     sx += x + 3;
619                     rowCount++;
620                 }
621             }
622 #endif
623             for(; x <= maxx; x++, ptr += 4)
624             {
625                 int t0 = ptr[0], t1 = ptr[1], t2 = ptr[2];
626                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
627                 {
628                     s0 += t0;
629                     s1 += t1;
630                     s2 += t2;
631                     sx += x;
632                     rowCount++;
633                 }
634             }
635             if(rowCount == 0)
636                 continue;
637             count += rowCount;
638             sy += y * rowCount;
639         }
640
641         if( count == 0 )
642             break;
643
644         int x1 = sx / count;
645         int y1 = sy / count;
646         s0 = s0 / count;
647         s1 = s1 / count;
648         s2 = s2 / count;
649
650         bool stopFlag = (x0 == x1 && y0 == y1) || (abs(x1 - x0) + abs(y1 - y0) +
651             tab[s0 - c0 + 255] + tab[s1 - c1 + 255] + tab[s2 - c2 + 255] <= eps);
652
653         //revise the pointer corresponding to the new (y0,x0)
654         revx = x1 - x0;
655         revy = y1 - y0;
656
657         x0 = x1;
658         y0 = y1;
659         c0 = s0;
660         c1 = s1;
661         c2 = s2;
662
663         if( stopFlag )
664             break;
665     } //for iter
666
667     dptr[0] = (uchar)c0;
668     dptr[1] = (uchar)c1;
669     dptr[2] = (uchar)c2;
670     dptr[3] = (uchar)c3;
671
672     COOR coor;
673     coor.x = static_cast<short>(x0);
674     coor.y = static_cast<short>(y0);
675     return coor;
676 }
677
678 static void meanShiftFiltering_(const Mat &src_roi, Mat &dst_roi, int sp, int sr, cv::TermCriteria crit)
679 {
680     if( src_roi.empty() )
681         CV_Error( CV_StsBadArg, "The input image is empty" );
682
683     if( src_roi.depth() != CV_8U || src_roi.channels() != 4 )
684         CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 4-channel images are supported" );
685
686     dst_roi.create(src_roi.size(), src_roi.type());
687
688     CV_Assert( (src_roi.cols == dst_roi.cols) && (src_roi.rows == dst_roi.rows) );
689     CV_Assert( !(dst_roi.step & 0x3) );
690
691     if( !(crit.type & cv::TermCriteria::MAX_ITER) )
692         crit.maxCount = 5;
693     int maxIter = std::min(std::max(crit.maxCount, 1), 100);
694     float eps;
695     if( !(crit.type & cv::TermCriteria::EPS) )
696         eps = 1.f;
697     eps = (float)std::max(crit.epsilon, 0.0);
698
699     int tab[512];
700     for(int i = 0; i < 512; i++)
701         tab[i] = (i - 255) * (i - 255);
702     uchar *sptr = src_roi.data;
703     uchar *dptr = dst_roi.data;
704     int sstep = (int)src_roi.step;
705     int dstep = (int)dst_roi.step;
706     cv::Size size = src_roi.size();
707
708     for(int i = 0; i < size.height; i++, sptr += sstep - (size.width << 2),
709         dptr += dstep - (size.width << 2))
710     {
711         for(int j = 0; j < size.width; j++, sptr += 4, dptr += 4)
712         {
713             do_meanShift(j, i, sptr, dptr, sstep, size, sp, sr, maxIter, eps, tab);
714         }
715     }
716 }
717
718 PERFTEST(meanShiftFiltering)
719 {
720     int sp = 5, sr = 6;
721     Mat src, dst, ocl_dst;
722
723     ocl::oclMat d_src, d_dst;
724
725     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
726     {
727         SUBTEST << size << 'x' << size << "; 8UC3 vs 8UC4";
728
729         gen(src, size, size, CV_8UC4, Scalar::all(0), Scalar::all(256));
730
731         cv::TermCriteria crit(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 5, 1);
732
733         meanShiftFiltering_(src, dst, sp, sr, crit);
734
735         CPU_ON;
736         meanShiftFiltering_(src, dst, sp, sr, crit);
737         CPU_OFF;
738
739         d_src.upload(src);
740
741         WARMUP_ON;
742         ocl::meanShiftFiltering(d_src, d_dst, sp, sr, crit);
743         WARMUP_OFF;
744
745         GPU_ON;
746         ocl::meanShiftFiltering(d_src, d_dst, sp, sr);
747         GPU_OFF;
748
749         GPU_FULL_ON;
750         d_src.upload(src);
751         ocl::meanShiftFiltering(d_src, d_dst, sp, sr);
752         d_dst.download(ocl_dst);
753         GPU_FULL_OFF;
754
755         TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 0.0);
756     }
757 }
758
759 void meanShiftProc_(const Mat &src_roi, Mat &dst_roi, Mat &dstCoor_roi, int sp, int sr, cv::TermCriteria crit)
760 {
761     if (src_roi.empty())
762     {
763         CV_Error(CV_StsBadArg, "The input image is empty");
764     }
765     if (src_roi.depth() != CV_8U || src_roi.channels() != 4)
766     {
767         CV_Error(CV_StsUnsupportedFormat, "Only 8-bit, 4-channel images are supported");
768     }
769
770     dst_roi.create(src_roi.size(), src_roi.type());
771     dstCoor_roi.create(src_roi.size(), CV_16SC2);
772
773     CV_Assert((src_roi.cols == dst_roi.cols) && (src_roi.rows == dst_roi.rows) &&
774               (src_roi.cols == dstCoor_roi.cols) && (src_roi.rows == dstCoor_roi.rows));
775     CV_Assert(!(dstCoor_roi.step & 0x3));
776
777     if (!(crit.type & cv::TermCriteria::MAX_ITER))
778     {
779         crit.maxCount = 5;
780     }
781
782     int maxIter = std::min(std::max(crit.maxCount, 1), 100);
783     float eps;
784
785     if (!(crit.type & cv::TermCriteria::EPS))
786     {
787         eps = 1.f;
788     }
789
790     eps = (float)std::max(crit.epsilon, 0.0);
791
792     int tab[512];
793
794     for (int i = 0; i < 512; i++)
795     {
796         tab[i] = (i - 255) * (i - 255);
797     }
798
799     uchar *sptr = src_roi.data;
800     uchar *dptr = dst_roi.data;
801     short *dCoorptr = (short *)dstCoor_roi.data;
802     int sstep = (int)src_roi.step;
803     int dstep = (int)dst_roi.step;
804     int dCoorstep = (int)dstCoor_roi.step >> 1;
805     cv::Size size = src_roi.size();
806
807     for (int i = 0; i < size.height; i++, sptr += sstep - (size.width << 2),
808             dptr += dstep - (size.width << 2), dCoorptr += dCoorstep - (size.width << 1))
809     {
810         for (int j = 0; j < size.width; j++, sptr += 4, dptr += 4, dCoorptr += 2)
811         {
812             *((COOR *)dCoorptr) = do_meanShift(j, i, sptr, dptr, sstep, size, sp, sr, maxIter, eps, tab);
813         }
814     }
815
816 }
817 PERFTEST(meanShiftProc)
818 {
819     Mat src;
820     vector<Mat> dst(2), ocl_dst(2);
821     ocl::oclMat d_src, d_dst, d_dstCoor;
822
823     TermCriteria crit(TermCriteria::COUNT + TermCriteria::EPS, 5, 1);
824
825     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
826     {
827         SUBTEST << size << 'x' << size << "; 8UC4 and CV_16SC2 ";
828
829         gen(src, size, size, CV_8UC4, Scalar::all(0), Scalar::all(256));
830
831         meanShiftProc_(src, dst[0], dst[1], 5, 6, crit);
832
833         CPU_ON;
834         meanShiftProc_(src, dst[0], dst[1], 5, 6, crit);
835         CPU_OFF;
836
837         d_src.upload(src);
838
839         WARMUP_ON;
840         ocl::meanShiftProc(d_src, d_dst, d_dstCoor, 5, 6, crit);
841         WARMUP_OFF;
842
843         GPU_ON;
844         ocl::meanShiftProc(d_src, d_dst, d_dstCoor, 5, 6, crit);
845         GPU_OFF;
846
847         GPU_FULL_ON;
848         d_src.upload(src);
849         ocl::meanShiftProc(d_src, d_dst, d_dstCoor, 5, 6, crit);
850         d_dst.download(ocl_dst[0]);
851         d_dstCoor.download(ocl_dst[1]);
852         GPU_FULL_OFF;
853
854         vector<double> eps(2, 0.);
855         TestSystem::instance().ExpectMatsNear(dst, ocl_dst, eps);      
856     }
857 }
858
859 ///////////// remap////////////////////////
860 PERFTEST(remap)
861 {
862     Mat src, dst, xmap, ymap, ocl_dst;
863     ocl::oclMat d_src, d_dst, d_xmap, d_ymap;
864
865     int all_type[] = {CV_8UC1, CV_8UC4};
866     std::string type_name[] = {"CV_8UC1", "CV_8UC4"};
867
868     int interpolation = INTER_LINEAR;
869     int borderMode = BORDER_CONSTANT;
870
871     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
872     {
873         for (size_t t = 0; t < sizeof(all_type) / sizeof(int); t++)
874         {
875             SUBTEST << size << 'x' << size << "; src " << type_name[t] << "; map CV_32FC1";
876
877             gen(src, size, size, all_type[t], 0, 256);
878
879             xmap.create(size, size, CV_32FC1);
880             dst.create(size, size, CV_32FC1);
881             ymap.create(size, size, CV_32FC1);
882
883             for (int i = 0; i < size; ++i)
884             {
885                 float *xmap_row = xmap.ptr<float>(i);
886                 float *ymap_row = ymap.ptr<float>(i);
887
888                 for (int j = 0; j < size; ++j)
889                 {
890                     xmap_row[j] = (j - size * 0.5f) * 0.75f + size * 0.5f;
891                     ymap_row[j] = (i - size * 0.5f) * 0.75f + size * 0.5f;
892                 }
893             }
894
895             remap(src, dst, xmap, ymap, interpolation, borderMode);
896
897             CPU_ON;
898             remap(src, dst, xmap, ymap, interpolation, borderMode);
899             CPU_OFF;
900
901             d_src.upload(src);
902             d_dst.upload(dst);
903             d_xmap.upload(xmap);
904             d_ymap.upload(ymap);
905
906             WARMUP_ON;
907             ocl::remap(d_src, d_dst, d_xmap, d_ymap, interpolation, borderMode);
908             WARMUP_OFF;
909
910             GPU_ON;
911             ocl::remap(d_src, d_dst, d_xmap, d_ymap, interpolation, borderMode);
912             GPU_OFF;
913
914             GPU_FULL_ON;
915             d_src.upload(src);
916             ocl::remap(d_src, d_dst, d_xmap, d_ymap, interpolation, borderMode);
917             d_dst.download(ocl_dst);
918             GPU_FULL_OFF;
919
920             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 2.0);
921         }
922
923     }
924 }
925 ///////////// CLAHE ////////////////////////
926 PERFTEST(CLAHE)
927 {
928     Mat src, dst, ocl_dst;
929     cv::ocl::oclMat d_src, d_dst;
930     int all_type[] = {CV_8UC1};
931     std::string type_name[] = {"CV_8UC1"};
932
933     double clipLimit = 40.0;
934
935     cv::Ptr<cv::CLAHE>      clahe   = cv::createCLAHE(clipLimit);
936     cv::Ptr<cv::ocl::CLAHE> d_clahe = cv::ocl::createCLAHE(clipLimit);
937
938     for (int size = Min_Size; size <= Max_Size; size *= Multiple)
939     {
940         for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++)
941         {
942             SUBTEST << size << 'x' << size << "; " << type_name[j] ;
943
944             gen(src, size, size, all_type[j], 0, 256);
945
946             CPU_ON;
947             clahe->apply(src, dst);
948             CPU_OFF;
949
950             d_src.upload(src);
951
952             WARMUP_ON;
953             d_clahe->apply(d_src, d_dst);
954             WARMUP_OFF;
955
956             ocl_dst = d_dst;
957
958             TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0);
959
960             GPU_ON;
961             d_clahe->apply(d_src, d_dst);
962             GPU_OFF;
963
964             GPU_FULL_ON;
965             d_src.upload(src);
966             d_clahe->apply(d_src, d_dst);
967             d_dst.download(dst);
968             GPU_FULL_OFF;
969         }
970     }
971 }