OpenCV 2.4.8 components for OpenCVgrabber.
[mmanager-3rdparty.git] / OpenCV2.4.8 / build / include / opencv2 / gpu / device / filters.hpp
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 #ifndef __OPENCV_GPU_FILTERS_HPP__
44 #define __OPENCV_GPU_FILTERS_HPP__
45
46 #include "saturate_cast.hpp"
47 #include "vec_traits.hpp"
48 #include "vec_math.hpp"
49 #include "type_traits.hpp"
50
51 namespace cv { namespace gpu { namespace device
52 {
53     template <typename Ptr2D> struct PointFilter
54     {
55         typedef typename Ptr2D::elem_type elem_type;
56         typedef float index_type;
57
58         explicit __host__ __device__ __forceinline__ PointFilter(const Ptr2D& src_, float fx = 0.f, float fy = 0.f)
59         : src(src_)
60         {
61             (void)fx;
62             (void)fy;
63         }
64
65         __device__ __forceinline__ elem_type operator ()(float y, float x) const
66         {
67             return src(__float2int_rz(y), __float2int_rz(x));
68         }
69
70         const Ptr2D src;
71     };
72
73     template <typename Ptr2D> struct LinearFilter
74     {
75         typedef typename Ptr2D::elem_type elem_type;
76         typedef float index_type;
77
78         explicit __host__ __device__ __forceinline__ LinearFilter(const Ptr2D& src_, float fx = 0.f, float fy = 0.f)
79         : src(src_)
80         {
81             (void)fx;
82             (void)fy;
83         }
84         __device__ __forceinline__ elem_type operator ()(float y, float x) const
85         {
86             typedef typename TypeVec<float, VecTraits<elem_type>::cn>::vec_type work_type;
87
88             work_type out = VecTraits<work_type>::all(0);
89
90             const int x1 = __float2int_rd(x);
91             const int y1 = __float2int_rd(y);
92             const int x2 = x1 + 1;
93             const int y2 = y1 + 1;
94
95             elem_type src_reg = src(y1, x1);
96             out = out + src_reg * ((x2 - x) * (y2 - y));
97
98             src_reg = src(y1, x2);
99             out = out + src_reg * ((x - x1) * (y2 - y));
100
101             src_reg = src(y2, x1);
102             out = out + src_reg * ((x2 - x) * (y - y1));
103
104             src_reg = src(y2, x2);
105             out = out + src_reg * ((x - x1) * (y - y1));
106
107             return saturate_cast<elem_type>(out);
108         }
109
110         const Ptr2D src;
111     };
112
113     template <typename Ptr2D> struct CubicFilter
114     {
115         typedef typename Ptr2D::elem_type elem_type;
116         typedef float index_type;
117         typedef typename TypeVec<float, VecTraits<elem_type>::cn>::vec_type work_type;
118
119         explicit __host__ __device__ __forceinline__ CubicFilter(const Ptr2D& src_, float fx = 0.f, float fy = 0.f)
120         : src(src_)
121         {
122             (void)fx;
123             (void)fy;
124         }
125
126         static __device__ __forceinline__ float bicubicCoeff(float x_)
127         {
128             float x = fabsf(x_);
129             if (x <= 1.0f)
130             {
131                 return x * x * (1.5f * x - 2.5f) + 1.0f;
132             }
133             else if (x < 2.0f)
134             {
135                 return x * (x * (-0.5f * x + 2.5f) - 4.0f) + 2.0f;
136             }
137             else
138             {
139                 return 0.0f;
140             }
141         }
142
143         __device__ elem_type operator ()(float y, float x) const
144         {
145             const float xmin = ::ceilf(x - 2.0f);
146             const float xmax = ::floorf(x + 2.0f);
147
148             const float ymin = ::ceilf(y - 2.0f);
149             const float ymax = ::floorf(y + 2.0f);
150
151             work_type sum = VecTraits<work_type>::all(0);
152             float wsum = 0.0f;
153
154             for (float cy = ymin; cy <= ymax; cy += 1.0f)
155             {
156                 for (float cx = xmin; cx <= xmax; cx += 1.0f)
157                 {
158                     const float w = bicubicCoeff(x - cx) * bicubicCoeff(y - cy);
159                     sum = sum + w * src(__float2int_rd(cy), __float2int_rd(cx));
160                     wsum += w;
161                 }
162             }
163
164             work_type res = (!wsum)? VecTraits<work_type>::all(0) : sum / wsum;
165
166             return saturate_cast<elem_type>(res);
167         }
168
169         const Ptr2D src;
170     };
171     // for integer scaling
172     template <typename Ptr2D> struct IntegerAreaFilter
173     {
174         typedef typename Ptr2D::elem_type elem_type;
175         typedef float index_type;
176
177         explicit __host__ __device__ __forceinline__ IntegerAreaFilter(const Ptr2D& src_, float scale_x_, float scale_y_)
178             : src(src_), scale_x(scale_x_), scale_y(scale_y_), scale(1.f / (scale_x * scale_y)) {}
179
180         __device__ __forceinline__ elem_type operator ()(float y, float x) const
181         {
182             float fsx1 = x * scale_x;
183             float fsx2 = fsx1 + scale_x;
184
185             int sx1 = __float2int_ru(fsx1);
186             int sx2 = __float2int_rd(fsx2);
187
188             float fsy1 = y * scale_y;
189             float fsy2 = fsy1 + scale_y;
190
191             int sy1 = __float2int_ru(fsy1);
192             int sy2 = __float2int_rd(fsy2);
193
194             typedef typename TypeVec<float, VecTraits<elem_type>::cn>::vec_type work_type;
195             work_type out = VecTraits<work_type>::all(0.f);
196
197             for(int dy = sy1; dy < sy2; ++dy)
198                 for(int dx = sx1; dx < sx2; ++dx)
199                 {
200                     out = out + src(dy, dx) * scale;
201                 }
202
203             return saturate_cast<elem_type>(out);
204         }
205
206         const Ptr2D src;
207         float scale_x, scale_y ,scale;
208     };
209
210     template <typename Ptr2D> struct AreaFilter
211     {
212         typedef typename Ptr2D::elem_type elem_type;
213         typedef float index_type;
214
215         explicit __host__ __device__ __forceinline__ AreaFilter(const Ptr2D& src_, float scale_x_, float scale_y_)
216             : src(src_), scale_x(scale_x_), scale_y(scale_y_){}
217
218         __device__ __forceinline__ elem_type operator ()(float y, float x) const
219         {
220             float fsx1 = x * scale_x;
221             float fsx2 = fsx1 + scale_x;
222
223             int sx1 = __float2int_ru(fsx1);
224             int sx2 = __float2int_rd(fsx2);
225
226             float fsy1 = y * scale_y;
227             float fsy2 = fsy1 + scale_y;
228
229             int sy1 = __float2int_ru(fsy1);
230             int sy2 = __float2int_rd(fsy2);
231
232             float scale = 1.f / (fminf(scale_x, src.width - fsx1) * fminf(scale_y, src.height - fsy1));
233
234             typedef typename TypeVec<float, VecTraits<elem_type>::cn>::vec_type work_type;
235             work_type out = VecTraits<work_type>::all(0.f);
236
237             for (int dy = sy1; dy < sy2; ++dy)
238             {
239                 for (int dx = sx1; dx < sx2; ++dx)
240                     out = out + src(dy, dx) * scale;
241
242                 if (sx1 > fsx1)
243                     out = out + src(dy, (sx1 -1) ) * ((sx1 - fsx1) * scale);
244
245                 if (sx2 < fsx2)
246                     out = out + src(dy, sx2) * ((fsx2 -sx2) * scale);
247             }
248
249             if (sy1 > fsy1)
250                 for (int dx = sx1; dx < sx2; ++dx)
251                     out = out + src( (sy1 - 1) , dx) * ((sy1 -fsy1) * scale);
252
253             if (sy2 < fsy2)
254                 for (int dx = sx1; dx < sx2; ++dx)
255                     out = out + src(sy2, dx) * ((fsy2 -sy2) * scale);
256
257             if ((sy1 > fsy1) &&  (sx1 > fsx1))
258                 out = out + src( (sy1 - 1) , (sx1 - 1)) * ((sy1 -fsy1) * (sx1 -fsx1) * scale);
259
260             if ((sy1 > fsy1) &&  (sx2 < fsx2))
261                 out = out + src( (sy1 - 1) , sx2) * ((sy1 -fsy1) * (fsx2 -sx2) * scale);
262
263             if ((sy2 < fsy2) &&  (sx2 < fsx2))
264                 out = out + src(sy2, sx2) * ((fsy2 -sy2) * (fsx2 -sx2) * scale);
265
266             if ((sy2 < fsy2) &&  (sx1 > fsx1))
267                 out = out + src(sy2, (sx1 - 1)) * ((fsy2 -sy2) * (sx1 -fsx1) * scale);
268
269             return saturate_cast<elem_type>(out);
270         }
271
272         const Ptr2D src;
273         float scale_x, scale_y;
274         int width, haight;
275     };
276 }}} // namespace cv { namespace gpu { namespace device
277
278 #endif // __OPENCV_GPU_FILTERS_HPP__