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 "test_precomp.hpp" 44 45#ifdef HAVE_CUDA 46 47using namespace cvtest; 48 49//////////////////////////////////////////////////////////////////////////////// 50// Norm 51 52PARAM_TEST_CASE(Norm, cv::cuda::DeviceInfo, cv::Size, MatDepth, NormCode, UseRoi) 53{ 54 cv::cuda::DeviceInfo devInfo; 55 cv::Size size; 56 int depth; 57 int normCode; 58 bool useRoi; 59 60 virtual void SetUp() 61 { 62 devInfo = GET_PARAM(0); 63 size = GET_PARAM(1); 64 depth = GET_PARAM(2); 65 normCode = GET_PARAM(3); 66 useRoi = GET_PARAM(4); 67 68 cv::cuda::setDevice(devInfo.deviceID()); 69 } 70}; 71 72CUDA_TEST_P(Norm, Accuracy) 73{ 74 cv::Mat src = randomMat(size, depth); 75 cv::Mat mask = randomMat(size, CV_8UC1, 0, 2); 76 77 double val = cv::cuda::norm(loadMat(src, useRoi), normCode, loadMat(mask, useRoi)); 78 79 double val_gold = cv::norm(src, normCode, mask); 80 81 EXPECT_NEAR(val_gold, val, depth < CV_32F ? 0.0 : 1.0); 82} 83 84CUDA_TEST_P(Norm, Async) 85{ 86 cv::Mat src = randomMat(size, depth); 87 cv::Mat mask = randomMat(size, CV_8UC1, 0, 2); 88 89 cv::cuda::Stream stream; 90 91 cv::cuda::HostMem dst; 92 cv::cuda::calcNorm(loadMat(src, useRoi), dst, normCode, loadMat(mask, useRoi), stream); 93 94 stream.waitForCompletion(); 95 96 double val; 97 dst.createMatHeader().convertTo(cv::Mat(1, 1, CV_64FC1, &val), CV_64F); 98 99 double val_gold = cv::norm(src, normCode, mask); 100 101 EXPECT_NEAR(val_gold, val, depth < CV_32F ? 0.0 : 1.0); 102} 103 104INSTANTIATE_TEST_CASE_P(CUDA_Arithm, Norm, testing::Combine( 105 ALL_DEVICES, 106 DIFFERENT_SIZES, 107 testing::Values(MatDepth(CV_8U), 108 MatDepth(CV_8S), 109 MatDepth(CV_16U), 110 MatDepth(CV_16S), 111 MatDepth(CV_32S), 112 MatDepth(CV_32F)), 113 testing::Values(NormCode(cv::NORM_L1), NormCode(cv::NORM_L2), NormCode(cv::NORM_INF)), 114 WHOLE_SUBMAT)); 115 116//////////////////////////////////////////////////////////////////////////////// 117// normDiff 118 119PARAM_TEST_CASE(NormDiff, cv::cuda::DeviceInfo, cv::Size, NormCode, UseRoi) 120{ 121 cv::cuda::DeviceInfo devInfo; 122 cv::Size size; 123 int normCode; 124 bool useRoi; 125 126 virtual void SetUp() 127 { 128 devInfo = GET_PARAM(0); 129 size = GET_PARAM(1); 130 normCode = GET_PARAM(2); 131 useRoi = GET_PARAM(3); 132 133 cv::cuda::setDevice(devInfo.deviceID()); 134 } 135}; 136 137CUDA_TEST_P(NormDiff, Accuracy) 138{ 139 cv::Mat src1 = randomMat(size, CV_8UC1); 140 cv::Mat src2 = randomMat(size, CV_8UC1); 141 142 double val = cv::cuda::norm(loadMat(src1, useRoi), loadMat(src2, useRoi), normCode); 143 144 double val_gold = cv::norm(src1, src2, normCode); 145 146 EXPECT_NEAR(val_gold, val, 0.0); 147} 148 149CUDA_TEST_P(NormDiff, Async) 150{ 151 cv::Mat src1 = randomMat(size, CV_8UC1); 152 cv::Mat src2 = randomMat(size, CV_8UC1); 153 154 cv::cuda::Stream stream; 155 156 cv::cuda::HostMem dst; 157 cv::cuda::calcNormDiff(loadMat(src1, useRoi), loadMat(src2, useRoi), dst, normCode, stream); 158 159 stream.waitForCompletion(); 160 161 double val; 162 const cv::Mat val_mat(1, 1, CV_64FC1, &val); 163 dst.createMatHeader().convertTo(val_mat, CV_64F); 164 165 double val_gold = cv::norm(src1, src2, normCode); 166 167 EXPECT_NEAR(val_gold, val, 0.0); 168} 169 170INSTANTIATE_TEST_CASE_P(CUDA_Arithm, NormDiff, testing::Combine( 171 ALL_DEVICES, 172 DIFFERENT_SIZES, 173 testing::Values(NormCode(cv::NORM_L1), NormCode(cv::NORM_L2), NormCode(cv::NORM_INF)), 174 WHOLE_SUBMAT)); 175 176////////////////////////////////////////////////////////////////////////////// 177// Sum 178 179namespace 180{ 181 template <typename T> 182 cv::Scalar absSumImpl(const cv::Mat& src) 183 { 184 const int cn = src.channels(); 185 186 cv::Scalar sum = cv::Scalar::all(0); 187 188 for (int y = 0; y < src.rows; ++y) 189 { 190 for (int x = 0; x < src.cols; ++x) 191 { 192 for (int c = 0; c < cn; ++c) 193 sum[c] += std::abs(src.at<T>(y, x * cn + c)); 194 } 195 } 196 197 return sum; 198 } 199 200 cv::Scalar absSumGold(const cv::Mat& src) 201 { 202 typedef cv::Scalar (*func_t)(const cv::Mat& src); 203 204 static const func_t funcs[] = 205 { 206 absSumImpl<uchar>, 207 absSumImpl<schar>, 208 absSumImpl<ushort>, 209 absSumImpl<short>, 210 absSumImpl<int>, 211 absSumImpl<float>, 212 absSumImpl<double> 213 }; 214 215 return funcs[src.depth()](src); 216 } 217 218 template <typename T> 219 cv::Scalar sqrSumImpl(const cv::Mat& src) 220 { 221 const int cn = src.channels(); 222 223 cv::Scalar sum = cv::Scalar::all(0); 224 225 for (int y = 0; y < src.rows; ++y) 226 { 227 for (int x = 0; x < src.cols; ++x) 228 { 229 for (int c = 0; c < cn; ++c) 230 { 231 const T val = src.at<T>(y, x * cn + c); 232 sum[c] += val * val; 233 } 234 } 235 } 236 237 return sum; 238 } 239 240 cv::Scalar sqrSumGold(const cv::Mat& src) 241 { 242 typedef cv::Scalar (*func_t)(const cv::Mat& src); 243 244 static const func_t funcs[] = 245 { 246 sqrSumImpl<uchar>, 247 sqrSumImpl<schar>, 248 sqrSumImpl<ushort>, 249 sqrSumImpl<short>, 250 sqrSumImpl<int>, 251 sqrSumImpl<float>, 252 sqrSumImpl<double> 253 }; 254 255 return funcs[src.depth()](src); 256 } 257} 258 259PARAM_TEST_CASE(Sum, cv::cuda::DeviceInfo, cv::Size, MatType, UseRoi) 260{ 261 cv::cuda::DeviceInfo devInfo; 262 cv::Size size; 263 int type; 264 bool useRoi; 265 266 cv::Mat src; 267 268 virtual void SetUp() 269 { 270 devInfo = GET_PARAM(0); 271 size = GET_PARAM(1); 272 type = GET_PARAM(2); 273 useRoi = GET_PARAM(3); 274 275 cv::cuda::setDevice(devInfo.deviceID()); 276 277 src = randomMat(size, type, -128.0, 128.0); 278 } 279}; 280 281CUDA_TEST_P(Sum, Simple) 282{ 283 cv::Scalar val = cv::cuda::sum(loadMat(src, useRoi)); 284 285 cv::Scalar val_gold = cv::sum(src); 286 287 EXPECT_SCALAR_NEAR(val_gold, val, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.5); 288} 289 290CUDA_TEST_P(Sum, Simple_Async) 291{ 292 cv::cuda::Stream stream; 293 294 cv::cuda::HostMem dst; 295 cv::cuda::calcSum(loadMat(src, useRoi), dst, cv::noArray(), stream); 296 297 stream.waitForCompletion(); 298 299 cv::Scalar val; 300 cv::Mat val_mat(dst.size(), CV_64FC(dst.channels()), val.val); 301 dst.createMatHeader().convertTo(val_mat, CV_64F); 302 303 cv::Scalar val_gold = cv::sum(src); 304 305 EXPECT_SCALAR_NEAR(val_gold, val, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.5); 306} 307 308CUDA_TEST_P(Sum, Abs) 309{ 310 cv::Scalar val = cv::cuda::absSum(loadMat(src, useRoi)); 311 312 cv::Scalar val_gold = absSumGold(src); 313 314 EXPECT_SCALAR_NEAR(val_gold, val, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.5); 315} 316 317CUDA_TEST_P(Sum, Abs_Async) 318{ 319 cv::cuda::Stream stream; 320 321 cv::cuda::HostMem dst; 322 cv::cuda::calcAbsSum(loadMat(src, useRoi), dst, cv::noArray(), stream); 323 324 stream.waitForCompletion(); 325 326 cv::Scalar val; 327 cv::Mat val_mat(dst.size(), CV_64FC(dst.channels()), val.val); 328 dst.createMatHeader().convertTo(val_mat, CV_64F); 329 330 cv::Scalar val_gold = absSumGold(src); 331 332 EXPECT_SCALAR_NEAR(val_gold, val, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.5); 333} 334 335CUDA_TEST_P(Sum, Sqr) 336{ 337 cv::Scalar val = cv::cuda::sqrSum(loadMat(src, useRoi)); 338 339 cv::Scalar val_gold = sqrSumGold(src); 340 341 EXPECT_SCALAR_NEAR(val_gold, val, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.5); 342} 343 344CUDA_TEST_P(Sum, Sqr_Async) 345{ 346 cv::cuda::Stream stream; 347 348 cv::cuda::HostMem dst; 349 cv::cuda::calcSqrSum(loadMat(src, useRoi), dst, cv::noArray(), stream); 350 351 stream.waitForCompletion(); 352 353 cv::Scalar val; 354 cv::Mat val_mat(dst.size(), CV_64FC(dst.channels()), val.val); 355 dst.createMatHeader().convertTo(val_mat, CV_64F); 356 357 cv::Scalar val_gold = sqrSumGold(src); 358 359 EXPECT_SCALAR_NEAR(val_gold, val, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.5); 360} 361 362INSTANTIATE_TEST_CASE_P(CUDA_Arithm, Sum, testing::Combine( 363 ALL_DEVICES, 364 DIFFERENT_SIZES, 365 TYPES(CV_8U, CV_64F, 1, 4), 366 WHOLE_SUBMAT)); 367 368//////////////////////////////////////////////////////////////////////////////// 369// MinMax 370 371PARAM_TEST_CASE(MinMax, cv::cuda::DeviceInfo, cv::Size, MatDepth, UseRoi) 372{ 373 cv::cuda::DeviceInfo devInfo; 374 cv::Size size; 375 int depth; 376 bool useRoi; 377 378 virtual void SetUp() 379 { 380 devInfo = GET_PARAM(0); 381 size = GET_PARAM(1); 382 depth = GET_PARAM(2); 383 useRoi = GET_PARAM(3); 384 385 cv::cuda::setDevice(devInfo.deviceID()); 386 } 387}; 388 389CUDA_TEST_P(MinMax, WithoutMask) 390{ 391 cv::Mat src = randomMat(size, depth); 392 393 if (depth == CV_64F && !supportFeature(devInfo, cv::cuda::NATIVE_DOUBLE)) 394 { 395 try 396 { 397 double minVal, maxVal; 398 cv::cuda::minMax(loadMat(src), &minVal, &maxVal); 399 } 400 catch (const cv::Exception& e) 401 { 402 ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); 403 } 404 } 405 else 406 { 407 double minVal, maxVal; 408 cv::cuda::minMax(loadMat(src, useRoi), &minVal, &maxVal); 409 410 double minVal_gold, maxVal_gold; 411 minMaxLocGold(src, &minVal_gold, &maxVal_gold); 412 413 EXPECT_DOUBLE_EQ(minVal_gold, minVal); 414 EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); 415 } 416} 417 418CUDA_TEST_P(MinMax, Async) 419{ 420 cv::Mat src = randomMat(size, depth); 421 422 cv::cuda::Stream stream; 423 424 cv::cuda::HostMem dst; 425 cv::cuda::findMinMax(loadMat(src, useRoi), dst, cv::noArray(), stream); 426 427 stream.waitForCompletion(); 428 429 double vals[2]; 430 const cv::Mat vals_mat(1, 2, CV_64FC1, &vals[0]); 431 dst.createMatHeader().convertTo(vals_mat, CV_64F); 432 433 double minVal_gold, maxVal_gold; 434 minMaxLocGold(src, &minVal_gold, &maxVal_gold); 435 436 EXPECT_DOUBLE_EQ(minVal_gold, vals[0]); 437 EXPECT_DOUBLE_EQ(maxVal_gold, vals[1]); 438} 439 440CUDA_TEST_P(MinMax, WithMask) 441{ 442 cv::Mat src = randomMat(size, depth); 443 cv::Mat mask = randomMat(size, CV_8UC1, 0.0, 2.0); 444 445 if (depth == CV_64F && !supportFeature(devInfo, cv::cuda::NATIVE_DOUBLE)) 446 { 447 try 448 { 449 double minVal, maxVal; 450 cv::cuda::minMax(loadMat(src), &minVal, &maxVal, loadMat(mask)); 451 } 452 catch (const cv::Exception& e) 453 { 454 ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); 455 } 456 } 457 else 458 { 459 double minVal, maxVal; 460 cv::cuda::minMax(loadMat(src, useRoi), &minVal, &maxVal, loadMat(mask, useRoi)); 461 462 double minVal_gold, maxVal_gold; 463 minMaxLocGold(src, &minVal_gold, &maxVal_gold, 0, 0, mask); 464 465 EXPECT_DOUBLE_EQ(minVal_gold, minVal); 466 EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); 467 } 468} 469 470CUDA_TEST_P(MinMax, NullPtr) 471{ 472 cv::Mat src = randomMat(size, depth); 473 474 if (depth == CV_64F && !supportFeature(devInfo, cv::cuda::NATIVE_DOUBLE)) 475 { 476 try 477 { 478 double minVal, maxVal; 479 cv::cuda::minMax(loadMat(src), &minVal, 0); 480 cv::cuda::minMax(loadMat(src), 0, &maxVal); 481 } 482 catch (const cv::Exception& e) 483 { 484 ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); 485 } 486 } 487 else 488 { 489 double minVal, maxVal; 490 cv::cuda::minMax(loadMat(src, useRoi), &minVal, 0); 491 cv::cuda::minMax(loadMat(src, useRoi), 0, &maxVal); 492 493 double minVal_gold, maxVal_gold; 494 minMaxLocGold(src, &minVal_gold, &maxVal_gold, 0, 0); 495 496 EXPECT_DOUBLE_EQ(minVal_gold, minVal); 497 EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); 498 } 499} 500 501INSTANTIATE_TEST_CASE_P(CUDA_Arithm, MinMax, testing::Combine( 502 ALL_DEVICES, 503 DIFFERENT_SIZES, 504 ALL_DEPTH, 505 WHOLE_SUBMAT)); 506 507//////////////////////////////////////////////////////////////////////////////// 508// MinMaxLoc 509 510namespace 511{ 512 template <typename T> 513 void expectEqualImpl(const cv::Mat& src, cv::Point loc_gold, cv::Point loc) 514 { 515 EXPECT_EQ(src.at<T>(loc_gold.y, loc_gold.x), src.at<T>(loc.y, loc.x)); 516 } 517 518 void expectEqual(const cv::Mat& src, cv::Point loc_gold, cv::Point loc) 519 { 520 typedef void (*func_t)(const cv::Mat& src, cv::Point loc_gold, cv::Point loc); 521 522 static const func_t funcs[] = 523 { 524 expectEqualImpl<uchar>, 525 expectEqualImpl<schar>, 526 expectEqualImpl<ushort>, 527 expectEqualImpl<short>, 528 expectEqualImpl<int>, 529 expectEqualImpl<float>, 530 expectEqualImpl<double> 531 }; 532 533 funcs[src.depth()](src, loc_gold, loc); 534 } 535} 536 537PARAM_TEST_CASE(MinMaxLoc, cv::cuda::DeviceInfo, cv::Size, MatDepth, UseRoi) 538{ 539 cv::cuda::DeviceInfo devInfo; 540 cv::Size size; 541 int depth; 542 bool useRoi; 543 544 virtual void SetUp() 545 { 546 devInfo = GET_PARAM(0); 547 size = GET_PARAM(1); 548 depth = GET_PARAM(2); 549 useRoi = GET_PARAM(3); 550 551 cv::cuda::setDevice(devInfo.deviceID()); 552 } 553}; 554 555CUDA_TEST_P(MinMaxLoc, WithoutMask) 556{ 557 cv::Mat src = randomMat(size, depth); 558 559 if (depth == CV_64F && !supportFeature(devInfo, cv::cuda::NATIVE_DOUBLE)) 560 { 561 try 562 { 563 double minVal, maxVal; 564 cv::Point minLoc, maxLoc; 565 cv::cuda::minMaxLoc(loadMat(src), &minVal, &maxVal, &minLoc, &maxLoc); 566 } 567 catch (const cv::Exception& e) 568 { 569 ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); 570 } 571 } 572 else 573 { 574 double minVal, maxVal; 575 cv::Point minLoc, maxLoc; 576 cv::cuda::minMaxLoc(loadMat(src, useRoi), &minVal, &maxVal, &minLoc, &maxLoc); 577 578 double minVal_gold, maxVal_gold; 579 cv::Point minLoc_gold, maxLoc_gold; 580 minMaxLocGold(src, &minVal_gold, &maxVal_gold, &minLoc_gold, &maxLoc_gold); 581 582 EXPECT_DOUBLE_EQ(minVal_gold, minVal); 583 EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); 584 585 expectEqual(src, minLoc_gold, minLoc); 586 expectEqual(src, maxLoc_gold, maxLoc); 587 } 588} 589 590CUDA_TEST_P(MinMaxLoc, OneRowMat) 591{ 592 cv::Mat src = randomMat(cv::Size(size.width, 1), depth); 593 594 double minVal, maxVal; 595 cv::Point minLoc, maxLoc; 596 cv::cuda::minMaxLoc(loadMat(src, useRoi), &minVal, &maxVal, &minLoc, &maxLoc); 597 598 double minVal_gold, maxVal_gold; 599 cv::Point minLoc_gold, maxLoc_gold; 600 minMaxLocGold(src, &minVal_gold, &maxVal_gold, &minLoc_gold, &maxLoc_gold); 601 602 EXPECT_DOUBLE_EQ(minVal_gold, minVal); 603 EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); 604 605 expectEqual(src, minLoc_gold, minLoc); 606 expectEqual(src, maxLoc_gold, maxLoc); 607} 608 609CUDA_TEST_P(MinMaxLoc, OneColumnMat) 610{ 611 cv::Mat src = randomMat(cv::Size(1, size.height), depth); 612 613 double minVal, maxVal; 614 cv::Point minLoc, maxLoc; 615 cv::cuda::minMaxLoc(loadMat(src, useRoi), &minVal, &maxVal, &minLoc, &maxLoc); 616 617 double minVal_gold, maxVal_gold; 618 cv::Point minLoc_gold, maxLoc_gold; 619 minMaxLocGold(src, &minVal_gold, &maxVal_gold, &minLoc_gold, &maxLoc_gold); 620 621 EXPECT_DOUBLE_EQ(minVal_gold, minVal); 622 EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); 623 624 expectEqual(src, minLoc_gold, minLoc); 625 expectEqual(src, maxLoc_gold, maxLoc); 626} 627 628CUDA_TEST_P(MinMaxLoc, Async) 629{ 630 cv::Mat src = randomMat(size, depth); 631 632 cv::cuda::Stream stream; 633 634 cv::cuda::HostMem minMaxVals, locVals; 635 cv::cuda::findMinMaxLoc(loadMat(src, useRoi), minMaxVals, locVals, cv::noArray(), stream); 636 637 stream.waitForCompletion(); 638 639 double vals[2]; 640 const cv::Mat vals_mat(2, 1, CV_64FC1, &vals[0]); 641 minMaxVals.createMatHeader().convertTo(vals_mat, CV_64F); 642 643 int locs[2]; 644 const cv::Mat locs_mat(2, 1, CV_32SC1, &locs[0]); 645 locVals.createMatHeader().copyTo(locs_mat); 646 647 cv::Point locs2D[] = { 648 cv::Point(locs[0] % src.cols, locs[0] / src.cols), 649 cv::Point(locs[1] % src.cols, locs[1] / src.cols), 650 }; 651 652 double minVal_gold, maxVal_gold; 653 cv::Point minLoc_gold, maxLoc_gold; 654 minMaxLocGold(src, &minVal_gold, &maxVal_gold, &minLoc_gold, &maxLoc_gold); 655 656 EXPECT_DOUBLE_EQ(minVal_gold, vals[0]); 657 EXPECT_DOUBLE_EQ(maxVal_gold, vals[1]); 658 659 expectEqual(src, minLoc_gold, locs2D[0]); 660 expectEqual(src, maxLoc_gold, locs2D[1]); 661} 662 663CUDA_TEST_P(MinMaxLoc, WithMask) 664{ 665 cv::Mat src = randomMat(size, depth); 666 cv::Mat mask = randomMat(size, CV_8UC1, 0.0, 2.0); 667 668 if (depth == CV_64F && !supportFeature(devInfo, cv::cuda::NATIVE_DOUBLE)) 669 { 670 try 671 { 672 double minVal, maxVal; 673 cv::Point minLoc, maxLoc; 674 cv::cuda::minMaxLoc(loadMat(src), &minVal, &maxVal, &minLoc, &maxLoc, loadMat(mask)); 675 } 676 catch (const cv::Exception& e) 677 { 678 ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); 679 } 680 } 681 else 682 { 683 double minVal, maxVal; 684 cv::Point minLoc, maxLoc; 685 cv::cuda::minMaxLoc(loadMat(src, useRoi), &minVal, &maxVal, &minLoc, &maxLoc, loadMat(mask, useRoi)); 686 687 double minVal_gold, maxVal_gold; 688 cv::Point minLoc_gold, maxLoc_gold; 689 minMaxLocGold(src, &minVal_gold, &maxVal_gold, &minLoc_gold, &maxLoc_gold, mask); 690 691 EXPECT_DOUBLE_EQ(minVal_gold, minVal); 692 EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); 693 694 expectEqual(src, minLoc_gold, minLoc); 695 expectEqual(src, maxLoc_gold, maxLoc); 696 } 697} 698 699CUDA_TEST_P(MinMaxLoc, NullPtr) 700{ 701 cv::Mat src = randomMat(size, depth); 702 703 if (depth == CV_64F && !supportFeature(devInfo, cv::cuda::NATIVE_DOUBLE)) 704 { 705 try 706 { 707 double minVal, maxVal; 708 cv::Point minLoc, maxLoc; 709 cv::cuda::minMaxLoc(loadMat(src, useRoi), &minVal, 0, 0, 0); 710 cv::cuda::minMaxLoc(loadMat(src, useRoi), 0, &maxVal, 0, 0); 711 cv::cuda::minMaxLoc(loadMat(src, useRoi), 0, 0, &minLoc, 0); 712 cv::cuda::minMaxLoc(loadMat(src, useRoi), 0, 0, 0, &maxLoc); 713 } 714 catch (const cv::Exception& e) 715 { 716 ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); 717 } 718 } 719 else 720 { 721 double minVal, maxVal; 722 cv::Point minLoc, maxLoc; 723 cv::cuda::minMaxLoc(loadMat(src, useRoi), &minVal, 0, 0, 0); 724 cv::cuda::minMaxLoc(loadMat(src, useRoi), 0, &maxVal, 0, 0); 725 cv::cuda::minMaxLoc(loadMat(src, useRoi), 0, 0, &minLoc, 0); 726 cv::cuda::minMaxLoc(loadMat(src, useRoi), 0, 0, 0, &maxLoc); 727 728 double minVal_gold, maxVal_gold; 729 cv::Point minLoc_gold, maxLoc_gold; 730 minMaxLocGold(src, &minVal_gold, &maxVal_gold, &minLoc_gold, &maxLoc_gold); 731 732 EXPECT_DOUBLE_EQ(minVal_gold, minVal); 733 EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); 734 735 expectEqual(src, minLoc_gold, minLoc); 736 expectEqual(src, maxLoc_gold, maxLoc); 737 } 738} 739 740INSTANTIATE_TEST_CASE_P(CUDA_Arithm, MinMaxLoc, testing::Combine( 741 ALL_DEVICES, 742 DIFFERENT_SIZES, 743 ALL_DEPTH, 744 WHOLE_SUBMAT)); 745 746//////////////////////////////////////////////////////////////////////////// 747// CountNonZero 748 749PARAM_TEST_CASE(CountNonZero, cv::cuda::DeviceInfo, cv::Size, MatDepth, UseRoi) 750{ 751 cv::cuda::DeviceInfo devInfo; 752 cv::Size size; 753 int depth; 754 bool useRoi; 755 756 cv::Mat src; 757 758 virtual void SetUp() 759 { 760 devInfo = GET_PARAM(0); 761 size = GET_PARAM(1); 762 depth = GET_PARAM(2); 763 useRoi = GET_PARAM(3); 764 765 cv::cuda::setDevice(devInfo.deviceID()); 766 767 cv::Mat srcBase = randomMat(size, CV_8U, 0.0, 1.5); 768 srcBase.convertTo(src, depth); 769 } 770}; 771 772CUDA_TEST_P(CountNonZero, Accuracy) 773{ 774 if (depth == CV_64F && !supportFeature(devInfo, cv::cuda::NATIVE_DOUBLE)) 775 { 776 try 777 { 778 cv::cuda::countNonZero(loadMat(src)); 779 } 780 catch (const cv::Exception& e) 781 { 782 ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code); 783 } 784 } 785 else 786 { 787 int val = cv::cuda::countNonZero(loadMat(src, useRoi)); 788 789 int val_gold = cv::countNonZero(src); 790 791 ASSERT_EQ(val_gold, val); 792 } 793} 794 795CUDA_TEST_P(CountNonZero, Async) 796{ 797 cv::cuda::Stream stream; 798 799 cv::cuda::HostMem dst; 800 cv::cuda::countNonZero(loadMat(src, useRoi), dst, stream); 801 802 stream.waitForCompletion(); 803 804 int val; 805 const cv::Mat val_mat(1, 1, CV_32SC1, &val); 806 dst.createMatHeader().copyTo(val_mat); 807 808 int val_gold = cv::countNonZero(src); 809 810 ASSERT_EQ(val_gold, val); 811} 812 813INSTANTIATE_TEST_CASE_P(CUDA_Arithm, CountNonZero, testing::Combine( 814 ALL_DEVICES, 815 DIFFERENT_SIZES, 816 ALL_DEPTH, 817 WHOLE_SUBMAT)); 818 819////////////////////////////////////////////////////////////////////////////// 820// Reduce 821 822CV_ENUM(ReduceCode, cv::REDUCE_SUM, cv::REDUCE_AVG, cv::REDUCE_MAX, cv::REDUCE_MIN) 823#define ALL_REDUCE_CODES testing::Values(ReduceCode(cv::REDUCE_SUM), ReduceCode(cv::REDUCE_AVG), ReduceCode(cv::REDUCE_MAX), ReduceCode(cv::REDUCE_MIN)) 824 825PARAM_TEST_CASE(Reduce, cv::cuda::DeviceInfo, cv::Size, MatDepth, Channels, ReduceCode, UseRoi) 826{ 827 cv::cuda::DeviceInfo devInfo; 828 cv::Size size; 829 int depth; 830 int channels; 831 int reduceOp; 832 bool useRoi; 833 834 int type; 835 int dst_depth; 836 int dst_type; 837 838 virtual void SetUp() 839 { 840 devInfo = GET_PARAM(0); 841 size = GET_PARAM(1); 842 depth = GET_PARAM(2); 843 channels = GET_PARAM(3); 844 reduceOp = GET_PARAM(4); 845 useRoi = GET_PARAM(5); 846 847 cv::cuda::setDevice(devInfo.deviceID()); 848 849 type = CV_MAKE_TYPE(depth, channels); 850 851 if (reduceOp == cv::REDUCE_MAX || reduceOp == cv::REDUCE_MIN) 852 dst_depth = depth; 853 else if (reduceOp == cv::REDUCE_SUM) 854 dst_depth = depth == CV_8U ? CV_32S : depth < CV_64F ? CV_32F : depth; 855 else 856 dst_depth = depth < CV_32F ? CV_32F : depth; 857 858 dst_type = CV_MAKE_TYPE(dst_depth, channels); 859 } 860 861}; 862 863CUDA_TEST_P(Reduce, Rows) 864{ 865 cv::Mat src = randomMat(size, type); 866 867 cv::cuda::GpuMat dst = createMat(cv::Size(src.cols, 1), dst_type, useRoi); 868 cv::cuda::reduce(loadMat(src, useRoi), dst, 0, reduceOp, dst_depth); 869 870 cv::Mat dst_gold; 871 cv::reduce(src, dst_gold, 0, reduceOp, dst_depth); 872 873 EXPECT_MAT_NEAR(dst_gold, dst, dst_depth < CV_32F ? 0.0 : 0.02); 874} 875 876CUDA_TEST_P(Reduce, Cols) 877{ 878 cv::Mat src = randomMat(size, type); 879 880 cv::cuda::GpuMat dst = createMat(cv::Size(src.rows, 1), dst_type, useRoi); 881 cv::cuda::reduce(loadMat(src, useRoi), dst, 1, reduceOp, dst_depth); 882 883 cv::Mat dst_gold; 884 cv::reduce(src, dst_gold, 1, reduceOp, dst_depth); 885 dst_gold.cols = dst_gold.rows; 886 dst_gold.rows = 1; 887 dst_gold.step = dst_gold.cols * dst_gold.elemSize(); 888 889 EXPECT_MAT_NEAR(dst_gold, dst, dst_depth < CV_32F ? 0.0 : 0.02); 890} 891 892INSTANTIATE_TEST_CASE_P(CUDA_Arithm, Reduce, testing::Combine( 893 ALL_DEVICES, 894 DIFFERENT_SIZES, 895 testing::Values(MatDepth(CV_8U), 896 MatDepth(CV_16U), 897 MatDepth(CV_16S), 898 MatDepth(CV_32F), 899 MatDepth(CV_64F)), 900 ALL_CHANNELS, 901 ALL_REDUCE_CODES, 902 WHOLE_SUBMAT)); 903 904////////////////////////////////////////////////////////////////////////////// 905// Normalize 906 907PARAM_TEST_CASE(Normalize, cv::cuda::DeviceInfo, cv::Size, MatDepth, NormCode, UseRoi) 908{ 909 cv::cuda::DeviceInfo devInfo; 910 cv::Size size; 911 int type; 912 int norm_type; 913 bool useRoi; 914 915 double alpha; 916 double beta; 917 918 virtual void SetUp() 919 { 920 devInfo = GET_PARAM(0); 921 size = GET_PARAM(1); 922 type = GET_PARAM(2); 923 norm_type = GET_PARAM(3); 924 useRoi = GET_PARAM(4); 925 926 cv::cuda::setDevice(devInfo.deviceID()); 927 928 alpha = 1; 929 beta = 0; 930 } 931 932}; 933 934CUDA_TEST_P(Normalize, WithOutMask) 935{ 936 cv::Mat src = randomMat(size, type); 937 938 cv::cuda::GpuMat dst = createMat(size, type, useRoi); 939 cv::cuda::normalize(loadMat(src, useRoi), dst, alpha, beta, norm_type, type); 940 941 cv::Mat dst_gold; 942 cv::normalize(src, dst_gold, alpha, beta, norm_type, type); 943 944 EXPECT_MAT_NEAR(dst_gold, dst, type < CV_32F ? 1.0 : 1e-4); 945} 946 947CUDA_TEST_P(Normalize, WithMask) 948{ 949 cv::Mat src = randomMat(size, type); 950 cv::Mat mask = randomMat(size, CV_8UC1, 0, 2); 951 952 cv::cuda::GpuMat dst = createMat(size, type, useRoi); 953 dst.setTo(cv::Scalar::all(0)); 954 cv::cuda::normalize(loadMat(src, useRoi), dst, alpha, beta, norm_type, type, loadMat(mask, useRoi)); 955 956 cv::Mat dst_gold(size, type); 957 dst_gold.setTo(cv::Scalar::all(0)); 958 cv::normalize(src, dst_gold, alpha, beta, norm_type, type, mask); 959 960 EXPECT_MAT_NEAR(dst_gold, dst, type < CV_32F ? 1.0 : 1e-4); 961} 962 963INSTANTIATE_TEST_CASE_P(CUDA_Arithm, Normalize, testing::Combine( 964 ALL_DEVICES, 965 DIFFERENT_SIZES, 966 ALL_DEPTH, 967 testing::Values(NormCode(cv::NORM_L1), NormCode(cv::NORM_L2), NormCode(cv::NORM_INF), NormCode(cv::NORM_MINMAX)), 968 WHOLE_SUBMAT)); 969 970//////////////////////////////////////////////////////////////////////////////// 971// MeanStdDev 972 973PARAM_TEST_CASE(MeanStdDev, cv::cuda::DeviceInfo, cv::Size, UseRoi) 974{ 975 cv::cuda::DeviceInfo devInfo; 976 cv::Size size; 977 bool useRoi; 978 979 virtual void SetUp() 980 { 981 devInfo = GET_PARAM(0); 982 size = GET_PARAM(1); 983 useRoi = GET_PARAM(2); 984 985 cv::cuda::setDevice(devInfo.deviceID()); 986 } 987}; 988 989CUDA_TEST_P(MeanStdDev, Accuracy) 990{ 991 cv::Mat src = randomMat(size, CV_8UC1); 992 993 if (!supportFeature(devInfo, cv::cuda::FEATURE_SET_COMPUTE_13)) 994 { 995 try 996 { 997 cv::Scalar mean; 998 cv::Scalar stddev; 999 cv::cuda::meanStdDev(loadMat(src, useRoi), mean, stddev); 1000 } 1001 catch (const cv::Exception& e) 1002 { 1003 ASSERT_EQ(cv::Error::StsNotImplemented, e.code); 1004 } 1005 } 1006 else 1007 { 1008 cv::Scalar mean; 1009 cv::Scalar stddev; 1010 cv::cuda::meanStdDev(loadMat(src, useRoi), mean, stddev); 1011 1012 cv::Scalar mean_gold; 1013 cv::Scalar stddev_gold; 1014 cv::meanStdDev(src, mean_gold, stddev_gold); 1015 1016 EXPECT_SCALAR_NEAR(mean_gold, mean, 1e-5); 1017 EXPECT_SCALAR_NEAR(stddev_gold, stddev, 1e-5); 1018 } 1019} 1020 1021CUDA_TEST_P(MeanStdDev, Async) 1022{ 1023 cv::Mat src = randomMat(size, CV_8UC1); 1024 1025 cv::cuda::Stream stream; 1026 1027 cv::cuda::HostMem dst; 1028 cv::cuda::meanStdDev(loadMat(src, useRoi), dst, stream); 1029 1030 stream.waitForCompletion(); 1031 1032 double vals[2]; 1033 dst.createMatHeader().copyTo(cv::Mat(1, 2, CV_64FC1, &vals[0])); 1034 1035 cv::Scalar mean_gold; 1036 cv::Scalar stddev_gold; 1037 cv::meanStdDev(src, mean_gold, stddev_gold); 1038 1039 EXPECT_SCALAR_NEAR(mean_gold, cv::Scalar(vals[0]), 1e-5); 1040 EXPECT_SCALAR_NEAR(stddev_gold, cv::Scalar(vals[1]), 1e-5); 1041} 1042 1043INSTANTIATE_TEST_CASE_P(CUDA_Arithm, MeanStdDev, testing::Combine( 1044 ALL_DEVICES, 1045 DIFFERENT_SIZES, 1046 WHOLE_SUBMAT)); 1047 1048/////////////////////////////////////////////////////////////////////////////////////////////////////// 1049// Integral 1050 1051PARAM_TEST_CASE(Integral, cv::cuda::DeviceInfo, cv::Size, UseRoi) 1052{ 1053 cv::cuda::DeviceInfo devInfo; 1054 cv::Size size; 1055 bool useRoi; 1056 1057 virtual void SetUp() 1058 { 1059 devInfo = GET_PARAM(0); 1060 size = GET_PARAM(1); 1061 useRoi = GET_PARAM(2); 1062 1063 cv::cuda::setDevice(devInfo.deviceID()); 1064 } 1065}; 1066 1067CUDA_TEST_P(Integral, Accuracy) 1068{ 1069 cv::Mat src = randomMat(size, CV_8UC1); 1070 1071 cv::cuda::GpuMat dst = createMat(cv::Size(src.cols + 1, src.rows + 1), CV_32SC1, useRoi); 1072 cv::cuda::integral(loadMat(src, useRoi), dst); 1073 1074 cv::Mat dst_gold; 1075 cv::integral(src, dst_gold, CV_32S); 1076 1077 EXPECT_MAT_NEAR(dst_gold, dst, 0.0); 1078} 1079 1080INSTANTIATE_TEST_CASE_P(CUDA_Arithm, Integral, testing::Combine( 1081 ALL_DEVICES, 1082 testing::Values(cv::Size(128, 128), cv::Size(113, 113), cv::Size(768, 1066)), 1083 WHOLE_SUBMAT)); 1084 1085/////////////////////////////////////////////////////////////////////////////////////////////////////// 1086// IntegralSqr 1087 1088PARAM_TEST_CASE(IntegralSqr, cv::cuda::DeviceInfo, cv::Size, UseRoi) 1089{ 1090 cv::cuda::DeviceInfo devInfo; 1091 cv::Size size; 1092 bool useRoi; 1093 1094 virtual void SetUp() 1095 { 1096 devInfo = GET_PARAM(0); 1097 size = GET_PARAM(1); 1098 useRoi = GET_PARAM(2); 1099 1100 cv::cuda::setDevice(devInfo.deviceID()); 1101 } 1102}; 1103 1104CUDA_TEST_P(IntegralSqr, Accuracy) 1105{ 1106 cv::Mat src = randomMat(size, CV_8UC1); 1107 1108 cv::cuda::GpuMat dst = createMat(cv::Size(src.cols + 1, src.rows + 1), CV_64FC1, useRoi); 1109 cv::cuda::sqrIntegral(loadMat(src, useRoi), dst); 1110 1111 cv::Mat dst_gold, temp; 1112 cv::integral(src, temp, dst_gold); 1113 1114 EXPECT_MAT_NEAR(dst_gold, dst, 0.0); 1115} 1116 1117INSTANTIATE_TEST_CASE_P(CUDA_Arithm, IntegralSqr, testing::Combine( 1118 ALL_DEVICES, 1119 DIFFERENT_SIZES, 1120 WHOLE_SUBMAT)); 1121 1122#endif // HAVE_CUDA 1123