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_FILTERS_HPP__
00044 #define __OPENCV_GPU_FILTERS_HPP__
00045
00046 #include "saturate_cast.hpp"
00047 #include "vec_traits.hpp"
00048 #include "vec_math.hpp"
00049 #include "type_traits.hpp"
00050
00051 namespace cv { namespace gpu { namespace device
00052 {
00053 template <typename Ptr2D> struct PointFilter
00054 {
00055 typedef typename Ptr2D::elem_type elem_type;
00056 typedef float index_type;
00057
00058 explicit __host__ __device__ __forceinline__ PointFilter(const Ptr2D& src_, float fx = 0.f, float fy = 0.f)
00059 : src(src_)
00060 {
00061 (void)fx;
00062 (void)fy;
00063 }
00064
00065 __device__ __forceinline__ elem_type operator ()(float y, float x) const
00066 {
00067 return src(__float2int_rz(y), __float2int_rz(x));
00068 }
00069
00070 const Ptr2D src;
00071 };
00072
00073 template <typename Ptr2D> struct LinearFilter
00074 {
00075 typedef typename Ptr2D::elem_type elem_type;
00076 typedef float index_type;
00077
00078 explicit __host__ __device__ __forceinline__ LinearFilter(const Ptr2D& src_, float fx = 0.f, float fy = 0.f)
00079 : src(src_)
00080 {
00081 (void)fx;
00082 (void)fy;
00083 }
00084 __device__ __forceinline__ elem_type operator ()(float y, float x) const
00085 {
00086 typedef typename TypeVec<float, VecTraits<elem_type>::cn>::vec_type work_type;
00087
00088 work_type out = VecTraits<work_type>::all(0);
00089
00090 const int x1 = __float2int_rd(x);
00091 const int y1 = __float2int_rd(y);
00092 const int x2 = x1 + 1;
00093 const int y2 = y1 + 1;
00094
00095 elem_type src_reg = src(y1, x1);
00096 out = out + src_reg * ((x2 - x) * (y2 - y));
00097
00098 src_reg = src(y1, x2);
00099 out = out + src_reg * ((x - x1) * (y2 - y));
00100
00101 src_reg = src(y2, x1);
00102 out = out + src_reg * ((x2 - x) * (y - y1));
00103
00104 src_reg = src(y2, x2);
00105 out = out + src_reg * ((x - x1) * (y - y1));
00106
00107 return saturate_cast<elem_type>(out);
00108 }
00109
00110 const Ptr2D src;
00111 };
00112
00113 template <typename Ptr2D> struct CubicFilter
00114 {
00115 typedef typename Ptr2D::elem_type elem_type;
00116 typedef float index_type;
00117 typedef typename TypeVec<float, VecTraits<elem_type>::cn>::vec_type work_type;
00118
00119 explicit __host__ __device__ __forceinline__ CubicFilter(const Ptr2D& src_, float fx = 0.f, float fy = 0.f)
00120 : src(src_)
00121 {
00122 (void)fx;
00123 (void)fy;
00124 }
00125
00126 static __device__ __forceinline__ float bicubicCoeff(float x_)
00127 {
00128 float x = fabsf(x_);
00129 if (x <= 1.0f)
00130 {
00131 return x * x * (1.5f * x - 2.5f) + 1.0f;
00132 }
00133 else if (x < 2.0f)
00134 {
00135 return x * (x * (-0.5f * x + 2.5f) - 4.0f) + 2.0f;
00136 }
00137 else
00138 {
00139 return 0.0f;
00140 }
00141 }
00142
00143 __device__ elem_type operator ()(float y, float x) const
00144 {
00145 const float xmin = ::ceilf(x - 2.0f);
00146 const float xmax = ::floorf(x + 2.0f);
00147
00148 const float ymin = ::ceilf(y - 2.0f);
00149 const float ymax = ::floorf(y + 2.0f);
00150
00151 work_type sum = VecTraits<work_type>::all(0);
00152 float wsum = 0.0f;
00153
00154 for (float cy = ymin; cy <= ymax; cy += 1.0f)
00155 {
00156 for (float cx = xmin; cx <= xmax; cx += 1.0f)
00157 {
00158 const float w = bicubicCoeff(x - cx) * bicubicCoeff(y - cy);
00159 sum = sum + w * src(__float2int_rd(cy), __float2int_rd(cx));
00160 wsum += w;
00161 }
00162 }
00163
00164 work_type res = (!wsum)? VecTraits<work_type>::all(0) : sum / wsum;
00165
00166 return saturate_cast<elem_type>(res);
00167 }
00168
00169 const Ptr2D src;
00170 };
00171
00172 template <typename Ptr2D> struct IntegerAreaFilter
00173 {
00174 typedef typename Ptr2D::elem_type elem_type;
00175 typedef float index_type;
00176
00177 explicit __host__ __device__ __forceinline__ IntegerAreaFilter(const Ptr2D& src_, float scale_x_, float scale_y_)
00178 : src(src_), scale_x(scale_x_), scale_y(scale_y_), scale(1.f / (scale_x * scale_y)) {}
00179
00180 __device__ __forceinline__ elem_type operator ()(float y, float x) const
00181 {
00182 float fsx1 = x * scale_x;
00183 float fsx2 = fsx1 + scale_x;
00184
00185 int sx1 = __float2int_ru(fsx1);
00186 int sx2 = __float2int_rd(fsx2);
00187
00188 float fsy1 = y * scale_y;
00189 float fsy2 = fsy1 + scale_y;
00190
00191 int sy1 = __float2int_ru(fsy1);
00192 int sy2 = __float2int_rd(fsy2);
00193
00194 typedef typename TypeVec<float, VecTraits<elem_type>::cn>::vec_type work_type;
00195 work_type out = VecTraits<work_type>::all(0.f);
00196
00197 for(int dy = sy1; dy < sy2; ++dy)
00198 for(int dx = sx1; dx < sx2; ++dx)
00199 {
00200 out = out + src(dy, dx) * scale;
00201 }
00202
00203 return saturate_cast<elem_type>(out);
00204 }
00205
00206 const Ptr2D src;
00207 float scale_x, scale_y ,scale;
00208 };
00209
00210 template <typename Ptr2D> struct AreaFilter
00211 {
00212 typedef typename Ptr2D::elem_type elem_type;
00213 typedef float index_type;
00214
00215 explicit __host__ __device__ __forceinline__ AreaFilter(const Ptr2D& src_, float scale_x_, float scale_y_)
00216 : src(src_), scale_x(scale_x_), scale_y(scale_y_){}
00217
00218 __device__ __forceinline__ elem_type operator ()(float y, float x) const
00219 {
00220 float fsx1 = x * scale_x;
00221 float fsx2 = fsx1 + scale_x;
00222
00223 int sx1 = __float2int_ru(fsx1);
00224 int sx2 = __float2int_rd(fsx2);
00225
00226 float fsy1 = y * scale_y;
00227 float fsy2 = fsy1 + scale_y;
00228
00229 int sy1 = __float2int_ru(fsy1);
00230 int sy2 = __float2int_rd(fsy2);
00231
00232 float scale = 1.f / (fminf(scale_x, src.width - fsx1) * fminf(scale_y, src.height - fsy1));
00233
00234 typedef typename TypeVec<float, VecTraits<elem_type>::cn>::vec_type work_type;
00235 work_type out = VecTraits<work_type>::all(0.f);
00236
00237 for (int dy = sy1; dy < sy2; ++dy)
00238 {
00239 for (int dx = sx1; dx < sx2; ++dx)
00240 out = out + src(dy, dx) * scale;
00241
00242 if (sx1 > fsx1)
00243 out = out + src(dy, (sx1 -1) ) * ((sx1 - fsx1) * scale);
00244
00245 if (sx2 < fsx2)
00246 out = out + src(dy, sx2) * ((fsx2 -sx2) * scale);
00247 }
00248
00249 if (sy1 > fsy1)
00250 for (int dx = sx1; dx < sx2; ++dx)
00251 out = out + src( (sy1 - 1) , dx) * ((sy1 -fsy1) * scale);
00252
00253 if (sy2 < fsy2)
00254 for (int dx = sx1; dx < sx2; ++dx)
00255 out = out + src(sy2, dx) * ((fsy2 -sy2) * scale);
00256
00257 if ((sy1 > fsy1) && (sx1 > fsx1))
00258 out = out + src( (sy1 - 1) , (sx1 - 1)) * ((sy1 -fsy1) * (sx1 -fsx1) * scale);
00259
00260 if ((sy1 > fsy1) && (sx2 < fsx2))
00261 out = out + src( (sy1 - 1) , sx2) * ((sy1 -fsy1) * (fsx2 -sx2) * scale);
00262
00263 if ((sy2 < fsy2) && (sx2 < fsx2))
00264 out = out + src(sy2, sx2) * ((fsy2 -sy2) * (fsx2 -sx2) * scale);
00265
00266 if ((sy2 < fsy2) && (sx1 > fsx1))
00267 out = out + src(sy2, (sx1 - 1)) * ((fsy2 -sy2) * (sx1 -fsx1) * scale);
00268
00269 return saturate_cast<elem_type>(out);
00270 }
00271
00272 const Ptr2D src;
00273 float scale_x, scale_y;
00274 int width, haight;
00275 };
00276 }}}
00277
00278 #endif // __OPENCV_GPU_FILTERS_HPP__