00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef __OPENCV_GPU_VECMATH_HPP__
00044 #define __OPENCV_GPU_VECMATH_HPP__
00045
00046 #include "saturate_cast.hpp"
00047 #include "vec_traits.hpp"
00048 #include "functional.hpp"
00049
00050 namespace cv { namespace gpu { namespace device
00051 {
00052 namespace vec_math_detail
00053 {
00054 template <int cn, typename VecD> struct SatCastHelper;
00055 template <typename VecD> struct SatCastHelper<1, VecD>
00056 {
00057 template <typename VecS> static __device__ __forceinline__ VecD cast(const VecS& v)
00058 {
00059 typedef typename VecTraits<VecD>::elem_type D;
00060 return VecTraits<VecD>::make(saturate_cast<D>(v.x));
00061 }
00062 };
00063 template <typename VecD> struct SatCastHelper<2, VecD>
00064 {
00065 template <typename VecS> static __device__ __forceinline__ VecD cast(const VecS& v)
00066 {
00067 typedef typename VecTraits<VecD>::elem_type D;
00068 return VecTraits<VecD>::make(saturate_cast<D>(v.x), saturate_cast<D>(v.y));
00069 }
00070 };
00071 template <typename VecD> struct SatCastHelper<3, VecD>
00072 {
00073 template <typename VecS> static __device__ __forceinline__ VecD cast(const VecS& v)
00074 {
00075 typedef typename VecTraits<VecD>::elem_type D;
00076 return VecTraits<VecD>::make(saturate_cast<D>(v.x), saturate_cast<D>(v.y), saturate_cast<D>(v.z));
00077 }
00078 };
00079 template <typename VecD> struct SatCastHelper<4, VecD>
00080 {
00081 template <typename VecS> static __device__ __forceinline__ VecD cast(const VecS& v)
00082 {
00083 typedef typename VecTraits<VecD>::elem_type D;
00084 return VecTraits<VecD>::make(saturate_cast<D>(v.x), saturate_cast<D>(v.y), saturate_cast<D>(v.z), saturate_cast<D>(v.w));
00085 }
00086 };
00087
00088 template <typename VecD, typename VecS> static __device__ __forceinline__ VecD saturate_cast_caller(const VecS& v)
00089 {
00090 return SatCastHelper<VecTraits<VecD>::cn, VecD>::cast(v);
00091 }
00092 }
00093
00094 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uchar1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00095 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const char1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00096 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const ushort1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00097 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const short1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00098 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uint1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00099 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const int1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00100 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const float1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00101 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const double1& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00102
00103 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uchar2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00104 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const char2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00105 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const ushort2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00106 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const short2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00107 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uint2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00108 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const int2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00109 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const float2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00110 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const double2& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00111
00112 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uchar3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00113 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const char3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00114 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const ushort3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00115 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const short3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00116 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uint3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00117 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const int3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00118 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const float3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00119 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const double3& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00120
00121 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uchar4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00122 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const char4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00123 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const ushort4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00124 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const short4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00125 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const uint4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00126 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const int4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00127 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const float4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00128 template<typename _Tp> static __device__ __forceinline__ _Tp saturate_cast(const double4& v) {return vec_math_detail::saturate_cast_caller<_Tp>(v);}
00129
00130 #define OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, op, func) \
00131 __device__ __forceinline__ TypeVec<func<type>::result_type, 1>::vec_type op(const type ## 1 & a) \
00132 { \
00133 func<type> f; \
00134 return VecTraits<TypeVec<func<type>::result_type, 1>::vec_type>::make(f(a.x)); \
00135 } \
00136 __device__ __forceinline__ TypeVec<func<type>::result_type, 2>::vec_type op(const type ## 2 & a) \
00137 { \
00138 func<type> f; \
00139 return VecTraits<TypeVec<func<type>::result_type, 2>::vec_type>::make(f(a.x), f(a.y)); \
00140 } \
00141 __device__ __forceinline__ TypeVec<func<type>::result_type, 3>::vec_type op(const type ## 3 & a) \
00142 { \
00143 func<type> f; \
00144 return VecTraits<TypeVec<func<type>::result_type, 3>::vec_type>::make(f(a.x), f(a.y), f(a.z)); \
00145 } \
00146 __device__ __forceinline__ TypeVec<func<type>::result_type, 4>::vec_type op(const type ## 4 & a) \
00147 { \
00148 func<type> f; \
00149 return VecTraits<TypeVec<func<type>::result_type, 4>::vec_type>::make(f(a.x), f(a.y), f(a.z), f(a.w)); \
00150 }
00151
00152 namespace vec_math_detail
00153 {
00154 template <typename T1, typename T2> struct BinOpTraits
00155 {
00156 typedef int argument_type;
00157 };
00158 template <typename T> struct BinOpTraits<T, T>
00159 {
00160 typedef T argument_type;
00161 };
00162 template <typename T> struct BinOpTraits<T, double>
00163 {
00164 typedef double argument_type;
00165 };
00166 template <typename T> struct BinOpTraits<double, T>
00167 {
00168 typedef double argument_type;
00169 };
00170 template <> struct BinOpTraits<double, double>
00171 {
00172 typedef double argument_type;
00173 };
00174 template <typename T> struct BinOpTraits<T, float>
00175 {
00176 typedef float argument_type;
00177 };
00178 template <typename T> struct BinOpTraits<float, T>
00179 {
00180 typedef float argument_type;
00181 };
00182 template <> struct BinOpTraits<float, float>
00183 {
00184 typedef float argument_type;
00185 };
00186 template <> struct BinOpTraits<double, float>
00187 {
00188 typedef double argument_type;
00189 };
00190 template <> struct BinOpTraits<float, double>
00191 {
00192 typedef double argument_type;
00193 };
00194 }
00195
00196 #define OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, op, func) \
00197 __device__ __forceinline__ TypeVec<func<type>::result_type, 1>::vec_type op(const type ## 1 & a, const type ## 1 & b) \
00198 { \
00199 func<type> f; \
00200 return VecTraits<TypeVec<func<type>::result_type, 1>::vec_type>::make(f(a.x, b.x)); \
00201 } \
00202 template <typename T> \
00203 __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 1>::vec_type op(const type ## 1 & v, T s) \
00204 { \
00205 func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00206 return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 1>::vec_type>::make(f(v.x, s)); \
00207 } \
00208 template <typename T> \
00209 __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 1>::vec_type op(T s, const type ## 1 & v) \
00210 { \
00211 func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00212 return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 1>::vec_type>::make(f(s, v.x)); \
00213 } \
00214 __device__ __forceinline__ TypeVec<func<type>::result_type, 2>::vec_type op(const type ## 2 & a, const type ## 2 & b) \
00215 { \
00216 func<type> f; \
00217 return VecTraits<TypeVec<func<type>::result_type, 2>::vec_type>::make(f(a.x, b.x), f(a.y, b.y)); \
00218 } \
00219 template <typename T> \
00220 __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 2>::vec_type op(const type ## 2 & v, T s) \
00221 { \
00222 func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00223 return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 2>::vec_type>::make(f(v.x, s), f(v.y, s)); \
00224 } \
00225 template <typename T> \
00226 __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 2>::vec_type op(T s, const type ## 2 & v) \
00227 { \
00228 func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00229 return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 2>::vec_type>::make(f(s, v.x), f(s, v.y)); \
00230 } \
00231 __device__ __forceinline__ TypeVec<func<type>::result_type, 3>::vec_type op(const type ## 3 & a, const type ## 3 & b) \
00232 { \
00233 func<type> f; \
00234 return VecTraits<TypeVec<func<type>::result_type, 3>::vec_type>::make(f(a.x, b.x), f(a.y, b.y), f(a.z, b.z)); \
00235 } \
00236 template <typename T> \
00237 __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 3>::vec_type op(const type ## 3 & v, T s) \
00238 { \
00239 func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00240 return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 3>::vec_type>::make(f(v.x, s), f(v.y, s), f(v.z, s)); \
00241 } \
00242 template <typename T> \
00243 __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 3>::vec_type op(T s, const type ## 3 & v) \
00244 { \
00245 func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00246 return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 3>::vec_type>::make(f(s, v.x), f(s, v.y), f(s, v.z)); \
00247 } \
00248 __device__ __forceinline__ TypeVec<func<type>::result_type, 4>::vec_type op(const type ## 4 & a, const type ## 4 & b) \
00249 { \
00250 func<type> f; \
00251 return VecTraits<TypeVec<func<type>::result_type, 4>::vec_type>::make(f(a.x, b.x), f(a.y, b.y), f(a.z, b.z), f(a.w, b.w)); \
00252 } \
00253 template <typename T> \
00254 __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 4>::vec_type op(const type ## 4 & v, T s) \
00255 { \
00256 func<typename vec_math_detail::BinOpTraits<type, T>::argument_type> f; \
00257 return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 4>::vec_type>::make(f(v.x, s), f(v.y, s), f(v.z, s), f(v.w, s)); \
00258 } \
00259 template <typename T> \
00260 __device__ __forceinline__ typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 4>::vec_type op(T s, const type ## 4 & v) \
00261 { \
00262 func<typename vec_math_detail::BinOpTraits<T, type>::argument_type> f; \
00263 return VecTraits<typename TypeVec<typename func<typename vec_math_detail::BinOpTraits<type, T>::argument_type>::result_type, 4>::vec_type>::make(f(s, v.x), f(s, v.y), f(s, v.z), f(s, v.w)); \
00264 }
00265
00266 #define OPENCV_GPU_IMPLEMENT_VEC_OP(type) \
00267 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator +, plus) \
00268 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator -, minus) \
00269 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator *, multiplies) \
00270 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator /, divides) \
00271 OPENCV_GPU_IMPLEMENT_VEC_UNOP (type, operator -, negate) \
00272 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator ==, equal_to) \
00273 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator !=, not_equal_to) \
00274 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator > , greater) \
00275 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator < , less) \
00276 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator >=, greater_equal) \
00277 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator <=, less_equal) \
00278 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator &&, logical_and) \
00279 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator ||, logical_or) \
00280 OPENCV_GPU_IMPLEMENT_VEC_UNOP (type, operator ! , logical_not) \
00281 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, max, maximum) \
00282 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, min, minimum) \
00283 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, fabs, fabs_func) \
00284 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, sqrt, sqrt_func) \
00285 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, exp, exp_func) \
00286 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, exp2, exp2_func) \
00287 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, exp10, exp10_func) \
00288 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, log, log_func) \
00289 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, log2, log2_func) \
00290 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, log10, log10_func) \
00291 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, sin, sin_func) \
00292 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, cos, cos_func) \
00293 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, tan, tan_func) \
00294 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, asin, asin_func) \
00295 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, acos, acos_func) \
00296 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, atan, atan_func) \
00297 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, sinh, sinh_func) \
00298 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, cosh, cosh_func) \
00299 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, tanh, tanh_func) \
00300 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, asinh, asinh_func) \
00301 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, acosh, acosh_func) \
00302 OPENCV_GPU_IMPLEMENT_VEC_UNOP(type, atanh, atanh_func) \
00303 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, hypot, hypot_func) \
00304 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, atan2, atan2_func) \
00305 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, pow, pow_func) \
00306 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, hypot_sqr, hypot_sqr_func)
00307
00308 #define OPENCV_GPU_IMPLEMENT_VEC_INT_OP(type) \
00309 OPENCV_GPU_IMPLEMENT_VEC_OP(type) \
00310 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator &, bit_and) \
00311 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator |, bit_or) \
00312 OPENCV_GPU_IMPLEMENT_VEC_BINOP(type, operator ^, bit_xor) \
00313 OPENCV_GPU_IMPLEMENT_VEC_UNOP (type, operator ~, bit_not)
00314
00315 OPENCV_GPU_IMPLEMENT_VEC_INT_OP(uchar)
00316 OPENCV_GPU_IMPLEMENT_VEC_INT_OP(char)
00317 OPENCV_GPU_IMPLEMENT_VEC_INT_OP(ushort)
00318 OPENCV_GPU_IMPLEMENT_VEC_INT_OP(short)
00319 OPENCV_GPU_IMPLEMENT_VEC_INT_OP(int)
00320 OPENCV_GPU_IMPLEMENT_VEC_INT_OP(uint)
00321 OPENCV_GPU_IMPLEMENT_VEC_OP(float)
00322 OPENCV_GPU_IMPLEMENT_VEC_OP(double)
00323
00324 #undef OPENCV_GPU_IMPLEMENT_VEC_UNOP
00325 #undef OPENCV_GPU_IMPLEMENT_VEC_BINOP
00326 #undef OPENCV_GPU_IMPLEMENT_VEC_OP
00327 #undef OPENCV_GPU_IMPLEMENT_VEC_INT_OP
00328 }}}
00329
00330 #endif // __OPENCV_GPU_VECMATH_HPP__