用霍夫變換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);
  • 得到如下結果。


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