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 using namespace std; 46 using namespace testing; 47 using namespace perf; 48 49 ////////////////////////////////////////////////////////////////////// 50 // HoughLines 51 52 namespace 53 { 54 struct Vec4iComparator 55 { 56 bool operator()(const cv::Vec4i& a, const cv::Vec4i b) const 57 { 58 if (a[0] != b[0]) return a[0] < b[0]; 59 else if(a[1] != b[1]) return a[1] < b[1]; 60 else if(a[2] != b[2]) return a[2] < b[2]; 61 else return a[3] < b[3]; 62 } 63 }; 64 struct Vec3fComparator 65 { 66 bool operator()(const cv::Vec3f& a, const cv::Vec3f b) const 67 { 68 if(a[0] != b[0]) return a[0] < b[0]; 69 else if(a[1] != b[1]) return a[1] < b[1]; 70 else return a[2] < b[2]; 71 } 72 }; 73 struct Vec2fComparator 74 { 75 bool operator()(const cv::Vec2f& a, const cv::Vec2f b) const 76 { 77 if(a[0] != b[0]) return a[0] < b[0]; 78 else return a[1] < b[1]; 79 } 80 }; 81 } 82 83 PERF_TEST_P(Sz, HoughLines, 84 CUDA_TYPICAL_MAT_SIZES) 85 { 86 declare.time(30.0); 87 88 const cv::Size size = GetParam(); 89 90 const float rho = 1.0f; 91 const float theta = static_cast<float>(CV_PI / 180.0); 92 const int threshold = 300; 93 94 cv::Mat src(size, CV_8UC1, cv::Scalar::all(0)); 95 cv::line(src, cv::Point(0, 100), cv::Point(src.cols, 100), cv::Scalar::all(255), 1); 96 cv::line(src, cv::Point(0, 200), cv::Point(src.cols, 200), cv::Scalar::all(255), 1); 97 cv::line(src, cv::Point(0, 400), cv::Point(src.cols, 400), cv::Scalar::all(255), 1); 98 cv::line(src, cv::Point(100, 0), cv::Point(100, src.rows), cv::Scalar::all(255), 1); 99 cv::line(src, cv::Point(200, 0), cv::Point(200, src.rows), cv::Scalar::all(255), 1); 100 cv::line(src, cv::Point(400, 0), cv::Point(400, src.rows), cv::Scalar::all(255), 1); 101 102 if (PERF_RUN_CUDA()) 103 { 104 const cv::cuda::GpuMat d_src(src); 105 cv::cuda::GpuMat d_lines; 106 107 cv::Ptr<cv::cuda::HoughLinesDetector> hough = cv::cuda::createHoughLinesDetector(rho, theta, threshold); 108 109 TEST_CYCLE() hough->detect(d_src, d_lines); 110 111 cv::Mat gpu_lines(d_lines.row(0)); 112 cv::Vec2f* begin = gpu_lines.ptr<cv::Vec2f>(0); 113 cv::Vec2f* end = begin + gpu_lines.cols; 114 std::sort(begin, end, Vec2fComparator()); 115 SANITY_CHECK(gpu_lines); 116 } 117 else 118 { 119 std::vector<cv::Vec2f> cpu_lines; 120 121 TEST_CYCLE() cv::HoughLines(src, cpu_lines, rho, theta, threshold); 122 123 SANITY_CHECK(cpu_lines); 124 } 125 } 126 127 ////////////////////////////////////////////////////////////////////// 128 // HoughLinesP 129 130 DEF_PARAM_TEST_1(Image, std::string); 131 132 PERF_TEST_P(Image, HoughLinesP, 133 testing::Values("cv/shared/pic5.png", "stitching/a1.png")) 134 { 135 declare.time(30.0); 136 137 const std::string fileName = getDataPath(GetParam()); 138 139 const float rho = 1.0f; 140 const float theta = static_cast<float>(CV_PI / 180.0); 141 const int threshold = 100; 142 const int minLineLength = 50; 143 const int maxLineGap = 5; 144 145 const cv::Mat image = cv::imread(fileName, cv::IMREAD_GRAYSCALE); 146 ASSERT_FALSE(image.empty()); 147 148 cv::Mat mask; 149 cv::Canny(image, mask, 50, 100); 150 151 if (PERF_RUN_CUDA()) 152 { 153 const cv::cuda::GpuMat d_mask(mask); 154 cv::cuda::GpuMat d_lines; 155 156 cv::Ptr<cv::cuda::HoughSegmentDetector> hough = cv::cuda::createHoughSegmentDetector(rho, theta, minLineLength, maxLineGap); 157 158 TEST_CYCLE() hough->detect(d_mask, d_lines); 159 160 cv::Mat gpu_lines(d_lines); 161 cv::Vec4i* begin = gpu_lines.ptr<cv::Vec4i>(); 162 cv::Vec4i* end = begin + gpu_lines.cols; 163 std::sort(begin, end, Vec4iComparator()); 164 SANITY_CHECK(gpu_lines); 165 } 166 else 167 { 168 std::vector<cv::Vec4i> cpu_lines; 169 170 TEST_CYCLE() cv::HoughLinesP(mask, cpu_lines, rho, theta, threshold, minLineLength, maxLineGap); 171 172 SANITY_CHECK(cpu_lines); 173 } 174 } 175 176 ////////////////////////////////////////////////////////////////////// 177 // HoughCircles 178 179 DEF_PARAM_TEST(Sz_Dp_MinDist, cv::Size, float, float); 180 181 PERF_TEST_P(Sz_Dp_MinDist, HoughCircles, 182 Combine(CUDA_TYPICAL_MAT_SIZES, 183 Values(1.0f, 2.0f, 4.0f), 184 Values(1.0f))) 185 { 186 declare.time(30.0); 187 188 const cv::Size size = GET_PARAM(0); 189 const float dp = GET_PARAM(1); 190 const float minDist = GET_PARAM(2); 191 192 const int minRadius = 10; 193 const int maxRadius = 30; 194 const int cannyThreshold = 100; 195 const int votesThreshold = 15; 196 197 cv::Mat src(size, CV_8UC1, cv::Scalar::all(0)); 198 cv::circle(src, cv::Point(100, 100), 20, cv::Scalar::all(255), -1); 199 cv::circle(src, cv::Point(200, 200), 25, cv::Scalar::all(255), -1); 200 cv::circle(src, cv::Point(200, 100), 25, cv::Scalar::all(255), -1); 201 202 if (PERF_RUN_CUDA()) 203 { 204 const cv::cuda::GpuMat d_src(src); 205 cv::cuda::GpuMat d_circles; 206 207 cv::Ptr<cv::cuda::HoughCirclesDetector> houghCircles = cv::cuda::createHoughCirclesDetector(dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius); 208 209 TEST_CYCLE() houghCircles->detect(d_src, d_circles); 210 211 cv::Mat gpu_circles(d_circles); 212 cv::Vec3f* begin = gpu_circles.ptr<cv::Vec3f>(0); 213 cv::Vec3f* end = begin + gpu_circles.cols; 214 std::sort(begin, end, Vec3fComparator()); 215 SANITY_CHECK(gpu_circles); 216 } 217 else 218 { 219 std::vector<cv::Vec3f> cpu_circles; 220 221 TEST_CYCLE() cv::HoughCircles(src, cpu_circles, cv::HOUGH_GRADIENT, dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius); 222 223 SANITY_CHECK(cpu_circles); 224 } 225 } 226 227 ////////////////////////////////////////////////////////////////////// 228 // GeneralizedHough 229 230 PERF_TEST_P(Sz, GeneralizedHoughBallard, CUDA_TYPICAL_MAT_SIZES) 231 { 232 declare.time(10); 233 234 const cv::Size imageSize = GetParam(); 235 236 const cv::Mat templ = readImage("cv/shared/templ.png", cv::IMREAD_GRAYSCALE); 237 ASSERT_FALSE(templ.empty()); 238 239 cv::Mat image(imageSize, CV_8UC1, cv::Scalar::all(0)); 240 templ.copyTo(image(cv::Rect(50, 50, templ.cols, templ.rows))); 241 242 cv::Mat edges; 243 cv::Canny(image, edges, 50, 100); 244 245 cv::Mat dx, dy; 246 cv::Sobel(image, dx, CV_32F, 1, 0); 247 cv::Sobel(image, dy, CV_32F, 0, 1); 248 249 if (PERF_RUN_CUDA()) 250 { 251 cv::Ptr<cv::GeneralizedHoughBallard> alg = cv::cuda::createGeneralizedHoughBallard(); 252 253 const cv::cuda::GpuMat d_edges(edges); 254 const cv::cuda::GpuMat d_dx(dx); 255 const cv::cuda::GpuMat d_dy(dy); 256 cv::cuda::GpuMat positions; 257 258 alg->setTemplate(cv::cuda::GpuMat(templ)); 259 260 TEST_CYCLE() alg->detect(d_edges, d_dx, d_dy, positions); 261 262 CUDA_SANITY_CHECK(positions); 263 } 264 else 265 { 266 cv::Ptr<cv::GeneralizedHoughBallard> alg = cv::createGeneralizedHoughBallard(); 267 268 cv::Mat positions; 269 270 alg->setTemplate(templ); 271 272 TEST_CYCLE() alg->detect(edges, dx, dy, positions); 273 274 CPU_SANITY_CHECK(positions); 275 } 276 } 277 278 PERF_TEST_P(Sz, DISABLED_GeneralizedHoughGuil, CUDA_TYPICAL_MAT_SIZES) 279 { 280 declare.time(10); 281 282 const cv::Size imageSize = GetParam(); 283 284 const cv::Mat templ = readImage("cv/shared/templ.png", cv::IMREAD_GRAYSCALE); 285 ASSERT_FALSE(templ.empty()); 286 287 cv::Mat image(imageSize, CV_8UC1, cv::Scalar::all(0)); 288 templ.copyTo(image(cv::Rect(50, 50, templ.cols, templ.rows))); 289 290 cv::RNG rng(123456789); 291 const int objCount = rng.uniform(5, 15); 292 for (int i = 0; i < objCount; ++i) 293 { 294 double scale = rng.uniform(0.7, 1.3); 295 bool rotate = 1 == rng.uniform(0, 2); 296 297 cv::Mat obj; 298 cv::resize(templ, obj, cv::Size(), scale, scale); 299 if (rotate) 300 obj = obj.t(); 301 302 cv::Point pos; 303 304 pos.x = rng.uniform(0, image.cols - obj.cols); 305 pos.y = rng.uniform(0, image.rows - obj.rows); 306 307 cv::Mat roi = image(cv::Rect(pos, obj.size())); 308 cv::add(roi, obj, roi); 309 } 310 311 cv::Mat edges; 312 cv::Canny(image, edges, 50, 100); 313 314 cv::Mat dx, dy; 315 cv::Sobel(image, dx, CV_32F, 1, 0); 316 cv::Sobel(image, dy, CV_32F, 0, 1); 317 318 if (PERF_RUN_CUDA()) 319 { 320 cv::Ptr<cv::GeneralizedHoughGuil> alg = cv::cuda::createGeneralizedHoughGuil(); 321 alg->setMaxAngle(90.0); 322 alg->setAngleStep(2.0); 323 324 const cv::cuda::GpuMat d_edges(edges); 325 const cv::cuda::GpuMat d_dx(dx); 326 const cv::cuda::GpuMat d_dy(dy); 327 cv::cuda::GpuMat positions; 328 329 alg->setTemplate(cv::cuda::GpuMat(templ)); 330 331 TEST_CYCLE() alg->detect(d_edges, d_dx, d_dy, positions); 332 } 333 else 334 { 335 cv::Ptr<cv::GeneralizedHoughGuil> alg = cv::createGeneralizedHoughGuil(); 336 alg->setMaxAngle(90.0); 337 alg->setAngleStep(2.0); 338 339 cv::Mat positions; 340 341 alg->setTemplate(templ); 342 343 TEST_CYCLE() alg->detect(edges, dx, dy, positions); 344 } 345 346 // The algorithm is not stable yet. 347 SANITY_CHECK_NOTHING(); 348 } 349