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 // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 16 // Third party copyrights are property of their respective owners. 17 // 18 // Redistribution and use in source and binary forms, with or without modification, 19 // are permitted provided that the following conditions are met: 20 // 21 // * Redistribution's of source code must retain the above copyright notice, 22 // this list of conditions and the following disclaimer. 23 // 24 // * Redistribution's in binary form must reproduce the above copyright notice, 25 // this list of conditions and the following disclaimer in the documentation 26 // and/or other materials provided with the distribution. 27 // 28 // * The name of the copyright holders may not be used to endorse or promote products 29 // derived from this software without specific prior written permission. 30 // 31 // This software is provided by the copyright holders and contributors "as is" and 32 // any express or implied warranties, including, but not limited to, the implied 33 // warranties of merchantability and fitness for a particular purpose are disclaimed. 34 // In no event shall the Intel Corporation or contributors be liable for any direct, 35 // indirect, incidental, special, exemplary, or consequential damages 36 // (including, but not limited to, procurement of substitute goods or services; 37 // loss of use, data, or profits; or business interruption) however caused 38 // and on any theory of liability, whether in contract, strict liability, 39 // or tort (including negligence or otherwise) arising in any way out of 40 // the use of this software, even if advised of the possibility of such damage. 41 // 42 //M*/ 43 44 #pragma once 45 46 #ifndef __OPENCV_CUDEV_FUNCTIONAL_FUNCTIONAL_HPP__ 47 #define __OPENCV_CUDEV_FUNCTIONAL_FUNCTIONAL_HPP__ 48 49 #include "../common.hpp" 50 #include "../util/saturate_cast.hpp" 51 #include "../util/vec_traits.hpp" 52 #include "../util/vec_math.hpp" 53 #include "../util/type_traits.hpp" 54 55 namespace cv { namespace cudev { 56 57 //! @addtogroup cudev 58 //! @{ 59 60 // Function Objects 61 62 template <typename _Arg, typename _Result> struct unary_function 63 { 64 typedef _Arg argument_type; 65 typedef _Result result_type; 66 }; 67 68 template <typename _Arg1, typename _Arg2, typename _Result> struct binary_function 69 { 70 typedef _Arg1 first_argument_type; 71 typedef _Arg2 second_argument_type; 72 typedef _Result result_type; 73 }; 74 75 // Arithmetic Operations 76 77 template <typename T> struct plus : binary_function<T, T, T> 78 { 79 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 80 typename TypeTraits<T>::parameter_type b) const 81 { 82 return saturate_cast<T>(a + b); 83 } 84 }; 85 86 template <typename T> struct minus : binary_function<T, T, T> 87 { 88 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 89 typename TypeTraits<T>::parameter_type b) const 90 { 91 return saturate_cast<T>(a - b); 92 } 93 }; 94 95 template <typename T> struct multiplies : binary_function<T, T, T> 96 { 97 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 98 typename TypeTraits<T>::parameter_type b) const 99 { 100 return saturate_cast<T>(a * b); 101 } 102 }; 103 104 template <typename T> struct divides : binary_function<T, T, T> 105 { 106 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 107 typename TypeTraits<T>::parameter_type b) const 108 { 109 return saturate_cast<T>(a / b); 110 } 111 }; 112 113 template <typename T> struct modulus : binary_function<T, T, T> 114 { 115 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 116 typename TypeTraits<T>::parameter_type b) const 117 { 118 return saturate_cast<T>(a % b); 119 } 120 }; 121 122 template <typename T> struct negate : unary_function<T, T> 123 { 124 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a) const 125 { 126 return saturate_cast<T>(-a); 127 } 128 }; 129 130 // Comparison Operations 131 132 template <typename T> struct equal_to : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type> 133 { 134 __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type 135 operator ()(typename TypeTraits<T>::parameter_type a, 136 typename TypeTraits<T>::parameter_type b) const 137 { 138 return a == b; 139 } 140 }; 141 142 template <typename T> struct not_equal_to : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type> 143 { 144 __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type 145 operator ()(typename TypeTraits<T>::parameter_type a, 146 typename TypeTraits<T>::parameter_type b) const 147 { 148 return a != b; 149 } 150 }; 151 152 template <typename T> struct greater : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type> 153 { 154 __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type 155 operator ()(typename TypeTraits<T>::parameter_type a, 156 typename TypeTraits<T>::parameter_type b) const 157 { 158 return a > b; 159 } 160 }; 161 162 template <typename T> struct less : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type> 163 { 164 __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type 165 operator ()(typename TypeTraits<T>::parameter_type a, 166 typename TypeTraits<T>::parameter_type b) const 167 { 168 return a < b; 169 } 170 }; 171 172 template <typename T> struct greater_equal : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type> 173 { 174 __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type 175 operator ()(typename TypeTraits<T>::parameter_type a, 176 typename TypeTraits<T>::parameter_type b) const 177 { 178 return a >= b; 179 } 180 }; 181 182 template <typename T> struct less_equal : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type> 183 { 184 __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type 185 operator ()(typename TypeTraits<T>::parameter_type a, 186 typename TypeTraits<T>::parameter_type b) const 187 { 188 return a <= b; 189 } 190 }; 191 192 // Logical Operations 193 194 template <typename T> struct logical_and : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type> 195 { 196 __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type 197 operator ()(typename TypeTraits<T>::parameter_type a, 198 typename TypeTraits<T>::parameter_type b) const 199 { 200 return a && b; 201 } 202 }; 203 204 template <typename T> struct logical_or : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type> 205 { 206 __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type 207 operator ()(typename TypeTraits<T>::parameter_type a, 208 typename TypeTraits<T>::parameter_type b) const 209 { 210 return a || b; 211 } 212 }; 213 214 template <typename T> struct logical_not : unary_function<T, typename MakeVec<uchar, VecTraits<T>::cn>::type> 215 { 216 __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type 217 operator ()(typename TypeTraits<T>::parameter_type a) const 218 { 219 return !a; 220 } 221 }; 222 223 // Bitwise Operations 224 225 template <typename T> struct bit_and : binary_function<T, T, T> 226 { 227 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 228 typename TypeTraits<T>::parameter_type b) const 229 { 230 return a & b; 231 } 232 }; 233 234 template <typename T> struct bit_or : binary_function<T, T, T> 235 { 236 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 237 typename TypeTraits<T>::parameter_type b) const 238 { 239 return a | b; 240 } 241 }; 242 243 template <typename T> struct bit_xor : binary_function<T, T, T> 244 { 245 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 246 typename TypeTraits<T>::parameter_type b) const 247 { 248 return a ^ b; 249 } 250 }; 251 252 template <typename T> struct bit_not : unary_function<T, T> 253 { 254 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type v) const 255 { 256 return ~v; 257 } 258 }; 259 260 template <typename T> struct bit_lshift : binary_function<T, T, T> 261 { 262 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 263 typename TypeTraits<T>::parameter_type b) const 264 { 265 return a << b; 266 } 267 }; 268 269 template <typename T> struct bit_rshift : binary_function<T, T, T> 270 { 271 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 272 typename TypeTraits<T>::parameter_type b) const 273 { 274 return a >> b; 275 } 276 }; 277 278 // Generalized Identity Operations 279 280 template <typename T> struct identity : unary_function<T, T> 281 { 282 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type x) const 283 { 284 return x; 285 } 286 }; 287 288 template <typename T1, typename T2> struct project1st : binary_function<T1, T2, T1> 289 { 290 __device__ __forceinline__ T1 291 operator ()(typename TypeTraits<T1>::parameter_type lhs, 292 typename TypeTraits<T2>::parameter_type) const 293 { 294 return lhs; 295 } 296 }; 297 298 template <typename T1, typename T2> struct project2nd : binary_function<T1, T2, T2> 299 { 300 __device__ __forceinline__ T2 301 operator ()(typename TypeTraits<T1>::parameter_type, 302 typename TypeTraits<T2>::parameter_type rhs) const 303 { 304 return rhs; 305 } 306 }; 307 308 // Min/Max Operations 309 310 template <typename T> struct maximum : binary_function<T, T, T> 311 { 312 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 313 typename TypeTraits<T>::parameter_type b) const 314 { 315 return max(a, b); 316 } 317 }; 318 319 template <typename T> struct minimum : binary_function<T, T, T> 320 { 321 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, 322 typename TypeTraits<T>::parameter_type b) const 323 { 324 return min(a, b); 325 } 326 }; 327 328 #define CV_CUDEV_MINMAX_INST(type, maxop, minop) \ 329 template <> struct maximum<type> : binary_function<type, type, type> \ 330 { \ 331 __device__ __forceinline__ type operator ()(type a, type b) const {return maxop(a, b);} \ 332 }; \ 333 template <> struct minimum<type> : binary_function<type, type, type> \ 334 { \ 335 __device__ __forceinline__ type operator ()(type a, type b) const {return minop(a, b);} \ 336 }; 337 338 339 CV_CUDEV_MINMAX_INST(uchar, ::max, ::min) 340 CV_CUDEV_MINMAX_INST(schar, ::max, ::min) 341 CV_CUDEV_MINMAX_INST(ushort, ::max, ::min) 342 CV_CUDEV_MINMAX_INST(short, ::max, ::min) 343 CV_CUDEV_MINMAX_INST(int, ::max, ::min) 344 CV_CUDEV_MINMAX_INST(uint, ::max, ::min) 345 CV_CUDEV_MINMAX_INST(float, ::fmaxf, ::fminf) 346 CV_CUDEV_MINMAX_INST(double, ::fmax, ::fmin) 347 348 #undef CV_CUDEV_MINMAX_INST 349 350 // abs_func 351 352 template <typename T> struct abs_func : unary_function<T, T> 353 { 354 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type x) const 355 { 356 return abs(x); 357 } 358 }; 359 360 template <> struct abs_func<uchar> : unary_function<uchar, uchar> 361 { 362 __device__ __forceinline__ uchar operator ()(uchar x) const 363 { 364 return x; 365 } 366 }; 367 368 template <> struct abs_func<schar> : unary_function<schar, schar> 369 { 370 __device__ __forceinline__ schar operator ()(schar x) const 371 { 372 return ::abs((int) x); 373 } 374 }; 375 376 template <> struct abs_func<ushort> : unary_function<ushort, ushort> 377 { 378 __device__ __forceinline__ ushort operator ()(ushort x) const 379 { 380 return x; 381 } 382 }; 383 384 template <> struct abs_func<short> : unary_function<short, short> 385 { 386 __device__ __forceinline__ short operator ()(short x) const 387 { 388 return ::abs((int) x); 389 } 390 }; 391 392 template <> struct abs_func<uint> : unary_function<uint, uint> 393 { 394 __device__ __forceinline__ uint operator ()(uint x) const 395 { 396 return x; 397 } 398 }; 399 400 template <> struct abs_func<int> : unary_function<int, int> 401 { 402 __device__ __forceinline__ int operator ()(int x) const 403 { 404 return ::abs(x); 405 } 406 }; 407 408 template <> struct abs_func<float> : unary_function<float, float> 409 { 410 __device__ __forceinline__ float operator ()(float x) const 411 { 412 return ::fabsf(x); 413 } 414 }; 415 416 template <> struct abs_func<double> : unary_function<double, double> 417 { 418 __device__ __forceinline__ double operator ()(double x) const 419 { 420 return ::fabs(x); 421 } 422 }; 423 424 // absdiff_func 425 426 template <typename T> struct absdiff_func : binary_function<T, T, T> 427 { 428 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, typename TypeTraits<T>::parameter_type b) const 429 { 430 abs_func<T> f; 431 return f(a - b); 432 } 433 }; 434 435 // Math functions 436 437 template <typename T> struct sqr_func : unary_function<T, T> 438 { 439 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type x) const 440 { 441 return x * x; 442 } 443 }; 444 445 namespace functional_detail 446 { 447 template <typename T> struct FloatType 448 { 449 typedef typename MakeVec< 450 typename LargerType<float, typename VecTraits<T>::elem_type>::type, 451 VecTraits<T>::cn 452 >::type type; 453 }; 454 } 455 456 #define CV_CUDEV_UNARY_FUNCTION_INST(name, func) \ 457 template <typename T> struct name ## _func : unary_function<T, typename functional_detail::FloatType<T>::type> \ 458 { \ 459 __device__ __forceinline__ typename functional_detail::FloatType<T>::type operator ()(typename TypeTraits<T>::parameter_type a) const \ 460 { \ 461 return name(a); \ 462 } \ 463 }; \ 464 template <> struct name ## _func<uchar> : unary_function<uchar, float> \ 465 { \ 466 __device__ __forceinline__ float operator ()(uchar a) const \ 467 { \ 468 return func ## f(a); \ 469 } \ 470 }; \ 471 template <> struct name ## _func<schar> : unary_function<schar, float> \ 472 { \ 473 __device__ __forceinline__ float operator ()(schar a) const \ 474 { \ 475 return func ## f(a); \ 476 } \ 477 }; \ 478 template <> struct name ## _func<ushort> : unary_function<ushort, float> \ 479 { \ 480 __device__ __forceinline__ float operator ()(ushort a) const \ 481 { \ 482 return func ## f(a); \ 483 } \ 484 }; \ 485 template <> struct name ## _func<short> : unary_function<short, float> \ 486 { \ 487 __device__ __forceinline__ float operator ()(short a) const \ 488 { \ 489 return func ## f(a); \ 490 } \ 491 }; \ 492 template <> struct name ## _func<uint> : unary_function<uint, float> \ 493 { \ 494 __device__ __forceinline__ float operator ()(uint a) const \ 495 { \ 496 return func ## f(a); \ 497 } \ 498 }; \ 499 template <> struct name ## _func<int> : unary_function<int, float> \ 500 { \ 501 __device__ __forceinline__ float operator ()(int a) const \ 502 { \ 503 return func ## f(a); \ 504 } \ 505 }; \ 506 template <> struct name ## _func<float> : unary_function<float, float> \ 507 { \ 508 __device__ __forceinline__ float operator ()(float a) const \ 509 { \ 510 return func ## f(a); \ 511 } \ 512 }; \ 513 template <> struct name ## _func<double> : unary_function<double, double> \ 514 { \ 515 __device__ __forceinline__ double operator ()(double a) const \ 516 { \ 517 return func(a); \ 518 } \ 519 }; 520 521 CV_CUDEV_UNARY_FUNCTION_INST(sqrt, ::sqrt) 522 CV_CUDEV_UNARY_FUNCTION_INST(exp, ::exp) 523 CV_CUDEV_UNARY_FUNCTION_INST(exp2, ::exp2) 524 CV_CUDEV_UNARY_FUNCTION_INST(exp10, ::exp10) 525 CV_CUDEV_UNARY_FUNCTION_INST(log, ::log) 526 CV_CUDEV_UNARY_FUNCTION_INST(log2, ::log2) 527 CV_CUDEV_UNARY_FUNCTION_INST(log10, ::log10) 528 CV_CUDEV_UNARY_FUNCTION_INST(sin, ::sin) 529 CV_CUDEV_UNARY_FUNCTION_INST(cos, ::cos) 530 CV_CUDEV_UNARY_FUNCTION_INST(tan, ::tan) 531 CV_CUDEV_UNARY_FUNCTION_INST(asin, ::asin) 532 CV_CUDEV_UNARY_FUNCTION_INST(acos, ::acos) 533 CV_CUDEV_UNARY_FUNCTION_INST(atan, ::atan) 534 CV_CUDEV_UNARY_FUNCTION_INST(sinh, ::sinh) 535 CV_CUDEV_UNARY_FUNCTION_INST(cosh, ::cosh) 536 CV_CUDEV_UNARY_FUNCTION_INST(tanh, ::tanh) 537 CV_CUDEV_UNARY_FUNCTION_INST(asinh, ::asinh) 538 CV_CUDEV_UNARY_FUNCTION_INST(acosh, ::acosh) 539 CV_CUDEV_UNARY_FUNCTION_INST(atanh, ::atanh) 540 541 #undef CV_CUDEV_UNARY_FUNCTION_INST 542 543 #define CV_CUDEV_BINARY_FUNCTION_INST(name, func) \ 544 template <typename T> struct name ## _func : binary_function<T, T, typename functional_detail::FloatType<T>::type> \ 545 { \ 546 __device__ __forceinline__ typename functional_detail::FloatType<T>::type operator ()(typename TypeTraits<T>::parameter_type a, typename TypeTraits<T>::parameter_type b) const \ 547 { \ 548 return name(a, b); \ 549 } \ 550 }; \ 551 template <> struct name ## _func<uchar> : binary_function<uchar, uchar, float> \ 552 { \ 553 __device__ __forceinline__ float operator ()(uchar a, uchar b) const \ 554 { \ 555 return func ## f(a, b); \ 556 } \ 557 }; \ 558 template <> struct name ## _func<schar> : binary_function<schar, schar, float> \ 559 { \ 560 __device__ __forceinline__ float operator ()(schar a, schar b) const \ 561 { \ 562 return func ## f(a, b); \ 563 } \ 564 }; \ 565 template <> struct name ## _func<ushort> : binary_function<ushort, ushort, float> \ 566 { \ 567 __device__ __forceinline__ float operator ()(ushort a, ushort b) const \ 568 { \ 569 return func ## f(a, b); \ 570 } \ 571 }; \ 572 template <> struct name ## _func<short> : binary_function<short, short, float> \ 573 { \ 574 __device__ __forceinline__ float operator ()(short a, short b) const \ 575 { \ 576 return func ## f(a, b); \ 577 } \ 578 }; \ 579 template <> struct name ## _func<uint> : binary_function<uint, uint, float> \ 580 { \ 581 __device__ __forceinline__ float operator ()(uint a, uint b) const \ 582 { \ 583 return func ## f(a, b); \ 584 } \ 585 }; \ 586 template <> struct name ## _func<int> : binary_function<int, int, float> \ 587 { \ 588 __device__ __forceinline__ float operator ()(int a, int b) const \ 589 { \ 590 return func ## f(a, b); \ 591 } \ 592 }; \ 593 template <> struct name ## _func<float> : binary_function<float, float, float> \ 594 { \ 595 __device__ __forceinline__ float operator ()(float a, float b) const \ 596 { \ 597 return func ## f(a, b); \ 598 } \ 599 }; \ 600 template <> struct name ## _func<double> : binary_function<double, double, double> \ 601 { \ 602 __device__ __forceinline__ double operator ()(double a, double b) const \ 603 { \ 604 return func(a, b); \ 605 } \ 606 }; 607 608 CV_CUDEV_BINARY_FUNCTION_INST(hypot, ::hypot) 609 CV_CUDEV_BINARY_FUNCTION_INST(atan2, ::atan2) 610 611 #undef CV_CUDEV_BINARY_FUNCTION_INST 612 613 template <typename T> struct magnitude_func : binary_function<T, T, typename functional_detail::FloatType<T>::type> 614 { 615 __device__ __forceinline__ typename functional_detail::FloatType<T>::type operator ()(typename TypeTraits<T>::parameter_type a, typename TypeTraits<T>::parameter_type b) const 616 { 617 sqrt_func<typename functional_detail::FloatType<T>::type> f; 618 return f(a * a + b * b); 619 } 620 }; 621 622 template <typename T> struct magnitude_sqr_func : binary_function<T, T, typename functional_detail::FloatType<T>::type> 623 { 624 __device__ __forceinline__ typename functional_detail::FloatType<T>::type operator ()(typename TypeTraits<T>::parameter_type a, typename TypeTraits<T>::parameter_type b) const 625 { 626 return a * a + b * b; 627 } 628 }; 629 630 template <typename T, bool angleInDegrees> struct direction_func : binary_function<T, T, T> 631 { 632 __device__ T operator ()(T x, T y) const 633 { 634 atan2_func<T> f; 635 typename atan2_func<T>::result_type angle = f(y, x); 636 637 angle += (angle < 0) * (2.0f * CV_PI_F); 638 639 if (angleInDegrees) 640 angle *= (180.0f / CV_PI_F); 641 642 return saturate_cast<T>(angle); 643 } 644 }; 645 646 template <typename T> struct pow_func : binary_function<T, float, float> 647 { 648 __device__ __forceinline__ float operator ()(T val, float power) const 649 { 650 return ::powf(val, power); 651 } 652 }; 653 template <> struct pow_func<double> : binary_function<double, double, double> 654 { 655 __device__ __forceinline__ double operator ()(double val, double power) const 656 { 657 return ::pow(val, power); 658 } 659 }; 660 661 // Saturate Cast Functor 662 663 template <typename T, typename D> struct saturate_cast_func : unary_function<T, D> 664 { 665 __device__ __forceinline__ D operator ()(typename TypeTraits<T>::parameter_type v) const 666 { 667 return saturate_cast<D>(v); 668 } 669 }; 670 671 // Threshold Functors 672 673 template <typename T> struct ThreshBinaryFunc : unary_function<T, T> 674 { 675 T thresh; 676 T maxVal; 677 678 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const 679 { 680 return saturate_cast<T>(src > thresh) * maxVal; 681 } 682 }; 683 684 template <typename T> 685 __host__ __device__ ThreshBinaryFunc<T> thresh_binary_func(T thresh, T maxVal) 686 { 687 ThreshBinaryFunc<T> f; 688 f.thresh = thresh; 689 f.maxVal = maxVal; 690 return f; 691 } 692 693 template <typename T> struct ThreshBinaryInvFunc : unary_function<T, T> 694 { 695 T thresh; 696 T maxVal; 697 698 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const 699 { 700 return saturate_cast<T>(src <= thresh) * maxVal; 701 } 702 }; 703 704 template <typename T> 705 __host__ __device__ ThreshBinaryInvFunc<T> thresh_binary_inv_func(T thresh, T maxVal) 706 { 707 ThreshBinaryInvFunc<T> f; 708 f.thresh = thresh; 709 f.maxVal = maxVal; 710 return f; 711 } 712 713 template <typename T> struct ThreshTruncFunc : unary_function<T, T> 714 { 715 T thresh; 716 717 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const 718 { 719 minimum<T> minOp; 720 return minOp(src, thresh); 721 } 722 }; 723 724 template <typename T> 725 __host__ __device__ ThreshTruncFunc<T> thresh_trunc_func(T thresh) 726 { 727 ThreshTruncFunc<T> f; 728 f.thresh = thresh; 729 return f; 730 } 731 732 template <typename T> struct ThreshToZeroFunc : unary_function<T, T> 733 { 734 T thresh; 735 736 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const 737 { 738 return saturate_cast<T>(src > thresh) * src; 739 } 740 }; 741 742 template <typename T> 743 __host__ __device__ ThreshToZeroFunc<T> thresh_to_zero_func(T thresh) 744 { 745 ThreshToZeroFunc<T> f; 746 f.thresh = thresh; 747 return f; 748 } 749 750 template <typename T> struct ThreshToZeroInvFunc : unary_function<T, T> 751 { 752 T thresh; 753 754 __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const 755 { 756 return saturate_cast<T>(src <= thresh) * src; 757 } 758 }; 759 760 template <typename T> 761 __host__ __device__ ThreshToZeroInvFunc<T> thresh_to_zero_inv_func(T thresh) 762 { 763 ThreshToZeroInvFunc<T> f; 764 f.thresh = thresh; 765 return f; 766 } 767 768 // Function Object Adaptors 769 770 template <class Predicate> struct UnaryNegate : unary_function<typename Predicate::argument_type, typename Predicate::result_type> 771 { 772 Predicate pred; 773 774 __device__ __forceinline__ typename Predicate::result_type operator ()( 775 typename TypeTraits<typename Predicate::argument_type>::parameter_type x) const 776 { 777 return !pred(x); 778 } 779 }; 780 781 template <class Predicate> 782 __host__ __device__ UnaryNegate<Predicate> not1(const Predicate& pred) 783 { 784 UnaryNegate<Predicate> n; 785 n.pred = pred; 786 return n; 787 } 788 789 template <class Predicate> struct BinaryNegate : binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, typename Predicate::result_type> 790 { 791 Predicate pred; 792 793 __device__ __forceinline__ typename Predicate::result_type operator ()( 794 typename TypeTraits<typename Predicate::first_argument_type>::parameter_type x, 795 typename TypeTraits<typename Predicate::second_argument_type>::parameter_type y) const 796 { 797 return !pred(x, y); 798 } 799 }; 800 801 template <class Predicate> 802 __host__ __device__ BinaryNegate<Predicate> not2(const Predicate& pred) 803 { 804 BinaryNegate<Predicate> n; 805 n.pred = pred; 806 return n; 807 } 808 809 template <class Op> struct Binder1st : unary_function<typename Op::second_argument_type, typename Op::result_type> 810 { 811 Op op; 812 typename Op::first_argument_type arg1; 813 814 __device__ __forceinline__ typename Op::result_type operator ()( 815 typename TypeTraits<typename Op::second_argument_type>::parameter_type a) const 816 { 817 return op(arg1, a); 818 } 819 }; 820 821 template <class Op> 822 __host__ __device__ Binder1st<Op> bind1st(const Op& op, const typename Op::first_argument_type& arg1) 823 { 824 Binder1st<Op> b; 825 b.op = op; 826 b.arg1 = arg1; 827 return b; 828 } 829 830 template <class Op> struct Binder2nd : unary_function<typename Op::first_argument_type, typename Op::result_type> 831 { 832 Op op; 833 typename Op::second_argument_type arg2; 834 835 __device__ __forceinline__ typename Op::result_type operator ()( 836 typename TypeTraits<typename Op::first_argument_type>::parameter_type a) const 837 { 838 return op(a, arg2); 839 } 840 }; 841 842 template <class Op> 843 __host__ __device__ Binder2nd<Op> bind2nd(const Op& op, const typename Op::second_argument_type& arg2) 844 { 845 Binder2nd<Op> b; 846 b.op = op; 847 b.arg2 = arg2; 848 return b; 849 } 850 851 // Functor Traits 852 853 template <typename F> struct IsUnaryFunction 854 { 855 typedef char Yes; 856 struct No {Yes a[2];}; 857 858 template <typename T, typename D> static Yes check(unary_function<T, D>); 859 static No check(...); 860 861 static F makeF(); 862 863 enum { value = (sizeof(check(makeF())) == sizeof(Yes)) }; 864 }; 865 866 template <typename F> struct IsBinaryFunction 867 { 868 typedef char Yes; 869 struct No {Yes a[2];}; 870 871 template <typename T1, typename T2, typename D> static Yes check(binary_function<T1, T2, D>); 872 static No check(...); 873 874 static F makeF(); 875 876 enum { value = (sizeof(check(makeF())) == sizeof(Yes)) }; 877 }; 878 879 //! @} 880 881 }} 882 883 #endif 884