functional.hpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  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. #pragma once
  44. #ifndef OPENCV_CUDEV_FUNCTIONAL_FUNCTIONAL_HPP
  45. #define OPENCV_CUDEV_FUNCTIONAL_FUNCTIONAL_HPP
  46. #include "../common.hpp"
  47. #include "../util/saturate_cast.hpp"
  48. #include "../util/vec_traits.hpp"
  49. #include "../util/vec_math.hpp"
  50. #include "../util/type_traits.hpp"
  51. namespace cv { namespace cudev {
  52. //! @addtogroup cudev
  53. //! @{
  54. // Function Objects
  55. template <typename _Arg, typename _Result> struct unary_function
  56. {
  57. typedef _Arg argument_type;
  58. typedef _Result result_type;
  59. };
  60. template <typename _Arg1, typename _Arg2, typename _Result> struct binary_function
  61. {
  62. typedef _Arg1 first_argument_type;
  63. typedef _Arg2 second_argument_type;
  64. typedef _Result result_type;
  65. };
  66. // Arithmetic Operations
  67. template <typename T> struct plus : binary_function<T, T, T>
  68. {
  69. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  70. typename TypeTraits<T>::parameter_type b) const
  71. {
  72. return saturate_cast<T>(a + b);
  73. }
  74. };
  75. template <typename T> struct minus : binary_function<T, T, T>
  76. {
  77. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  78. typename TypeTraits<T>::parameter_type b) const
  79. {
  80. return saturate_cast<T>(a - b);
  81. }
  82. };
  83. template <typename T> struct multiplies : binary_function<T, T, T>
  84. {
  85. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  86. typename TypeTraits<T>::parameter_type b) const
  87. {
  88. return saturate_cast<T>(a * b);
  89. }
  90. };
  91. template <typename T> struct divides : binary_function<T, T, T>
  92. {
  93. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  94. typename TypeTraits<T>::parameter_type b) const
  95. {
  96. return saturate_cast<T>(a / b);
  97. }
  98. };
  99. template <typename T> struct modulus : binary_function<T, T, T>
  100. {
  101. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  102. typename TypeTraits<T>::parameter_type b) const
  103. {
  104. return saturate_cast<T>(a % b);
  105. }
  106. };
  107. template <typename T> struct negate : unary_function<T, T>
  108. {
  109. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a) const
  110. {
  111. return saturate_cast<T>(-a);
  112. }
  113. };
  114. // Comparison Operations
  115. template <typename T> struct equal_to : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type>
  116. {
  117. __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type
  118. operator ()(typename TypeTraits<T>::parameter_type a,
  119. typename TypeTraits<T>::parameter_type b) const
  120. {
  121. return a == b;
  122. }
  123. };
  124. template <typename T> struct not_equal_to : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type>
  125. {
  126. __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type
  127. operator ()(typename TypeTraits<T>::parameter_type a,
  128. typename TypeTraits<T>::parameter_type b) const
  129. {
  130. return a != b;
  131. }
  132. };
  133. template <typename T> struct greater : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type>
  134. {
  135. __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type
  136. operator ()(typename TypeTraits<T>::parameter_type a,
  137. typename TypeTraits<T>::parameter_type b) const
  138. {
  139. return a > b;
  140. }
  141. };
  142. template <typename T> struct less : 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. template <typename T> struct greater_equal : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type>
  152. {
  153. __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type
  154. operator ()(typename TypeTraits<T>::parameter_type a,
  155. typename TypeTraits<T>::parameter_type b) const
  156. {
  157. return a >= b;
  158. }
  159. };
  160. template <typename T> struct less_equal : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type>
  161. {
  162. __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type
  163. operator ()(typename TypeTraits<T>::parameter_type a,
  164. typename TypeTraits<T>::parameter_type b) const
  165. {
  166. return a <= b;
  167. }
  168. };
  169. // Logical Operations
  170. template <typename T> struct logical_and : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type>
  171. {
  172. __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type
  173. operator ()(typename TypeTraits<T>::parameter_type a,
  174. typename TypeTraits<T>::parameter_type b) const
  175. {
  176. return a && b;
  177. }
  178. };
  179. template <typename T> struct logical_or : binary_function<T, T, typename MakeVec<uchar, VecTraits<T>::cn>::type>
  180. {
  181. __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type
  182. operator ()(typename TypeTraits<T>::parameter_type a,
  183. typename TypeTraits<T>::parameter_type b) const
  184. {
  185. return a || b;
  186. }
  187. };
  188. template <typename T> struct logical_not : unary_function<T, typename MakeVec<uchar, VecTraits<T>::cn>::type>
  189. {
  190. __device__ __forceinline__ typename MakeVec<uchar, VecTraits<T>::cn>::type
  191. operator ()(typename TypeTraits<T>::parameter_type a) const
  192. {
  193. return !a;
  194. }
  195. };
  196. // Bitwise Operations
  197. template <typename T> struct bit_and : binary_function<T, T, T>
  198. {
  199. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  200. typename TypeTraits<T>::parameter_type b) const
  201. {
  202. return a & b;
  203. }
  204. };
  205. template <typename T> struct bit_or : binary_function<T, T, T>
  206. {
  207. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  208. typename TypeTraits<T>::parameter_type b) const
  209. {
  210. return a | b;
  211. }
  212. };
  213. template <typename T> struct bit_xor : binary_function<T, T, T>
  214. {
  215. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  216. typename TypeTraits<T>::parameter_type b) const
  217. {
  218. return a ^ b;
  219. }
  220. };
  221. template <typename T> struct bit_not : unary_function<T, T>
  222. {
  223. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type v) const
  224. {
  225. return ~v;
  226. }
  227. };
  228. template <typename T> struct bit_lshift : binary_function<T, T, T>
  229. {
  230. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  231. typename TypeTraits<T>::parameter_type b) const
  232. {
  233. return a << b;
  234. }
  235. };
  236. template <typename T> struct bit_rshift : binary_function<T, T, T>
  237. {
  238. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  239. typename TypeTraits<T>::parameter_type b) const
  240. {
  241. return a >> b;
  242. }
  243. };
  244. // Generalized Identity Operations
  245. template <typename T> struct identity : unary_function<T, T>
  246. {
  247. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type x) const
  248. {
  249. return x;
  250. }
  251. };
  252. template <typename T1, typename T2> struct project1st : binary_function<T1, T2, T1>
  253. {
  254. __device__ __forceinline__ T1
  255. operator ()(typename TypeTraits<T1>::parameter_type lhs,
  256. typename TypeTraits<T2>::parameter_type) const
  257. {
  258. return lhs;
  259. }
  260. };
  261. template <typename T1, typename T2> struct project2nd : binary_function<T1, T2, T2>
  262. {
  263. __device__ __forceinline__ T2
  264. operator ()(typename TypeTraits<T1>::parameter_type,
  265. typename TypeTraits<T2>::parameter_type rhs) const
  266. {
  267. return rhs;
  268. }
  269. };
  270. // Min/Max Operations
  271. template <typename T> struct maximum : binary_function<T, T, T>
  272. {
  273. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  274. typename TypeTraits<T>::parameter_type b) const
  275. {
  276. return max(a, b);
  277. }
  278. };
  279. template <typename T> struct minimum : binary_function<T, T, T>
  280. {
  281. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a,
  282. typename TypeTraits<T>::parameter_type b) const
  283. {
  284. return min(a, b);
  285. }
  286. };
  287. #define CV_CUDEV_MINMAX_INST(type, maxop, minop) \
  288. template <> struct maximum<type> : binary_function<type, type, type> \
  289. { \
  290. __device__ __forceinline__ type operator ()(type a, type b) const {return maxop(a, b);} \
  291. }; \
  292. template <> struct minimum<type> : binary_function<type, type, type> \
  293. { \
  294. __device__ __forceinline__ type operator ()(type a, type b) const {return minop(a, b);} \
  295. };
  296. CV_CUDEV_MINMAX_INST(uchar, ::max, ::min)
  297. CV_CUDEV_MINMAX_INST(schar, ::max, ::min)
  298. CV_CUDEV_MINMAX_INST(ushort, ::max, ::min)
  299. CV_CUDEV_MINMAX_INST(short, ::max, ::min)
  300. CV_CUDEV_MINMAX_INST(int, ::max, ::min)
  301. CV_CUDEV_MINMAX_INST(uint, ::max, ::min)
  302. CV_CUDEV_MINMAX_INST(float, ::fmaxf, ::fminf)
  303. CV_CUDEV_MINMAX_INST(double, ::fmax, ::fmin)
  304. #undef CV_CUDEV_MINMAX_INST
  305. // abs_func
  306. template <typename T> struct abs_func : unary_function<T, T>
  307. {
  308. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type x) const
  309. {
  310. return abs(x);
  311. }
  312. };
  313. template <> struct abs_func<uchar> : unary_function<uchar, uchar>
  314. {
  315. __device__ __forceinline__ uchar operator ()(uchar x) const
  316. {
  317. return x;
  318. }
  319. };
  320. template <> struct abs_func<schar> : unary_function<schar, schar>
  321. {
  322. __device__ __forceinline__ schar operator ()(schar x) const
  323. {
  324. return ::abs((int) x);
  325. }
  326. };
  327. template <> struct abs_func<ushort> : unary_function<ushort, ushort>
  328. {
  329. __device__ __forceinline__ ushort operator ()(ushort x) const
  330. {
  331. return x;
  332. }
  333. };
  334. template <> struct abs_func<short> : unary_function<short, short>
  335. {
  336. __device__ __forceinline__ short operator ()(short x) const
  337. {
  338. return ::abs((int) x);
  339. }
  340. };
  341. template <> struct abs_func<uint> : unary_function<uint, uint>
  342. {
  343. __device__ __forceinline__ uint operator ()(uint x) const
  344. {
  345. return x;
  346. }
  347. };
  348. template <> struct abs_func<int> : unary_function<int, int>
  349. {
  350. __device__ __forceinline__ int operator ()(int x) const
  351. {
  352. return ::abs(x);
  353. }
  354. };
  355. template <> struct abs_func<float> : unary_function<float, float>
  356. {
  357. __device__ __forceinline__ float operator ()(float x) const
  358. {
  359. return ::fabsf(x);
  360. }
  361. };
  362. template <> struct abs_func<double> : unary_function<double, double>
  363. {
  364. __device__ __forceinline__ double operator ()(double x) const
  365. {
  366. return ::fabs(x);
  367. }
  368. };
  369. // absdiff_func
  370. template <typename T> struct absdiff_func : binary_function<T, T, T>
  371. {
  372. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type a, typename TypeTraits<T>::parameter_type b) const
  373. {
  374. abs_func<T> f;
  375. return f(a - b);
  376. }
  377. };
  378. // Math functions
  379. template <typename T> struct sqr_func : unary_function<T, T>
  380. {
  381. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type x) const
  382. {
  383. return x * x;
  384. }
  385. };
  386. namespace functional_detail
  387. {
  388. template <typename T> struct FloatType
  389. {
  390. typedef typename MakeVec<
  391. typename LargerType<float, typename VecTraits<T>::elem_type>::type,
  392. VecTraits<T>::cn
  393. >::type type;
  394. };
  395. }
  396. #define CV_CUDEV_UNARY_FUNCTION_INST(name, func) \
  397. template <typename T> struct name ## _func : unary_function<T, typename functional_detail::FloatType<T>::type> \
  398. { \
  399. __device__ __forceinline__ typename functional_detail::FloatType<T>::type operator ()(typename TypeTraits<T>::parameter_type a) const \
  400. { \
  401. return name(a); \
  402. } \
  403. }; \
  404. template <> struct name ## _func<uchar> : unary_function<uchar, float> \
  405. { \
  406. __device__ __forceinline__ float operator ()(uchar a) const \
  407. { \
  408. return func ## f(a); \
  409. } \
  410. }; \
  411. template <> struct name ## _func<schar> : unary_function<schar, float> \
  412. { \
  413. __device__ __forceinline__ float operator ()(schar a) const \
  414. { \
  415. return func ## f(a); \
  416. } \
  417. }; \
  418. template <> struct name ## _func<ushort> : unary_function<ushort, float> \
  419. { \
  420. __device__ __forceinline__ float operator ()(ushort a) const \
  421. { \
  422. return func ## f(a); \
  423. } \
  424. }; \
  425. template <> struct name ## _func<short> : unary_function<short, float> \
  426. { \
  427. __device__ __forceinline__ float operator ()(short a) const \
  428. { \
  429. return func ## f(a); \
  430. } \
  431. }; \
  432. template <> struct name ## _func<uint> : unary_function<uint, float> \
  433. { \
  434. __device__ __forceinline__ float operator ()(uint a) const \
  435. { \
  436. return func ## f(a); \
  437. } \
  438. }; \
  439. template <> struct name ## _func<int> : unary_function<int, float> \
  440. { \
  441. __device__ __forceinline__ float operator ()(int a) const \
  442. { \
  443. return func ## f(a); \
  444. } \
  445. }; \
  446. template <> struct name ## _func<float> : unary_function<float, float> \
  447. { \
  448. __device__ __forceinline__ float operator ()(float a) const \
  449. { \
  450. return func ## f(a); \
  451. } \
  452. }; \
  453. template <> struct name ## _func<double> : unary_function<double, double> \
  454. { \
  455. __device__ __forceinline__ double operator ()(double a) const \
  456. { \
  457. return func(a); \
  458. } \
  459. };
  460. CV_CUDEV_UNARY_FUNCTION_INST(sqrt, ::sqrt)
  461. CV_CUDEV_UNARY_FUNCTION_INST(exp, ::exp)
  462. CV_CUDEV_UNARY_FUNCTION_INST(exp2, ::exp2)
  463. CV_CUDEV_UNARY_FUNCTION_INST(exp10, ::exp10)
  464. CV_CUDEV_UNARY_FUNCTION_INST(log, ::log)
  465. CV_CUDEV_UNARY_FUNCTION_INST(log2, ::log2)
  466. CV_CUDEV_UNARY_FUNCTION_INST(log10, ::log10)
  467. CV_CUDEV_UNARY_FUNCTION_INST(sin, ::sin)
  468. CV_CUDEV_UNARY_FUNCTION_INST(cos, ::cos)
  469. CV_CUDEV_UNARY_FUNCTION_INST(tan, ::tan)
  470. CV_CUDEV_UNARY_FUNCTION_INST(asin, ::asin)
  471. CV_CUDEV_UNARY_FUNCTION_INST(acos, ::acos)
  472. CV_CUDEV_UNARY_FUNCTION_INST(atan, ::atan)
  473. CV_CUDEV_UNARY_FUNCTION_INST(sinh, ::sinh)
  474. CV_CUDEV_UNARY_FUNCTION_INST(cosh, ::cosh)
  475. CV_CUDEV_UNARY_FUNCTION_INST(tanh, ::tanh)
  476. CV_CUDEV_UNARY_FUNCTION_INST(asinh, ::asinh)
  477. CV_CUDEV_UNARY_FUNCTION_INST(acosh, ::acosh)
  478. CV_CUDEV_UNARY_FUNCTION_INST(atanh, ::atanh)
  479. #undef CV_CUDEV_UNARY_FUNCTION_INST
  480. #define CV_CUDEV_BINARY_FUNCTION_INST(name, func) \
  481. template <typename T> struct name ## _func : binary_function<T, T, typename functional_detail::FloatType<T>::type> \
  482. { \
  483. __device__ __forceinline__ typename functional_detail::FloatType<T>::type operator ()(typename TypeTraits<T>::parameter_type a, typename TypeTraits<T>::parameter_type b) const \
  484. { \
  485. return name(a, b); \
  486. } \
  487. }; \
  488. template <> struct name ## _func<uchar> : binary_function<uchar, uchar, float> \
  489. { \
  490. __device__ __forceinline__ float operator ()(uchar a, uchar b) const \
  491. { \
  492. return func ## f(a, b); \
  493. } \
  494. }; \
  495. template <> struct name ## _func<schar> : binary_function<schar, schar, float> \
  496. { \
  497. __device__ __forceinline__ float operator ()(schar a, schar b) const \
  498. { \
  499. return func ## f(a, b); \
  500. } \
  501. }; \
  502. template <> struct name ## _func<ushort> : binary_function<ushort, ushort, float> \
  503. { \
  504. __device__ __forceinline__ float operator ()(ushort a, ushort b) const \
  505. { \
  506. return func ## f(a, b); \
  507. } \
  508. }; \
  509. template <> struct name ## _func<short> : binary_function<short, short, float> \
  510. { \
  511. __device__ __forceinline__ float operator ()(short a, short b) const \
  512. { \
  513. return func ## f(a, b); \
  514. } \
  515. }; \
  516. template <> struct name ## _func<uint> : binary_function<uint, uint, float> \
  517. { \
  518. __device__ __forceinline__ float operator ()(uint a, uint b) const \
  519. { \
  520. return func ## f(a, b); \
  521. } \
  522. }; \
  523. template <> struct name ## _func<int> : binary_function<int, int, float> \
  524. { \
  525. __device__ __forceinline__ float operator ()(int a, int b) const \
  526. { \
  527. return func ## f(a, b); \
  528. } \
  529. }; \
  530. template <> struct name ## _func<float> : binary_function<float, float, float> \
  531. { \
  532. __device__ __forceinline__ float operator ()(float a, float b) const \
  533. { \
  534. return func ## f(a, b); \
  535. } \
  536. }; \
  537. template <> struct name ## _func<double> : binary_function<double, double, double> \
  538. { \
  539. __device__ __forceinline__ double operator ()(double a, double b) const \
  540. { \
  541. return func(a, b); \
  542. } \
  543. };
  544. CV_CUDEV_BINARY_FUNCTION_INST(hypot, ::hypot)
  545. CV_CUDEV_BINARY_FUNCTION_INST(atan2, ::atan2)
  546. #undef CV_CUDEV_BINARY_FUNCTION_INST
  547. template <typename T> struct magnitude_func : binary_function<T, T, typename functional_detail::FloatType<T>::type>
  548. {
  549. __device__ __forceinline__ typename functional_detail::FloatType<T>::type operator ()(typename TypeTraits<T>::parameter_type a, typename TypeTraits<T>::parameter_type b) const
  550. {
  551. sqrt_func<typename functional_detail::FloatType<T>::type> f;
  552. return f(a * a + b * b);
  553. }
  554. };
  555. template <typename T> struct magnitude_sqr_func : binary_function<T, T, typename functional_detail::FloatType<T>::type>
  556. {
  557. __device__ __forceinline__ typename functional_detail::FloatType<T>::type operator ()(typename TypeTraits<T>::parameter_type a, typename TypeTraits<T>::parameter_type b) const
  558. {
  559. return a * a + b * b;
  560. }
  561. };
  562. template <typename T, bool angleInDegrees> struct direction_func : binary_function<T, T, T>
  563. {
  564. __device__ T operator ()(T x, T y) const
  565. {
  566. atan2_func<T> f;
  567. typename atan2_func<T>::result_type angle = f(y, x);
  568. angle += (angle < 0) * (2.0f * CV_PI_F);
  569. if (angleInDegrees)
  570. angle *= (180.0f / CV_PI_F);
  571. return saturate_cast<T>(angle);
  572. }
  573. };
  574. template <typename T> struct pow_func : binary_function<T, float, float>
  575. {
  576. __device__ __forceinline__ float operator ()(T val, float power) const
  577. {
  578. return ::powf(val, power);
  579. }
  580. };
  581. template <> struct pow_func<double> : binary_function<double, double, double>
  582. {
  583. __device__ __forceinline__ double operator ()(double val, double power) const
  584. {
  585. return ::pow(val, power);
  586. }
  587. };
  588. // Saturate Cast Functor
  589. template <typename T, typename D> struct saturate_cast_func : unary_function<T, D>
  590. {
  591. __device__ __forceinline__ D operator ()(typename TypeTraits<T>::parameter_type v) const
  592. {
  593. return saturate_cast<D>(v);
  594. }
  595. };
  596. // Convert Fp16 dummy
  597. template <typename T, typename D> struct saturate_cast_fp16_func;
  598. // Convert Fp16 from Fp32
  599. template <> struct saturate_cast_fp16_func<float, short> : unary_function<float, short>
  600. {
  601. __device__ __forceinline__ short operator ()(float v) const
  602. {
  603. return cast_fp16<float, short>(v);
  604. }
  605. };
  606. // Convert Fp16 to Fp32
  607. template <> struct saturate_cast_fp16_func<short, float> : unary_function<short, float>
  608. {
  609. __device__ __forceinline__ float operator ()(short v) const
  610. {
  611. return cast_fp16<short, float>(v);
  612. }
  613. };
  614. // Threshold Functors
  615. template <typename T> struct ThreshBinaryFunc : unary_function<T, T>
  616. {
  617. T thresh;
  618. T maxVal;
  619. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const
  620. {
  621. return saturate_cast<T>(src > thresh) * maxVal;
  622. }
  623. };
  624. template <typename T>
  625. __host__ __device__ ThreshBinaryFunc<T> thresh_binary_func(T thresh, T maxVal)
  626. {
  627. ThreshBinaryFunc<T> f;
  628. f.thresh = thresh;
  629. f.maxVal = maxVal;
  630. return f;
  631. }
  632. template <typename T> struct ThreshBinaryInvFunc : unary_function<T, T>
  633. {
  634. T thresh;
  635. T maxVal;
  636. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const
  637. {
  638. return saturate_cast<T>(src <= thresh) * maxVal;
  639. }
  640. };
  641. template <typename T>
  642. __host__ __device__ ThreshBinaryInvFunc<T> thresh_binary_inv_func(T thresh, T maxVal)
  643. {
  644. ThreshBinaryInvFunc<T> f;
  645. f.thresh = thresh;
  646. f.maxVal = maxVal;
  647. return f;
  648. }
  649. template <typename T> struct ThreshTruncFunc : unary_function<T, T>
  650. {
  651. T thresh;
  652. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const
  653. {
  654. minimum<T> minOp;
  655. return minOp(src, thresh);
  656. }
  657. };
  658. template <typename T>
  659. __host__ __device__ ThreshTruncFunc<T> thresh_trunc_func(T thresh)
  660. {
  661. ThreshTruncFunc<T> f;
  662. f.thresh = thresh;
  663. return f;
  664. }
  665. template <typename T> struct ThreshToZeroFunc : unary_function<T, T>
  666. {
  667. T thresh;
  668. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const
  669. {
  670. return saturate_cast<T>(src > thresh) * src;
  671. }
  672. };
  673. template <typename T>
  674. __host__ __device__ ThreshToZeroFunc<T> thresh_to_zero_func(T thresh)
  675. {
  676. ThreshToZeroFunc<T> f;
  677. f.thresh = thresh;
  678. return f;
  679. }
  680. template <typename T> struct ThreshToZeroInvFunc : unary_function<T, T>
  681. {
  682. T thresh;
  683. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::parameter_type src) const
  684. {
  685. return saturate_cast<T>(src <= thresh) * src;
  686. }
  687. };
  688. template <typename T>
  689. __host__ __device__ ThreshToZeroInvFunc<T> thresh_to_zero_inv_func(T thresh)
  690. {
  691. ThreshToZeroInvFunc<T> f;
  692. f.thresh = thresh;
  693. return f;
  694. }
  695. // Function Object Adaptors
  696. template <class Predicate> struct UnaryNegate : unary_function<typename Predicate::argument_type, typename Predicate::result_type>
  697. {
  698. Predicate pred;
  699. __device__ __forceinline__ typename Predicate::result_type operator ()(
  700. typename TypeTraits<typename Predicate::argument_type>::parameter_type x) const
  701. {
  702. return !pred(x);
  703. }
  704. };
  705. template <class Predicate>
  706. __host__ __device__ UnaryNegate<Predicate> not1(const Predicate& pred)
  707. {
  708. UnaryNegate<Predicate> n;
  709. n.pred = pred;
  710. return n;
  711. }
  712. template <class Predicate> struct BinaryNegate : binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, typename Predicate::result_type>
  713. {
  714. Predicate pred;
  715. __device__ __forceinline__ typename Predicate::result_type operator ()(
  716. typename TypeTraits<typename Predicate::first_argument_type>::parameter_type x,
  717. typename TypeTraits<typename Predicate::second_argument_type>::parameter_type y) const
  718. {
  719. return !pred(x, y);
  720. }
  721. };
  722. template <class Predicate>
  723. __host__ __device__ BinaryNegate<Predicate> not2(const Predicate& pred)
  724. {
  725. BinaryNegate<Predicate> n;
  726. n.pred = pred;
  727. return n;
  728. }
  729. template <class Op> struct Binder1st : unary_function<typename Op::second_argument_type, typename Op::result_type>
  730. {
  731. Op op;
  732. typename Op::first_argument_type arg1;
  733. __device__ __forceinline__ typename Op::result_type operator ()(
  734. typename TypeTraits<typename Op::second_argument_type>::parameter_type a) const
  735. {
  736. return op(arg1, a);
  737. }
  738. };
  739. template <class Op>
  740. __host__ __device__ Binder1st<Op> bind1st(const Op& op, const typename Op::first_argument_type& arg1)
  741. {
  742. Binder1st<Op> b;
  743. b.op = op;
  744. b.arg1 = arg1;
  745. return b;
  746. }
  747. template <class Op> struct Binder2nd : unary_function<typename Op::first_argument_type, typename Op::result_type>
  748. {
  749. Op op;
  750. typename Op::second_argument_type arg2;
  751. __device__ __forceinline__ typename Op::result_type operator ()(
  752. typename TypeTraits<typename Op::first_argument_type>::parameter_type a) const
  753. {
  754. return op(a, arg2);
  755. }
  756. };
  757. template <class Op>
  758. __host__ __device__ Binder2nd<Op> bind2nd(const Op& op, const typename Op::second_argument_type& arg2)
  759. {
  760. Binder2nd<Op> b;
  761. b.op = op;
  762. b.arg2 = arg2;
  763. return b;
  764. }
  765. // Functor Traits
  766. template <typename F> struct IsUnaryFunction
  767. {
  768. typedef char Yes;
  769. struct No {Yes a[2];};
  770. template <typename T, typename D> static Yes check(unary_function<T, D>);
  771. static No check(...);
  772. static F makeF();
  773. enum { value = (sizeof(check(makeF())) == sizeof(Yes)) };
  774. };
  775. template <typename F> struct IsBinaryFunction
  776. {
  777. typedef char Yes;
  778. struct No {Yes a[2];};
  779. template <typename T1, typename T2, typename D> static Yes check(binary_function<T1, T2, D>);
  780. static No check(...);
  781. static F makeF();
  782. enum { value = (sizeof(check(makeF())) == sizeof(Yes)) };
  783. };
  784. //! @}
  785. }}
  786. #endif