Home | History | Annotate | Download | only in cuda
      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     {
     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         {
     72             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         {
     90             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         {
    196             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 
    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