<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## OpenCV 學習(Hough 變換提取直線) 在機器視覺應用中,我們經常要提取圖像中的各種特征,最基本的特征就是圖像中的線條、拐角等。這篇筆記就來講講如何提取圖像中的直線。這里使用的方法叫做 Hough 變換。 Hough 變換這個名稱最早是在 Richard Duda 和 Peter Hart 兩人于 1972 年合寫的發表于 Comm. ACM 文章 《Use of the Hough Transformation to Detect Lines and Curves in Pictures》 中提出的。 大家可能會好奇,這倆人沒一個叫 Hough,為啥這個變換叫 Hough 變換呢。這還要追溯到更早的年代,1962 年 Paul Hough 申請了一個美國專利,專利的名稱叫做 《Method and means for recognizing complex patterns》,這個專利中提出了 Hough 變換基本方法。不過 1962 年那時還沒有所謂的機器視覺這個學科,計算機也不是一般人能見到的。所以這個專利并沒有受到特別的重視。 Richard Duda 和 Peter Hart 不知是如何翻到這個 10 年前的專利,并敏銳的發現了它的價值,并將其用于機器視覺領域。從此就有了大名鼎鼎的 Hough 變換。 關于 Hough 更詳細的歷史發展大家可以參考: [https://en.wikipedia.org/wiki/Hough_transform](https://en.wikipedia.org/wiki/Hough_transform) Hough 變換的原理介紹也可以參考上面的 wiki。簡單的說 Hough 變換采用的是一種證據收集的方式,遍歷一幅圖像上所有的直線位置,哪條直線上的特征點(證據)更多,哪條直線就更可能是我們希望找到的直線。 這里不準備詳細介紹Hough 變換的原理。但是Hough 變換如何表示圖像中的直線還是要介紹的。否則,我們都不知道如何使用獲得的結果。 Hough 變換時,我們采用參數方程來表示直線。 ρ=xcosθ+ysinθ ρ 的幾何含義是直線到圖像原點的距離。 θ 是直線的法向方向與 x 軸的夾角。 θ=0 表示的是垂直的直線,例如下圖中直線 1。 θ=π/2 表示的是水平的直線,例如下圖中直線 5。 θ 的取值范圍是 0 到 π。由于限制了θ的取值范圍,ρ 既可以為正也可以為負。比如下圖中直線2,θ=0.8π ,ρ 為負。 ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db65bb5e.jpg "") OpenCV 中提供了兩個Hough變換提取直線的函數。 1. cv::HoughLines 函數 1. cv::HoughLinesP 函數 下面分別介紹。 ### cv::HoughLines 函數 這個函數采用最原始的Hough 變換來計算直線的位置。 ~~~ void HoughLines( InputArray image, OutputArray lines, double rho, // rho 的步長 double theta, // 角度步長 int threshold, // 閾值 double srn=0, double stn=0 ); ~~~ 輸入圖像必須是單通道的。輸出的直線存在一個 ~~~ std::vector<cv::Vec2f> lines; ~~~ 首先給出一個簡單的測試圖片。這個圖片上有四條直線。沒有其他的干擾物體。這屬于最基本的情形。 ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db670816.jpg "") 下面是個測試代碼。 ~~~ #include <QCoreApplication> #include <math.h> #define PI 3.14159265358979 #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); cv::Mat image = cv::imread("c:\\test.png"); cv::Mat contours; cv::cvtColor(image, contours, cv::COLOR_BGR2GRAY); cv::bitwise_not(contours, contours); //cv::Canny(image, contours, 155, 350); std::vector<cv::Vec2f> lines; cv::HoughLines(contours, lines, 1, PI/180, 180); //cv::imshow("cany",contours ); std::vector<cv::Vec2f>::const_iterator it= lines.begin(); while (it!=lines.end()) { float rho= (*it)[0]; // first element is distance rho float theta= (*it)[1]; // second element is angle theta if (theta < PI/4. || theta > 3.*PI/4.)// ~vertical line { // point of intersection of the line with first row cv::Point pt1(rho/cos(theta), 0); // point of intersection of the line with last row cv::Point pt2((rho - image.rows * sin(theta))/cos(theta), image.rows); // draw a white line cv::line( image, pt1, pt2, cv::Scalar(255), 1); } else { // ~horizontal line // point of intersection of the // line with first column cv::Point pt1(0,rho/sin(theta)); // point of intersection of the line with last column cv::Point pt2(image.cols, (rho - image.cols * cos(theta))/sin(theta)); // draw a white line cv::line(image, pt1, pt2, cv::Scalar(255), 1); } ++it; } cv::imshow("", image); return a.exec(); } ~~~ 輸出結果如下: ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db68455e.jpg "") 這幾條線找的還是蠻準的。 ### cv::HoughLinesP 函數 與 cv::HoughLines函數不同, cv::HoughLinesP 函數可以提取線段。 輸出的直線存在一個 ~~~ std::vector<cv::Vec4i> lines; ~~~ 中。 cv::Vec4i 的四個整數分別是線段的起點和終點坐標。 ~~~ void HoughLinesP( InputArray image, OutputArray lines, double rho, // rho 的步長 double theta, // 角度的步長,單位是度 int threshold, // 閾值 double minLineLength=0, // 線段的最小長度 double maxLineGap=0 ); // 線段之間的最小距離 ~~~ 下面把 HoughLinesP 函數封裝到一個類中。 ~~~ class LineFinder { private: cv::Mat img; // original image std::vector<cv::Vec4i> lines; double deltaRho; double deltaTheta; int minVote; double minLength; // min length for a line double maxGap; // max allowed gap along the line public: // Default accumulator resolution is 1 pixel by 1 degree // no gap, no mimimum length LineFinder() : deltaRho(1), deltaTheta(PI/180), minVote(10), minLength(0.), maxGap(0.) {} // Set the resolution of the accumulator void setAccResolution(double dRho, double dTheta) { deltaRho= dRho; deltaTheta= dTheta; } // Set the minimum number of votes void setMinVote(int minv) { minVote= minv; } // Set line length and gap void setLineLengthAndGap(double length, double gap) { minLength= length; maxGap= gap; } // Apply probabilistic Hough Transform std::vector<cv::Vec4i> findLines(cv::Mat& binary) { lines.clear(); cv::HoughLinesP(binary, lines, deltaRho, deltaTheta, minVote, minLength, maxGap); return lines; } // Draw the detected lines on an image void drawDetectedLines(cv::Mat &image, cv::Scalar color = cv::Scalar(255, 255, 255)) { // Draw the lines 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, 2); ++it2; } } }; ~~~ 用這個類實現圖中線段的檢測。 ~~~ int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); cv::Mat image = cv::imread("c:\\test.png"); cv::Mat contours; cv::cvtColor(image, contours, cv::COLOR_BGR2GRAY); cv::bitwise_not(contours, contours); //cv::Canny(image, contours, 155, 350); LineFinder finder; // Set probabilistic Hough parameters finder.setLineLengthAndGap(100, 20); finder.setMinVote(80); // Detect lines and draw them std::vector<cv::Vec4i> lines = finder.findLines(contours); finder.drawDetectedLines(image, cv::Scalar(0, 0, 255)); cv::namedWindow("Detected Lines with HoughP"); cv::imshow("Detected Lines with HoughP",image); return a.exec(); } ~~~ ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db69a53f.jpg "")
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看