用霍夫变换HoughLines检测直线2

书名:OpenCV计算机视觉编程攻略(第3版)
作者:[加]罗伯特·拉戈尼尔
译者:相银初
出版社:人民邮电出版社
出版时间:2018-05
ISBN:9787115480934

一、HoughLinesP函数

  • 为解决上述问题(即测出的结果重复)并检测到线段(即包含端点的直线),人们提出了霍夫变换的改进版。这就是概率霍夫变换,在OpenCV中通过cv::HoughLinesP函数实现。我们用它创建LineFinder类,封装函数的参数:
        class LineFinder {
          private:
          // 原始图像
          cv::Mat img;
          // 包含被检测直线的端点的向量
      std::vector<cv::Vec4i> lines;
      // 累加器分辨率参数
      double deltaRho;
      double deltaTheta;
      // 确认直线之前必须收到的最小投票数
      int minVote;
      // 直线的最小长度
      double minLength;
      // 直线上允许的最大空隙
      double maxGap;
      public:
        // 默认累加器分辨率是1像素,1度
        // 没有空隙,没有最小长度
        LineFinder() : deltaRho(1), deltaTheta(PI/180),
                      minVote(10), minLength(0.), maxGap(0.) {}
  • 对应的设置方法:
    // 设置累加器的分辨率
    void setAccResolution(double dRho, double dTheta) {
      deltaRho= dRho;
      deltaTheta= dTheta;
    }
    // 设置最小投票数
    void setMinVote(int minv) {
      minVote= minv;
    }
    // 设置直线长度和空隙
    void setLineLengthAndGap(double length, double gap) {
      minLength= length;
      maxGap= gap;
    }

二、检测霍夫线段的代码

    // 应用概率霍夫变换
    std::vector<cv::Vec4i> findLines(cv::Mat& binary) {
      lines.clear();
      cv::HoughLinesP(binary, lines,
                      deltaRho, deltaTheta, minVote,
                      minLength, maxGap);
      return lines;
    }
  • 这个方法返回cv::Vec4i类型的向量,包含每条被检测线段的开始端点和结束端点的座标。我们可以用下面的方法在图像上绘制检测到的线段:
        // 在图像上绘制检测到的直线
        void drawDetectedLines(cv::Mat &image,
                                cv::Scalar color=cv::Scalar(255,255,255)) {
          // 画直线
          std::vector<cv::Vec4i>::const_iterator it2= lines.begin();

          while (it2! =lines.end()) {
            cv::Point pt1((*it2)[0], (*it2)[1]);
            cv::Point pt2((*it2)[2], (*it2)[3]);
            cv::line( image, pt1, pt2, color);
           ++it2;
          }
        }
  • 输入图像不变,可以用下面的次序检测直线:
        // 创建LineFinder类的实例
        LineFinder finder;


        // 设置概率霍夫变换的参数
        finder.setLineLengthAndGap(100,20);
        finder.setMinVote(60);


        // 检测直线并画线
        std::vector<cv::Vec4i> lines= finder.findLines(contours);
        finder.drawDetectedLines(image);
  • 得到如下结果。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章