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/transform.hpp"
     47 #include "opencv2/core/cuda/functional.hpp"
     48 #include "opencv2/core/cuda/reduce.hpp"
     49 
     50 namespace cv { namespace cuda { namespace device
     51 {
     52     /////////////////////////////////// reprojectImageTo3D ///////////////////////////////////////////////
     53 
     54     __constant__ float cq[16];
     55 
     56     template <typename T, typename D>
     57     __global__ void reprojectImageTo3D(const PtrStepSz<T> disp, PtrStep<D> xyz)
     58     {
     59         const int x = blockIdx.x * blockDim.x + threadIdx.x;
     60         const int y = blockIdx.y * blockDim.y + threadIdx.y;
     61 
     62         if (y >= disp.rows || x >= disp.cols)
     63             return;
     64 
     65         const float qx = x * cq[ 0] + y * cq[ 1] + cq[ 3];
     66         const float qy = x * cq[ 4] + y * cq[ 5] + cq[ 7];
     67         const float qz = x * cq[ 8] + y * cq[ 9] + cq[11];
     68         const float qw = x * cq[12] + y * cq[13] + cq[15];
     69 
     70         const T d = disp(y, x);
     71 
     72         const float iW = 1.f / (qw + cq[14] * d);
     73 
     74         D v = VecTraits<D>::all(1.0f);
     75         v.x = (qx + cq[2] * d) * iW;
     76         v.y = (qy + cq[6] * d) * iW;
     77         v.z = (qz + cq[10] * d) * iW;
     78 
     79         xyz(y, x) = v;
     80     }
     81 
     82     template <typename T, typename D>
     83     void reprojectImageTo3D_gpu(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream)
     84     {
     85         dim3 block(32, 8);
     86         dim3 grid(divUp(disp.cols, block.x), divUp(disp.rows, block.y));
     87 
     88         cudaSafeCall( cudaMemcpyToSymbol(cq, q, 16 * sizeof(float)) );
     89 
     90         reprojectImageTo3D<T, D><<<grid, block, 0, stream>>>((PtrStepSz<T>)disp, (PtrStepSz<D>)xyz);
     91         cudaSafeCall( cudaGetLastError() );
     92 
     93         if (stream == 0)
     94             cudaSafeCall( cudaDeviceSynchronize() );
     95     }
     96 
     97     template void reprojectImageTo3D_gpu<uchar, float3>(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
     98     template void reprojectImageTo3D_gpu<uchar, float4>(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
     99     template void reprojectImageTo3D_gpu<short, float3>(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
    100     template void reprojectImageTo3D_gpu<short, float4>(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
    101 
    102     /////////////////////////////////// drawColorDisp ///////////////////////////////////////////////
    103 
    104     template <typename T>
    105     __device__ unsigned int cvtPixel(T d, int ndisp, float S = 1, float V = 1)
    106     {
    107         unsigned int H = ((ndisp-d) * 240)/ndisp;
    108 
    109         unsigned int hi = (H/60) % 6;
    110         float f = H/60.f - H/60;
    111         float p = V * (1 - S);
    112         float q = V * (1 - f * S);
    113         float t = V * (1 - (1 - f) * S);
    114 
    115         float3 res;
    116 
    117         if (hi == 0) //R = V,	G = t,	B = p
    118         {
    119             res.x = p;
    120             res.y = t;
    121             res.z = V;
    122         }
    123 
    124         if (hi == 1) // R = q,	G = V,	B = p
    125         {
    126             res.x = p;
    127             res.y = V;
    128             res.z = q;
    129         }
    130 
    131         if (hi == 2) // R = p,	G = V,	B = t
    132         {
    133             res.x = t;
    134             res.y = V;
    135             res.z = p;
    136         }
    137 
    138         if (hi == 3) // R = p,	G = q,	B = V
    139         {
    140             res.x = V;
    141             res.y = q;
    142             res.z = p;
    143         }
    144 
    145         if (hi == 4) // R = t,	G = p,	B = V
    146         {
    147             res.x = V;
    148             res.y = p;
    149             res.z = t;
    150         }
    151 
    152         if (hi == 5) // R = V,	G = p,	B = q
    153         {
    154             res.x = q;
    155             res.y = p;
    156             res.z = V;
    157         }
    158         const unsigned int b = (unsigned int)(::max(0.f, ::min(res.x, 1.f)) * 255.f);
    159         const unsigned int g = (unsigned int)(::max(0.f, ::min(res.y, 1.f)) * 255.f);
    160         const unsigned int r = (unsigned int)(::max(0.f, ::min(res.z, 1.f)) * 255.f);
    161         const unsigned int a = 255U;
    162 
    163         return (a << 24) + (r << 16) + (g << 8) + b;
    164     }
    165 
    166     __global__ void drawColorDisp(uchar* disp, size_t disp_step, uchar* out_image, size_t out_step, int width, int height, int ndisp)
    167     {
    168         const int x = (blockIdx.x * blockDim.x + threadIdx.x) << 2;
    169         const int y = blockIdx.y * blockDim.y + threadIdx.y;
    170 
    171         if(x < width && y < height)
    172         {
    173             uchar4 d4 = *(uchar4*)(disp + y * disp_step + x);
    174 
    175             uint4 res;
    176             res.x = cvtPixel(d4.x, ndisp);
    177             res.y = cvtPixel(d4.y, ndisp);
    178             res.z = cvtPixel(d4.z, ndisp);
    179             res.w = cvtPixel(d4.w, ndisp);
    180 
    181             uint4* line = (uint4*)(out_image + y * out_step);
    182             line[x >> 2] = res;
    183         }
    184     }
    185 
    186     __global__ void drawColorDisp(short* disp, size_t disp_step, uchar* out_image, size_t out_step, int width, int height, int ndisp)
    187     {
    188         const int x = (blockIdx.x * blockDim.x + threadIdx.x) << 1;
    189         const int y = blockIdx.y * blockDim.y + threadIdx.y;
    190 
    191         if(x < width && y < height)
    192         {
    193             short2 d2 = *(short2*)(disp + y * disp_step + x);
    194 
    195             uint2 res;
    196             res.x = cvtPixel(d2.x, ndisp);
    197             res.y = cvtPixel(d2.y, ndisp);
    198 
    199             uint2* line = (uint2*)(out_image + y * out_step);
    200             line[x >> 1] = res;
    201         }
    202     }
    203 
    204 
    205     void drawColorDisp_gpu(const PtrStepSzb& src, const PtrStepSzb& dst, int ndisp, const cudaStream_t& stream)
    206     {
    207         dim3 threads(16, 16, 1);
    208         dim3 grid(1, 1, 1);
    209         grid.x = divUp(src.cols, threads.x << 2);
    210         grid.y = divUp(src.rows, threads.y);
    211 
    212         drawColorDisp<<<grid, threads, 0, stream>>>(src.data, src.step, dst.data, dst.step, src.cols, src.rows, ndisp);
    213         cudaSafeCall( cudaGetLastError() );
    214 
    215         if (stream == 0)
    216             cudaSafeCall( cudaDeviceSynchronize() );
    217     }
    218 
    219     void drawColorDisp_gpu(const PtrStepSz<short>& src, const PtrStepSzb& dst, int ndisp, const cudaStream_t& stream)
    220     {
    221         dim3 threads(32, 8, 1);
    222         dim3 grid(1, 1, 1);
    223         grid.x = divUp(src.cols, threads.x << 1);
    224         grid.y = divUp(src.rows, threads.y);
    225 
    226         drawColorDisp<<<grid, threads, 0, stream>>>(src.data, src.step / sizeof(short), dst.data, dst.step, src.cols, src.rows, ndisp);
    227         cudaSafeCall( cudaGetLastError() );
    228 
    229         if (stream == 0)
    230             cudaSafeCall( cudaDeviceSynchronize() );
    231     }
    232 }}} // namespace cv { namespace cuda { namespace cudev
    233 
    234 
    235 #endif /* CUDA_DISABLER */
    236