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
createHoughLinesDetector(float,float,int,bool,int)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:
HoughLinesDetectorImpl(float rho,float theta,int threshold,bool doSort,int maxLines)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
setRho(float rho)81 void setRho(float rho) { rho_ = rho; }
getRho() const82 float getRho() const { return rho_; }
83
setTheta(float theta)84 void setTheta(float theta) { theta_ = theta; }
getTheta() const85 float getTheta() const { return theta_; }
86
setThreshold(int threshold)87 void setThreshold(int threshold) { threshold_ = threshold; }
getThreshold() const88 int getThreshold() const { return threshold_; }
89
setDoSort(bool doSort)90 void setDoSort(bool doSort) { doSort_ = doSort; }
getDoSort() const91 bool getDoSort() const { return doSort_; }
92
setMaxLines(int maxLines)93 void setMaxLines(int maxLines) { maxLines_ = maxLines; }
getMaxLines() const94 int getMaxLines() const { return maxLines_; }
95
write(FileStorage & fs) const96 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
read(const FileNode & fn)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
detect(InputArray _src,OutputArray lines,Stream & stream)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
downloadResults(InputArray _d_lines,OutputArray h_lines,OutputArray h_votes,Stream & stream)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
createHoughLinesDetector(float rho,float theta,int threshold,bool doSort,int maxLines)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