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 "precomp.hpp" 44 45 using namespace cv; 46 using namespace cv::cuda; 47 48 #if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) 49 50 Ptr<cuda::HoughLinesDetector> cv::cuda::createHoughLinesDetector(float, float, int, bool, int) { throw_no_cuda(); return Ptr<HoughLinesDetector>(); } 51 52 #else /* !defined (HAVE_CUDA) */ 53 54 namespace cv { namespace cuda { namespace device 55 { 56 namespace hough 57 { 58 int buildPointList_gpu(PtrStepSzb src, unsigned int* list); 59 } 60 61 namespace hough_lines 62 { 63 void linesAccum_gpu(const unsigned int* list, int count, PtrStepSzi accum, float rho, float theta, size_t sharedMemPerBlock, bool has20); 64 int linesGetResult_gpu(PtrStepSzi accum, float2* out, int* votes, int maxSize, float rho, float theta, int threshold, bool doSort); 65 } 66 }}} 67 68 namespace 69 { 70 class HoughLinesDetectorImpl : public HoughLinesDetector 71 { 72 public: 73 HoughLinesDetectorImpl(float rho, float theta, int threshold, bool doSort, int maxLines) : 74 rho_(rho), theta_(theta), threshold_(threshold), doSort_(doSort), maxLines_(maxLines) 75 { 76 } 77 78 void detect(InputArray src, OutputArray lines, Stream& stream); 79 void downloadResults(InputArray d_lines, OutputArray h_lines, OutputArray h_votes, Stream& stream); 80 81 void setRho(float rho) { rho_ = rho; } 82 float getRho() const { return rho_; } 83 84 void setTheta(float theta) { theta_ = theta; } 85 float getTheta() const { return theta_; } 86 87 void setThreshold(int threshold) { threshold_ = threshold; } 88 int getThreshold() const { return threshold_; } 89 90 void setDoSort(bool doSort) { doSort_ = doSort; } 91 bool getDoSort() const { return doSort_; } 92 93 void setMaxLines(int maxLines) { maxLines_ = maxLines; } 94 int getMaxLines() const { return maxLines_; } 95 96 void write(FileStorage& fs) const 97 { 98 fs << "name" << "HoughLinesDetector_CUDA" 99 << "rho" << rho_ 100 << "theta" << theta_ 101 << "threshold" << threshold_ 102 << "doSort" << doSort_ 103 << "maxLines" << maxLines_; 104 } 105 106 void read(const FileNode& fn) 107 { 108 CV_Assert( String(fn["name"]) == "HoughLinesDetector_CUDA" ); 109 rho_ = (float)fn["rho"]; 110 theta_ = (float)fn["theta"]; 111 threshold_ = (int)fn["threshold"]; 112 doSort_ = (int)fn["doSort"] != 0; 113 maxLines_ = (int)fn["maxLines"]; 114 } 115 116 private: 117 float rho_; 118 float theta_; 119 int threshold_; 120 bool doSort_; 121 int maxLines_; 122 123 GpuMat accum_; 124 GpuMat list_; 125 GpuMat result_; 126 }; 127 128 void HoughLinesDetectorImpl::detect(InputArray _src, OutputArray lines, Stream& stream) 129 { 130 // TODO : implement async version 131 (void) stream; 132 133 using namespace cv::cuda::device::hough; 134 using namespace cv::cuda::device::hough_lines; 135 136 GpuMat src = _src.getGpuMat(); 137 138 CV_Assert( src.type() == CV_8UC1 ); 139 CV_Assert( src.cols < std::numeric_limits<unsigned short>::max() ); 140 CV_Assert( src.rows < std::numeric_limits<unsigned short>::max() ); 141 142 ensureSizeIsEnough(1, src.size().area(), CV_32SC1, list_); 143 unsigned int* srcPoints = list_.ptr<unsigned int>(); 144 145 const int pointsCount = buildPointList_gpu(src, srcPoints); 146 if (pointsCount == 0) 147 { 148 lines.release(); 149 return; 150 } 151 152 const int numangle = cvRound(CV_PI / theta_); 153 const int numrho = cvRound(((src.cols + src.rows) * 2 + 1) / rho_); 154 CV_Assert( numangle > 0 && numrho > 0 ); 155 156 ensureSizeIsEnough(numangle + 2, numrho + 2, CV_32SC1, accum_); 157 accum_.setTo(Scalar::all(0)); 158 159 DeviceInfo devInfo; 160 linesAccum_gpu(srcPoints, pointsCount, accum_, rho_, theta_, devInfo.sharedMemPerBlock(), devInfo.supports(FEATURE_SET_COMPUTE_20)); 161 162 ensureSizeIsEnough(2, maxLines_, CV_32FC2, result_); 163 164 int linesCount = linesGetResult_gpu(accum_, result_.ptr<float2>(0), result_.ptr<int>(1), maxLines_, rho_, theta_, threshold_, doSort_); 165 166 if (linesCount == 0) 167 { 168 lines.release(); 169 return; 170 } 171 172 result_.cols = linesCount; 173 result_.copyTo(lines); 174 } 175 176 void HoughLinesDetectorImpl::downloadResults(InputArray _d_lines, OutputArray h_lines, OutputArray h_votes, Stream& stream) 177 { 178 GpuMat d_lines = _d_lines.getGpuMat(); 179 180 if (d_lines.empty()) 181 { 182 h_lines.release(); 183 if (h_votes.needed()) 184 h_votes.release(); 185 return; 186 } 187 188 CV_Assert( d_lines.rows == 2 && d_lines.type() == CV_32FC2 ); 189 190 if (stream) 191 d_lines.row(0).download(h_lines, stream); 192 else 193 d_lines.row(0).download(h_lines); 194 195 if (h_votes.needed()) 196 { 197 GpuMat d_votes(1, d_lines.cols, CV_32SC1, d_lines.ptr<int>(1)); 198 if (stream) 199 d_votes.download(h_votes, stream); 200 else 201 d_votes.download(h_votes); 202 } 203 } 204 } 205 206 Ptr<HoughLinesDetector> cv::cuda::createHoughLinesDetector(float rho, float theta, int threshold, bool doSort, int maxLines) 207 { 208 return makePtr<HoughLinesDetectorImpl>(rho, theta, threshold, doSort, maxLines); 209 } 210 211 #endif /* !defined (HAVE_CUDA) */ 212