Home | History | Annotate | Download | only in src
      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