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 #include "opencv2/opencv_modules.hpp" 44 45 #ifndef HAVE_OPENCV_CUDEV 46 47 #error "opencv_cudev is required" 48 49 #else 50 51 #include "opencv2/cudaarithm.hpp" 52 #include "opencv2/cudev.hpp" 53 #include "opencv2/core/private.cuda.hpp" 54 55 using namespace cv; 56 using namespace cv::cuda; 57 using namespace cv::cudev; 58 59 namespace 60 { 61 texture<uchar, cudaTextureType1D, cudaReadModeElementType> texLutTable; 62 63 class LookUpTableImpl : public LookUpTable 64 { 65 public: 66 LookUpTableImpl(InputArray lut); 67 ~LookUpTableImpl(); 68 69 void transform(InputArray src, OutputArray dst, Stream& stream = Stream::Null()); 70 71 private: 72 GpuMat d_lut; 73 cudaTextureObject_t texLutTableObj; 74 bool cc30; 75 }; 76 77 LookUpTableImpl::LookUpTableImpl(InputArray _lut) 78 { 79 if (_lut.kind() == _InputArray::CUDA_GPU_MAT) 80 { 81 d_lut = _lut.getGpuMat(); 82 } 83 else 84 { 85 Mat h_lut = _lut.getMat(); 86 d_lut.upload(Mat(1, 256, h_lut.type(), h_lut.data)); 87 } 88 89 CV_Assert( d_lut.depth() == CV_8U ); 90 CV_Assert( d_lut.rows == 1 && d_lut.cols == 256 ); 91 92 cc30 = deviceSupports(FEATURE_SET_COMPUTE_30); 93 94 if (cc30) 95 { 96 // Use the texture object 97 cudaResourceDesc texRes; 98 std::memset(&texRes, 0, sizeof(texRes)); 99 texRes.resType = cudaResourceTypeLinear; 100 texRes.res.linear.devPtr = d_lut.data; 101 texRes.res.linear.desc = cudaCreateChannelDesc<uchar>(); 102 texRes.res.linear.sizeInBytes = 256 * d_lut.channels() * sizeof(uchar); 103 104 cudaTextureDesc texDescr; 105 std::memset(&texDescr, 0, sizeof(texDescr)); 106 107 CV_CUDEV_SAFE_CALL( cudaCreateTextureObject(&texLutTableObj, &texRes, &texDescr, 0) ); 108 } 109 else 110 { 111 // Use the texture reference 112 cudaChannelFormatDesc desc = cudaCreateChannelDesc<uchar>(); 113 CV_CUDEV_SAFE_CALL( cudaBindTexture(0, &texLutTable, d_lut.data, &desc) ); 114 } 115 } 116 117 LookUpTableImpl::~LookUpTableImpl() 118 { 119 if (cc30) 120 { 121 // Use the texture object 122 cudaDestroyTextureObject(texLutTableObj); 123 } 124 else 125 { 126 // Use the texture reference 127 cudaUnbindTexture(texLutTable); 128 } 129 } 130 131 struct LutTablePtrC1 132 { 133 typedef uchar value_type; 134 typedef uchar index_type; 135 136 cudaTextureObject_t texLutTableObj; 137 138 __device__ __forceinline__ uchar operator ()(uchar, uchar x) const 139 { 140 #if CV_CUDEV_ARCH < 300 141 // Use the texture reference 142 return tex1Dfetch(texLutTable, x); 143 #else 144 // Use the texture object 145 return tex1Dfetch<uchar>(texLutTableObj, x); 146 #endif 147 } 148 }; 149 struct LutTablePtrC3 150 { 151 typedef uchar3 value_type; 152 typedef uchar3 index_type; 153 154 cudaTextureObject_t texLutTableObj; 155 156 __device__ __forceinline__ uchar3 operator ()(const uchar3&, const uchar3& x) const 157 { 158 #if CV_CUDEV_ARCH < 300 159 // Use the texture reference 160 return make_uchar3(tex1Dfetch(texLutTable, x.x * 3), tex1Dfetch(texLutTable, x.y * 3 + 1), tex1Dfetch(texLutTable, x.z * 3 + 2)); 161 #else 162 // Use the texture object 163 return make_uchar3(tex1Dfetch<uchar>(texLutTableObj, x.x * 3), tex1Dfetch<uchar>(texLutTableObj, x.y * 3 + 1), tex1Dfetch<uchar>(texLutTableObj, x.z * 3 + 2)); 164 #endif 165 } 166 }; 167 168 void LookUpTableImpl::transform(InputArray _src, OutputArray _dst, Stream& stream) 169 { 170 GpuMat src = getInputMat(_src, stream); 171 172 const int cn = src.channels(); 173 const int lut_cn = d_lut.channels(); 174 175 CV_Assert( src.type() == CV_8UC1 || src.type() == CV_8UC3 ); 176 CV_Assert( lut_cn == 1 || lut_cn == cn ); 177 178 GpuMat dst = getOutputMat(_dst, src.size(), src.type(), stream); 179 180 if (lut_cn == 1) 181 { 182 GpuMat_<uchar> src1(src.reshape(1)); 183 GpuMat_<uchar> dst1(dst.reshape(1)); 184 185 LutTablePtrC1 tbl; 186 tbl.texLutTableObj = texLutTableObj; 187 188 dst1.assign(lut_(src1, tbl), stream); 189 } 190 else if (lut_cn == 3) 191 { 192 GpuMat_<uchar3>& src3 = (GpuMat_<uchar3>&) src; 193 GpuMat_<uchar3>& dst3 = (GpuMat_<uchar3>&) dst; 194 195 LutTablePtrC3 tbl; 196 tbl.texLutTableObj = texLutTableObj; 197 198 dst3.assign(lut_(src3, tbl), stream); 199 } 200 201 syncOutput(dst, _dst, stream); 202 } 203 } 204 205 Ptr<LookUpTable> cv::cuda::createLookUpTable(InputArray lut) 206 { 207 return makePtr<LookUpTableImpl>(lut); 208 } 209 210 #endif 211