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