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) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42 
43 #include "perf_precomp.hpp"
44 
45 namespace opencv_test { namespace {
46 
47 //////////////////////////////////////////////////////////////////////
48 // HoughLines
49 
50 namespace
51 {
52     struct Vec4iComparator
53     {
operator ()opencv_test::__anonf87657fc0111::__anonf87657fc0211::Vec4iComparator54         bool operator()(const cv::Vec4i& a, const cv::Vec4i b) const
55         {
56             if (a[0] != b[0]) return a[0] < b[0];
57             else if(a[1] != b[1]) return a[1] < b[1];
58             else if(a[2] != b[2]) return a[2] < b[2];
59             else return a[3] < b[3];
60         }
61     };
62     struct Vec3fComparator
63     {
operator ()opencv_test::__anonf87657fc0111::__anonf87657fc0211::Vec3fComparator64         bool operator()(const cv::Vec3f& a, const cv::Vec3f b) const
65         {
66             if(a[0] != b[0]) return a[0] < b[0];
67             else if(a[1] != b[1]) return a[1] < b[1];
68             else return a[2] < b[2];
69         }
70     };
71     struct Vec2fComparator
72     {
operator ()opencv_test::__anonf87657fc0111::__anonf87657fc0211::Vec2fComparator73         bool operator()(const cv::Vec2f& a, const cv::Vec2f b) const
74         {
75             if(a[0] != b[0]) return a[0] < b[0];
76             else return a[1] < b[1];
77         }
78     };
79 }
80 
PERF_TEST_P(Sz,HoughLines,CUDA_TYPICAL_MAT_SIZES)81 PERF_TEST_P(Sz, HoughLines,
82             CUDA_TYPICAL_MAT_SIZES)
83 {
84     declare.time(30.0);
85 
86     const cv::Size size = GetParam();
87 
88     const float rho = 1.0f;
89     const float theta = static_cast<float>(CV_PI / 180.0);
90     const int threshold = 300;
91 
92     cv::Mat src(size, CV_8UC1, cv::Scalar::all(0));
93     cv::line(src, cv::Point(0, 100), cv::Point(src.cols, 100), cv::Scalar::all(255), 1);
94     cv::line(src, cv::Point(0, 200), cv::Point(src.cols, 200), cv::Scalar::all(255), 1);
95     cv::line(src, cv::Point(0, 400), cv::Point(src.cols, 400), cv::Scalar::all(255), 1);
96     cv::line(src, cv::Point(100, 0), cv::Point(100, src.rows), cv::Scalar::all(255), 1);
97     cv::line(src, cv::Point(200, 0), cv::Point(200, src.rows), cv::Scalar::all(255), 1);
98     cv::line(src, cv::Point(400, 0), cv::Point(400, src.rows), cv::Scalar::all(255), 1);
99 
100     if (PERF_RUN_CUDA())
101     {
102         const cv::cuda::GpuMat d_src(src);
103         cv::cuda::GpuMat d_lines;
104 
105         cv::Ptr<cv::cuda::HoughLinesDetector> hough = cv::cuda::createHoughLinesDetector(rho, theta, threshold);
106 
107         TEST_CYCLE() hough->detect(d_src, d_lines);
108 
109         cv::Mat gpu_lines(d_lines.row(0));
110         cv::Vec2f* begin = gpu_lines.ptr<cv::Vec2f>(0);
111         cv::Vec2f* end = begin + gpu_lines.cols;
112         std::sort(begin, end, Vec2fComparator());
113         SANITY_CHECK(gpu_lines);
114     }
115     else
116     {
117         std::vector<cv::Vec2f> cpu_lines;
118 
119         TEST_CYCLE() cv::HoughLines(src, cpu_lines, rho, theta, threshold);
120 
121         SANITY_CHECK(cpu_lines);
122     }
123 }
124 
125 //////////////////////////////////////////////////////////////////////
126 // HoughLinesP
127 
128 DEF_PARAM_TEST_1(Image, std::string);
129 
130 PERF_TEST_P(Image, HoughLinesP,
131             testing::Values("cv/shared/pic5.png", "stitching/a1.png"))
132 {
133     declare.time(30.0);
134 
135     const std::string fileName = getDataPath(GetParam());
136 
137     const float rho = 1.0f;
138     const float theta = static_cast<float>(CV_PI / 180.0);
139     const int threshold = 100;
140     const int minLineLength = 50;
141     const int maxLineGap = 5;
142 
143     const cv::Mat image = cv::imread(fileName, cv::IMREAD_GRAYSCALE);
144     ASSERT_FALSE(image.empty());
145 
146     cv::Mat mask;
147     cv::Canny(image, mask, 50, 100);
148 
149     if (PERF_RUN_CUDA())
150     {
151         const cv::cuda::GpuMat d_mask(mask);
152         cv::cuda::GpuMat d_lines;
153 
154         cv::Ptr<cv::cuda::HoughSegmentDetector> hough = cv::cuda::createHoughSegmentDetector(rho, theta, minLineLength, maxLineGap);
155 
156         TEST_CYCLE() hough->detect(d_mask, d_lines);
157 
158         cv::Mat gpu_lines(d_lines);
159         cv::Vec4i* begin = gpu_lines.ptr<cv::Vec4i>();
160         cv::Vec4i* end = begin + gpu_lines.cols;
161         std::sort(begin, end, Vec4iComparator());
162         SANITY_CHECK(gpu_lines);
163     }
164     else
165     {
166         std::vector<cv::Vec4i> cpu_lines;
167 
168         TEST_CYCLE() cv::HoughLinesP(mask, cpu_lines, rho, theta, threshold, minLineLength, maxLineGap);
169 
170         SANITY_CHECK(cpu_lines);
171     }
172 }
173 
174 //////////////////////////////////////////////////////////////////////
175 // HoughCircles
176 
177 DEF_PARAM_TEST(Sz_Dp_MinDist, cv::Size, float, float);
178 
179 PERF_TEST_P(Sz_Dp_MinDist, HoughCircles,
180             Combine(CUDA_TYPICAL_MAT_SIZES,
181                     Values(1.0f, 2.0f, 4.0f),
182                     Values(1.0f)))
183 {
184     declare.time(30.0);
185 
186     const cv::Size size = GET_PARAM(0);
187     const float dp = GET_PARAM(1);
188     const float minDist = GET_PARAM(2);
189 
190     const int minRadius = 10;
191     const int maxRadius = 30;
192     const int cannyThreshold = 100;
193     const int votesThreshold = 15;
194 
195     cv::Mat src(size, CV_8UC1, cv::Scalar::all(0));
196     cv::circle(src, cv::Point(100, 100), 20, cv::Scalar::all(255), -1);
197     cv::circle(src, cv::Point(200, 200), 25, cv::Scalar::all(255), -1);
198     cv::circle(src, cv::Point(200, 100), 25, cv::Scalar::all(255), -1);
199 
200     if (PERF_RUN_CUDA())
201     {
202         const cv::cuda::GpuMat d_src(src);
203         cv::cuda::GpuMat d_circles;
204 
205         cv::Ptr<cv::cuda::HoughCirclesDetector> houghCircles = cv::cuda::createHoughCirclesDetector(dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius);
206 
207         TEST_CYCLE() houghCircles->detect(d_src, d_circles);
208 
209         cv::Mat gpu_circles(d_circles);
210         cv::Vec3f* begin = gpu_circles.ptr<cv::Vec3f>(0);
211         cv::Vec3f* end = begin + gpu_circles.cols;
212         std::sort(begin, end, Vec3fComparator());
213         SANITY_CHECK(gpu_circles);
214     }
215     else
216     {
217         std::vector<cv::Vec3f> cpu_circles;
218 
219         TEST_CYCLE() cv::HoughCircles(src, cpu_circles, cv::HOUGH_GRADIENT, dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius);
220 
221         SANITY_CHECK(cpu_circles);
222     }
223 }
224 
225 //////////////////////////////////////////////////////////////////////
226 // GeneralizedHough
227 
PERF_TEST_P(Sz,GeneralizedHoughBallard,CUDA_TYPICAL_MAT_SIZES)228 PERF_TEST_P(Sz, GeneralizedHoughBallard, CUDA_TYPICAL_MAT_SIZES)
229 {
230     declare.time(10);
231 
232     const cv::Size imageSize = GetParam();
233 
234     const cv::Mat templ = readImage("cv/shared/templ.png", cv::IMREAD_GRAYSCALE);
235     ASSERT_FALSE(templ.empty());
236 
237     cv::Mat image(imageSize, CV_8UC1, cv::Scalar::all(0));
238     templ.copyTo(image(cv::Rect(50, 50, templ.cols, templ.rows)));
239 
240     cv::Mat edges;
241     cv::Canny(image, edges, 50, 100);
242 
243     cv::Mat dx, dy;
244     cv::Sobel(image, dx, CV_32F, 1, 0);
245     cv::Sobel(image, dy, CV_32F, 0, 1);
246 
247     if (PERF_RUN_CUDA())
248     {
249         cv::Ptr<cv::GeneralizedHoughBallard> alg = cv::cuda::createGeneralizedHoughBallard();
250 
251         const cv::cuda::GpuMat d_edges(edges);
252         const cv::cuda::GpuMat d_dx(dx);
253         const cv::cuda::GpuMat d_dy(dy);
254         cv::cuda::GpuMat positions;
255 
256         alg->setTemplate(cv::cuda::GpuMat(templ));
257 
258         TEST_CYCLE() alg->detect(d_edges, d_dx, d_dy, positions);
259 
260         CUDA_SANITY_CHECK(positions);
261     }
262     else
263     {
264         cv::Ptr<cv::GeneralizedHoughBallard> alg = cv::createGeneralizedHoughBallard();
265 
266         cv::Mat positions;
267 
268         alg->setTemplate(templ);
269 
270         TEST_CYCLE() alg->detect(edges, dx, dy, positions);
271 
272         CPU_SANITY_CHECK(positions);
273     }
274 }
275 
PERF_TEST_P(Sz,DISABLED_GeneralizedHoughGuil,CUDA_TYPICAL_MAT_SIZES)276 PERF_TEST_P(Sz, DISABLED_GeneralizedHoughGuil, CUDA_TYPICAL_MAT_SIZES)
277 {
278     declare.time(10);
279 
280     const cv::Size imageSize = GetParam();
281 
282     const cv::Mat templ = readImage("cv/shared/templ.png", cv::IMREAD_GRAYSCALE);
283     ASSERT_FALSE(templ.empty());
284 
285     cv::Mat image(imageSize, CV_8UC1, cv::Scalar::all(0));
286     templ.copyTo(image(cv::Rect(50, 50, templ.cols, templ.rows)));
287 
288     cv::RNG rng(123456789);
289     const int objCount = rng.uniform(5, 15);
290     for (int i = 0; i < objCount; ++i)
291     {
292         double scale = rng.uniform(0.7, 1.3);
293         bool rotate = 1 == rng.uniform(0, 2);
294 
295         cv::Mat obj;
296         cv::resize(templ, obj, cv::Size(), scale, scale);
297         if (rotate)
298             obj = obj.t();
299 
300         cv::Point pos;
301 
302         pos.x = rng.uniform(0, image.cols - obj.cols);
303         pos.y = rng.uniform(0, image.rows - obj.rows);
304 
305         cv::Mat roi = image(cv::Rect(pos, obj.size()));
306         cv::add(roi, obj, roi);
307     }
308 
309     cv::Mat edges;
310     cv::Canny(image, edges, 50, 100);
311 
312     cv::Mat dx, dy;
313     cv::Sobel(image, dx, CV_32F, 1, 0);
314     cv::Sobel(image, dy, CV_32F, 0, 1);
315 
316     if (PERF_RUN_CUDA())
317     {
318         cv::Ptr<cv::GeneralizedHoughGuil> alg = cv::cuda::createGeneralizedHoughGuil();
319         alg->setMaxAngle(90.0);
320         alg->setAngleStep(2.0);
321 
322         const cv::cuda::GpuMat d_edges(edges);
323         const cv::cuda::GpuMat d_dx(dx);
324         const cv::cuda::GpuMat d_dy(dy);
325         cv::cuda::GpuMat positions;
326 
327         alg->setTemplate(cv::cuda::GpuMat(templ));
328 
329         TEST_CYCLE() alg->detect(d_edges, d_dx, d_dy, positions);
330     }
331     else
332     {
333         cv::Ptr<cv::GeneralizedHoughGuil> alg = cv::createGeneralizedHoughGuil();
334         alg->setMaxAngle(90.0);
335         alg->setAngleStep(2.0);
336 
337         cv::Mat positions;
338 
339         alg->setTemplate(templ);
340 
341         TEST_CYCLE() alg->detect(edges, dx, dy, positions);
342     }
343 
344     // The algorithm is not stable yet.
345     SANITY_CHECK_NOTHING();
346 }
347 
348 }} // namespace
349