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 #if !defined CUDA_DISABLER
44 
45 #include "opencv2/core/cuda/common.hpp"
46 #include "opencv2/core/cuda/border_interpolate.hpp"
47 #include "opencv2/core/cuda/vec_traits.hpp"
48 #include "opencv2/core/cuda/vec_math.hpp"
49 #include "opencv2/core/cuda/saturate_cast.hpp"
50 #include "opencv2/core/cuda/filters.hpp"
51 
52 namespace cv { namespace cuda { namespace device
53 {
54     namespace imgproc
55     {
remap(const Ptr2D src,const PtrStepf mapx,const PtrStepf mapy,PtrStepSz<T> dst)56         template <typename Ptr2D, typename T> __global__ void remap(const Ptr2D src, const PtrStepf mapx, const PtrStepf mapy, PtrStepSz<T> dst)
57         {
58             const int x = blockDim.x * blockIdx.x + threadIdx.x;
59             const int y = blockDim.y * blockIdx.y + threadIdx.y;
60 
61             if (x < dst.cols && y < dst.rows)
62             {
63                 const float xcoo = mapx.ptr(y)[x];
64                 const float ycoo = mapy.ptr(y)[x];
65 
66                 dst.ptr(y)[x] = saturate_cast<T>(src(ycoo, xcoo));
67             }
68         }
69 
70         template <template <typename> class Filter, template <typename> class B, typename T> struct RemapDispatcherStream
71         {
callcv::cuda::device::imgproc::RemapDispatcherStream72             static void call(PtrStepSz<T> src, PtrStepSzf mapx, PtrStepSzf mapy, PtrStepSz<T> dst, const float* borderValue, cudaStream_t stream, bool)
73             {
74                 typedef typename TypeVec<float, VecTraits<T>::cn>::vec_type work_type;
75 
76                 dim3 block(32, 8);
77                 dim3 grid(divUp(dst.cols, block.x), divUp(dst.rows, block.y));
78 
79                 B<work_type> brd(src.rows, src.cols, VecTraits<work_type>::make(borderValue));
80                 BorderReader< PtrStep<T>, B<work_type> > brdSrc(src, brd);
81                 Filter< BorderReader< PtrStep<T>, B<work_type> > > filter_src(brdSrc);
82 
83                 remap<<<grid, block, 0, stream>>>(filter_src, mapx, mapy, dst);
84                 cudaSafeCall( cudaGetLastError() );
85             }
86         };
87 
88         template <template <typename> class Filter, template <typename> class B, typename T> struct RemapDispatcherNonStream
89         {
callcv::cuda::device::imgproc::RemapDispatcherNonStream90             static void call(PtrStepSz<T> src, PtrStepSz<T> srcWhole, int xoff, int yoff, PtrStepSzf mapx, PtrStepSzf mapy, PtrStepSz<T> dst, const float* borderValue, bool)
91             {
92                 (void)srcWhole;
93                 (void)xoff;
94                 (void)yoff;
95                 typedef typename TypeVec<float, VecTraits<T>::cn>::vec_type work_type;
96 
97                 dim3 block(32, 8);
98                 dim3 grid(divUp(dst.cols, block.x), divUp(dst.rows, block.y));
99 
100                 B<work_type> brd(src.rows, src.cols, VecTraits<work_type>::make(borderValue));
101                 BorderReader< PtrStep<T>, B<work_type> > brdSrc(src, brd);
102                 Filter< BorderReader< PtrStep<T>, B<work_type> > > filter_src(brdSrc);
103 
104                 remap<<<grid, block>>>(filter_src, mapx, mapy, dst);
105                 cudaSafeCall( cudaGetLastError() );
106 
107                 cudaSafeCall( cudaDeviceSynchronize() );
108             }
109         };
110 
111         #define OPENCV_CUDA_IMPLEMENT_REMAP_TEX(type) \
112             texture< type , cudaTextureType2D> tex_remap_ ## type (0, cudaFilterModePoint, cudaAddressModeClamp); \
113             struct tex_remap_ ## type ## _reader \
114             { \
115                 typedef type elem_type; \
116                 typedef int index_type; \
117                 int xoff, yoff; \
118                 tex_remap_ ## type ## _reader (int xoff_, int yoff_) : xoff(xoff_), yoff(yoff_) {} \
119                 __device__ __forceinline__ elem_type operator ()(index_type y, index_type x) const \
120                 { \
121                     return tex2D(tex_remap_ ## type , x + xoff, y + yoff); \
122                 } \
123             }; \
124             template <template <typename> class Filter, template <typename> class B> struct RemapDispatcherNonStream<Filter, B, type> \
125             { \
126                 static void call(PtrStepSz< type > src, PtrStepSz< type > srcWhole, int xoff, int yoff, PtrStepSzf mapx, PtrStepSzf mapy, \
127                     PtrStepSz< type > dst, const float* borderValue, bool cc20) \
128                 { \
129                     typedef typename TypeVec<float, VecTraits< type >::cn>::vec_type work_type; \
130                     dim3 block(32, cc20 ? 8 : 4); \
131                     dim3 grid(divUp(dst.cols, block.x), divUp(dst.rows, block.y)); \
132                     bindTexture(&tex_remap_ ## type , srcWhole); \
133                     tex_remap_ ## type ##_reader texSrc(xoff, yoff); \
134                     B<work_type> brd(src.rows, src.cols, VecTraits<work_type>::make(borderValue)); \
135                     BorderReader< tex_remap_ ## type ##_reader, B<work_type> > brdSrc(texSrc, brd); \
136                     Filter< BorderReader< tex_remap_ ## type ##_reader, B<work_type> > > filter_src(brdSrc); \
137                     remap<<<grid, block>>>(filter_src, mapx, mapy, dst); \
138                     cudaSafeCall( cudaGetLastError() ); \
139                     cudaSafeCall( cudaDeviceSynchronize() ); \
140                 } \
141             }; \
142             template <template <typename> class Filter> struct RemapDispatcherNonStream<Filter, BrdReplicate, type> \
143             { \
144                 static void call(PtrStepSz< type > src, PtrStepSz< type > srcWhole, int xoff, int yoff, PtrStepSzf mapx, PtrStepSzf mapy, \
145                     PtrStepSz< type > dst, const float*, bool) \
146                 { \
147                     dim3 block(32, 8); \
148                     dim3 grid(divUp(dst.cols, block.x), divUp(dst.rows, block.y)); \
149                     bindTexture(&tex_remap_ ## type , srcWhole); \
150                     tex_remap_ ## type ##_reader texSrc(xoff, yoff); \
151                     if (srcWhole.cols == src.cols && srcWhole.rows == src.rows) \
152                     { \
153                         Filter< tex_remap_ ## type ##_reader > filter_src(texSrc); \
154                         remap<<<grid, block>>>(filter_src, mapx, mapy, dst); \
155                     } \
156                     else \
157                     { \
158                         BrdReplicate<type> brd(src.rows, src.cols); \
159                         BorderReader< tex_remap_ ## type ##_reader, BrdReplicate<type> > brdSrc(texSrc, brd); \
160                         Filter< BorderReader< tex_remap_ ## type ##_reader, BrdReplicate<type> > > filter_src(brdSrc); \
161                         remap<<<grid, block>>>(filter_src, mapx, mapy, dst); \
162                     } \
163                     cudaSafeCall( cudaGetLastError() ); \
164                     cudaSafeCall( cudaDeviceSynchronize() ); \
165                 } \
166             };
167 
168         OPENCV_CUDA_IMPLEMENT_REMAP_TEX(uchar)
169         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(uchar2)
170         OPENCV_CUDA_IMPLEMENT_REMAP_TEX(uchar4)
171 
172         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(schar)
173         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(char2)
174         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(char4)
175 
176         OPENCV_CUDA_IMPLEMENT_REMAP_TEX(ushort)
177         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(ushort2)
178         OPENCV_CUDA_IMPLEMENT_REMAP_TEX(ushort4)
179 
180         OPENCV_CUDA_IMPLEMENT_REMAP_TEX(short)
181         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(short2)
182         OPENCV_CUDA_IMPLEMENT_REMAP_TEX(short4)
183 
184         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(int)
185         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(int2)
186         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(int4)
187 
188         OPENCV_CUDA_IMPLEMENT_REMAP_TEX(float)
189         //OPENCV_CUDA_IMPLEMENT_REMAP_TEX(float2)
190         OPENCV_CUDA_IMPLEMENT_REMAP_TEX(float4)
191 
192         #undef OPENCV_CUDA_IMPLEMENT_REMAP_TEX
193 
194         template <template <typename> class Filter, template <typename> class B, typename T> struct RemapDispatcher
195         {
callcv::cuda::device::imgproc::RemapDispatcher196             static void call(PtrStepSz<T> src, PtrStepSz<T> srcWhole, int xoff, int yoff, PtrStepSzf mapx, PtrStepSzf mapy,
197                 PtrStepSz<T> dst, const float* borderValue, cudaStream_t stream, bool cc20)
198             {
199                 if (stream == 0)
200                     RemapDispatcherNonStream<Filter, B, T>::call(src, srcWhole, xoff, yoff, mapx, mapy, dst, borderValue, cc20);
201                 else
202                     RemapDispatcherStream<Filter, B, T>::call(src, mapx, mapy, dst, borderValue, stream, cc20);
203             }
204         };
205 
remap_gpu(PtrStepSzb src,PtrStepSzb srcWhole,int xoff,int yoff,PtrStepSzf xmap,PtrStepSzf ymap,PtrStepSzb dst,int interpolation,int borderMode,const float * borderValue,cudaStream_t stream,bool cc20)206         template <typename T> void remap_gpu(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap,
207             PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20)
208         {
209             typedef void (*caller_t)(PtrStepSz<T> src, PtrStepSz<T> srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap,
210                 PtrStepSz<T> dst, const float* borderValue, cudaStream_t stream, bool cc20);
211 
212             static const caller_t callers[3][5] =
213             {
214                 {
215                     RemapDispatcher<PointFilter, BrdConstant, T>::call,
216                     RemapDispatcher<PointFilter, BrdReplicate, T>::call,
217                     RemapDispatcher<PointFilter, BrdReflect, T>::call,
218                     RemapDispatcher<PointFilter, BrdWrap, T>::call,
219                     RemapDispatcher<PointFilter, BrdReflect101, T>::call
220                 },
221                 {
222                     RemapDispatcher<LinearFilter, BrdConstant, T>::call,
223                     RemapDispatcher<LinearFilter, BrdReplicate, T>::call,
224                     RemapDispatcher<LinearFilter, BrdReflect, T>::call,
225                     RemapDispatcher<LinearFilter, BrdWrap, T>::call,
226                     RemapDispatcher<LinearFilter, BrdReflect101, T>::call
227                 },
228                 {
229                     RemapDispatcher<CubicFilter, BrdConstant, T>::call,
230                     RemapDispatcher<CubicFilter, BrdReplicate, T>::call,
231                     RemapDispatcher<CubicFilter, BrdReflect, T>::call,
232                     RemapDispatcher<CubicFilter, BrdWrap, T>::call,
233                     RemapDispatcher<CubicFilter, BrdReflect101, T>::call
234                 }
235             };
236 
237             callers[interpolation][borderMode](static_cast< PtrStepSz<T> >(src), static_cast< PtrStepSz<T> >(srcWhole), xoff, yoff, xmap, ymap,
238                 static_cast< PtrStepSz<T> >(dst), borderValue, stream, cc20);
239         }
240 
241         template void remap_gpu<uchar >(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
242         //template void remap_gpu<uchar2>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
243         template void remap_gpu<uchar3>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
244         template void remap_gpu<uchar4>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
245 
246         //template void remap_gpu<schar>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
247         //template void remap_gpu<char2>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
248         //template void remap_gpu<char3>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
249         //template void remap_gpu<char4>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
250 
251         template void remap_gpu<ushort >(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
252         //template void remap_gpu<ushort2>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
253         template void remap_gpu<ushort3>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
254         template void remap_gpu<ushort4>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
255 
256         template void remap_gpu<short >(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
257         //template void remap_gpu<short2>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
258         template void remap_gpu<short3>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
259         template void remap_gpu<short4>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
260 
261         //template void remap_gpu<int >(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
262         //template void remap_gpu<int2>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
263         //template void remap_gpu<int3>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
264         //template void remap_gpu<int4>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
265 
266         template void remap_gpu<float >(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
267         //template void remap_gpu<float2>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
268         template void remap_gpu<float3>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
269         template void remap_gpu<float4>(PtrStepSzb src, PtrStepSzb srcWhole, int xoff, int yoff, PtrStepSzf xmap, PtrStepSzf ymap, PtrStepSzb dst, int interpolation, int borderMode, const float* borderValue, cudaStream_t stream, bool cc20);
270     } // namespace imgproc
271 }}} // namespace cv { namespace cuda { namespace cudev
272 
273 
274 #endif /* CUDA_DISABLER */
275