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, Institute Of Software Chinese Academy Of Science, all rights reserved.
14// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
15// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
16// Copyright (C) 2014, Itseez, Inc., all rights reserved.
17// Third party copyrights are property of their respective owners.
18//
19// @Authors
20//    Niko Li, newlife20080214@gmail.com
21//    Jia Haipeng, jiahaipeng95@gmail.com
22//    Shengen Yan, yanshengen@gmail.com
23//    Jiang Liyuan, lyuan001.good@163.com
24//    Rock Li, Rock.Li@amd.com
25//    Wu Zailong, bullet@yeah.net
26//    Xu Pang, pangxu010@163.com
27//    Sen Liu, swjtuls1987@126.com
28//
29// Redistribution and use in source and binary forms, with or without modification,
30// are permitted provided that the following conditions are met:
31//
32//   * Redistribution's of source code must retain the above copyright notice,
33//     this list of conditions and the following disclaimer.
34//
35//   * Redistribution's in binary form must reproduce the above copyright notice,
36//     this list of conditions and the following disclaimer in the documentation
37//     and/or other materials provided with the distribution.
38//
39//   * The name of the copyright holders may not be used to endorse or promote products
40//     derived from this software without specific prior written permission.
41//
42// This software is provided by the copyright holders and contributors "as is" and
43// any express or implied warranties, including, but not limited to, the implied
44// warranties of merchantability and fitness for a particular purpose are disclaimed.
45// In no event shall the Intel Corporation or contributors be liable for any direct,
46// indirect, incidental, special, exemplary, or consequential damages
47// (including, but not limited to, procurement of substitute goods or services;
48// loss of use, data, or profits; or business interruption) however caused
49// and on any theory of liability, whether in contract, strict liability,
50// or tort (including negligence or otherwise) arising in any way out of
51// the use of this software, even if advised of the possibility of such damage.
52//
53//M*/
54
55#include "../test_precomp.hpp"
56#include "cvconfig.h"
57#include "opencv2/ts/ocl_test.hpp"
58
59#ifdef HAVE_OPENCL
60
61namespace cvtest {
62namespace ocl {
63
64///////////////////////////////////////////////////////////////////////////////
65
66PARAM_TEST_CASE(CalcBackProject, MatDepth, int, bool)
67{
68    int depth, N;
69    bool useRoi;
70
71    std::vector<float> ranges;
72    std::vector<int> channels;
73    double scale;
74
75    std::vector<Mat> images;
76    std::vector<Mat> images_roi;
77    std::vector<UMat> uimages;
78    std::vector<UMat> uimages_roi;
79
80    TEST_DECLARE_INPUT_PARAMETER(hist);
81    TEST_DECLARE_OUTPUT_PARAMETER(dst);
82
83    virtual void SetUp()
84    {
85        depth = GET_PARAM(0);
86        N = GET_PARAM(1);
87        useRoi = GET_PARAM(2);
88
89        ASSERT_GE(2, N);
90
91        images.resize(N);
92        images_roi.resize(N);
93        uimages.resize(N);
94        uimages_roi.resize(N);
95    }
96
97    virtual void random_roi()
98    {
99        Size roiSize = randomSize(1, MAX_VALUE);
100
101        int totalChannels = 0;
102
103        ranges.clear();
104        channels.clear();
105
106        for (int i = 0; i < N; ++i)
107        {
108            Border srcBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
109            int cn = randomInt(1, 5);
110            randomSubMat(images[i], images_roi[i], roiSize, srcBorder, CV_MAKE_TYPE(depth, cn), 0, 125);
111
112            ranges.push_back(10);
113            ranges.push_back(100);
114
115            channels.push_back(randomInt(0, cn) + totalChannels);
116            totalChannels += cn;
117        }
118
119        Mat tmpHist;
120        {
121            std::vector<int> hist_size(N);
122            for (int i = 0 ; i < N; ++i)
123                hist_size[i] = randomInt(10, 50);
124
125            cv::calcHist(images_roi, channels, noArray(), tmpHist, hist_size, ranges);
126            ASSERT_EQ(CV_32FC1, tmpHist.type());
127        }
128
129        Border histBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
130        randomSubMat(hist, hist_roi, tmpHist.size(), histBorder, tmpHist.type(), 0, MAX_VALUE);
131        tmpHist.copyTo(hist_roi);
132
133        Border dstBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
134        randomSubMat(dst, dst_roi, roiSize, dstBorder, CV_MAKE_TYPE(depth, 1), 5, 16);
135
136        for (int i = 0; i < N; ++i)
137        {
138            images[i].copyTo(uimages[i]);
139
140            Size _wholeSize;
141            Point ofs;
142            images_roi[i].locateROI(_wholeSize, ofs);
143
144            uimages_roi[i] = uimages[i](Rect(ofs.x, ofs.y, images_roi[i].cols, images_roi[i].rows));
145        }
146
147        UMAT_UPLOAD_INPUT_PARAMETER(hist);
148        UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
149
150        scale = randomDouble(0.1, 1);
151    }
152
153    void test_by_pict()
154    {
155        Mat frame1 = readImage("optflow/RubberWhale1.png", IMREAD_GRAYSCALE);
156
157        UMat usrc;
158        frame1.copyTo(usrc);
159        int histSize = randomInt(3, 29);
160        float hue_range[] = { 0, 180 };
161        const float* ranges1 = { hue_range };
162        Mat hist1;
163
164        //compute histogram
165        calcHist(&frame1, 1, 0, Mat(), hist1, 1, &histSize, &ranges1, true, false);
166        normalize(hist1, hist1, 0, 255, NORM_MINMAX, -1, Mat());
167
168        Mat dst1;
169        UMat udst1, src, uhist1;
170        hist1.copyTo(uhist1);
171        std::vector<UMat> uims;
172        uims.push_back(usrc);
173        std::vector<float> urngs;
174        urngs.push_back(0);
175        urngs.push_back(180);
176        std::vector<int> chs;
177        chs.push_back(0);
178
179        OCL_OFF(calcBackProject(&frame1, 1, 0, hist1, dst1, &ranges1, 1, true));
180        OCL_ON(calcBackProject(uims, chs, uhist1, udst1, urngs, 1.0));
181
182        if (cv::ocl::useOpenCL() && cv::ocl::Device::getDefault().isAMD())
183        {
184            Size dstSize = dst1.size();
185            int nDiffs = (int)(0.03f*dstSize.height*dstSize.width);
186
187            //check if the dst mats are the same except 3% difference
188            EXPECT_MAT_N_DIFF(dst1, udst1, nDiffs);
189        }
190        else
191        {
192            EXPECT_MAT_NEAR(dst1, udst1, 0.0);
193        }
194    }
195};
196
197//////////////////////////////// CalcBackProject //////////////////////////////////////////////
198
199OCL_TEST_P(CalcBackProject, Mat)
200{
201    for (int j = 0; j < test_loop_times; j++)
202    {
203        random_roi();
204
205        OCL_OFF(cv::calcBackProject(images_roi, channels, hist_roi, dst_roi, ranges, scale));
206        OCL_ON(cv::calcBackProject(uimages_roi, channels, uhist_roi, udst_roi, ranges, scale));
207
208        Size dstSize = dst_roi.size();
209        int nDiffs = std::max((int)(0.07f*dstSize.area()), 1);
210
211        //check if the dst mats are the same except 7% difference
212        EXPECT_MAT_N_DIFF(dst_roi, udst_roi, nDiffs);
213    }
214}
215
216OCL_TEST_P(CalcBackProject, Mat_RealImage)
217{
218    //check on given image
219    test_by_pict();
220}
221
222//////////////////////////////// CalcHist //////////////////////////////////////////////
223
224PARAM_TEST_CASE(CalcHist, bool)
225{
226    bool useRoi;
227
228    TEST_DECLARE_INPUT_PARAMETER(src);
229    TEST_DECLARE_OUTPUT_PARAMETER(hist);
230
231    virtual void SetUp()
232    {
233        useRoi = GET_PARAM(0);
234    }
235
236    virtual void random_roi()
237    {
238        Size roiSize = randomSize(1, MAX_VALUE);
239
240        Border srcBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
241        randomSubMat(src, src_roi, roiSize, srcBorder, CV_8UC1, 0, 256);
242
243        Border histBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
244        randomSubMat(hist, hist_roi, Size(1, 256), histBorder, CV_32SC1, 0, MAX_VALUE);
245
246        UMAT_UPLOAD_INPUT_PARAMETER(src);
247        UMAT_UPLOAD_OUTPUT_PARAMETER(hist);
248    }
249};
250
251OCL_TEST_P(CalcHist, Mat)
252{
253    const std::vector<int> channels(1, 0);
254    std::vector<float> ranges(2);
255    std::vector<int> histSize(1, 256);
256    ranges[0] = 0;
257    ranges[1] = 256;
258
259    for (int j = 0; j < test_loop_times; j++)
260    {
261        random_roi();
262
263        OCL_OFF(cv::calcHist(std::vector<Mat>(1, src_roi), channels, noArray(), hist_roi, histSize, ranges, false));
264        OCL_ON(cv::calcHist(std::vector<UMat>(1, usrc_roi), channels, noArray(), uhist_roi, histSize, ranges, false));
265
266        OCL_EXPECT_MATS_NEAR(hist, 0.0);
267    }
268}
269
270/////////////////////////////////////////////////////////////////////////////////////
271
272OCL_INSTANTIATE_TEST_CASE_P(Imgproc, CalcBackProject, Combine(Values((MatDepth)CV_8U), Values(1, 2), Bool()));
273OCL_INSTANTIATE_TEST_CASE_P(Imgproc, CalcHist, Values(true, false));
274
275} } // namespace cvtest::ocl
276
277#endif // HAVE_OPENCL
278