日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv 霍夫线变换

發(fā)布時間:2025/4/16 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv 霍夫线变换 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

霍夫線變換

  • 霍夫線變換是一種用來尋找直線的方法.
  • 是用霍夫線變換之前, 首先要對圖像進行邊緣檢測的處理,也即霍夫線變換的直接輸入只能是邊緣二值圖像.
  • 它是如何實現(xiàn)的?

  • 眾所周知, 一條直線在圖像二維空間可由兩個變量表示. 例如:

  • 在?笛卡爾坐標系:?可由參數(shù):??斜率和截距表示.
  • 在?極坐標系:?可由參數(shù):??極徑和極角表示
  • 對于霍夫變換, 我們將用?極坐標系?來表示直線. 因此, 直線的表達式可為:

    化簡得:?

  • 一般來說對于點?, 我們可以將通過這個點的一族直線統(tǒng)一定義為:

    這就意味著每一對??代表一條通過點??的直線.

  • 如果對于一個給定點??我們在極坐標對極徑極角平面繪出所有通過它的直線, 將得到一條正弦曲線. 例如, 對于給定點??and?我們可以繪出下圖 (在平面??-?):

    只繪出滿足下列條件的點??and?.

  • 我們可以對圖像中所有的點進行上述操作. 如果兩個不同點進行上述操作后得到的曲線在平面??-??相交, 這就意味著它們通過同一條直線. 例如, 接上面的例子我們繼續(xù)對點:?,??和點?,??繪圖, 得到下圖:

    這三條曲線在??-??平面相交于點?, 坐標表示的是參數(shù)對 () 或者是說點?, 點??和點??組成的平面內(nèi)的的直線.

  • 那么以上的材料要說明什么呢? 這意味著一般來說, 一條直線能夠通過在平面??-??尋找交于一點的曲線數(shù)量來?檢測. 越多曲線交于一點也就意味著這個交點表示的直線由更多的點組成. 一般來說我們可以通過設(shè)置直線上點的?閾值?來定義多少條曲線交于一點我們才認為?檢測?到了一條直線.

  • 這就是霍夫線變換要做的. 它追蹤圖像中每個點對應曲線間的交點. 如果交于一點的曲線的數(shù)量超過了?閾值, 那么可以認為這個交點所代表的參數(shù)對??在原圖像中為一條直線.

  • 標準霍夫線變換和統(tǒng)計概率霍夫線變換

    OpenCV實現(xiàn)了以下兩種霍夫線變換:

  • 標準霍夫線變換
    • 原理在上面的部分已經(jīng)說明了. 它能給我們提供一組參數(shù)對??的集合來表示檢測到的直線
    • 在OpenCV 中通過函數(shù)?HoughLines?來實現(xiàn)
  • 統(tǒng)計概率霍夫線變換
    • 這是執(zhí)行起來效率更高的霍夫線變換. 它輸出檢測到的直線的端點?
    • 在OpenCV 中它通過函數(shù)?HoughLinesP?來實現(xiàn)

    代碼

  • 這個程序是用來做什么的?
    • 加載一幅圖片
    • 對圖片進行?標準霍夫線變換?或是?統(tǒng)計概率霍夫線變換.
    • 分別在兩個窗口顯示原圖像和繪出檢測到直線的圖像.
  • 我們將要說明的例程能從?這里?下載。 一個更高級的版本 (能同時演示標準霍夫線變換和統(tǒng)計概率霍夫線變換并帶有活動條來改變變換的閾值) 能從?這里?下載。
  • #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp"#include <iostream>using namespace cv; using namespace std;void help() {cout << "\nThis program demonstrates line finding with the Hough transform.\n""Usage:\n""./houghlines <image_name>, Default is pic1.jpg\n" << endl; }int main(int argc, char** argv) {const char* filename = argc >= 2 ? argv[1] : "pic1.jpg";Mat src = imread(filename, 0);if(src.empty()){help();cout << "can not open " << filename << endl;return -1;}Mat dst, cdst;Canny(src, dst, 50, 200, 3);cvtColor(dst, cdst, CV_GRAY2BGR);#if 0 vector<Vec2f> lines; HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 ); for( size_t i = 0; i < lines.size(); i++ ) { float rho = lines[i][0], theta = lines[i][1]; Point pt1, pt2; double a = cos(theta), b = sin(theta); double x0 = a*rho, y0 = b*rho; pt1.x = cvRound(x0 + 1000*(-b)); pt1.y = cvRound(y0 + 1000*(a)); pt2.x = cvRound(x0 - 1000*(-b)); pt2.y = cvRound(y0 - 1000*(a)); line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA); } #else vector<Vec4i> lines; HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 ); for( size_t i = 0; i < lines.size(); i++ ) { Vec4i l = lines[i]; line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA); } #endifimshow("source", src);imshow("detected lines", cdst);waitKey();return 0; }

    代碼說明

  • 加載圖片

    Mat src = imread(filename, 0); if(src.empty()) {help();cout << "can not open " << filename << endl;return -1; }
  • 用Canny算子對圖像進行邊緣檢測

    Canny(src, dst, 50, 200, 3);

    現(xiàn)在我們將要執(zhí)行霍夫線變換. 我們將會說明怎樣使用OpenCV的函數(shù)做到這一點:

  • 標準霍夫線變換

  • 首先, 你要執(zhí)行變換:

    vector<Vec2f> lines; HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );

    帶有以下自變量:

    • dst: 邊緣檢測的輸出圖像. 它應該是個灰度圖 (但事實上是個二值化圖)
    • lines: 儲存著檢測到的直線的參數(shù)對??的容器 *?rho?: 參數(shù)極徑??以像素值為單位的分辨率. 我們使用?1?像素.
    • theta: 參數(shù)極角??以弧度為單位的分辨率. 我們使用?1度?(即CV_PI/180)
    • threshold: 要”檢測” 一條直線所需最少的的曲線交點
    • srn?and?stn: 參數(shù)默認為0. 查缺O(jiān)penCV參考文獻來獲取更多信息.
  • 通過畫出檢測到的直線來顯示結(jié)果.

    for( size_t i = 0; i < lines.size(); i++ ) {float rho = lines[i][0], theta = lines[i][1];Point pt1, pt2;double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 1000*(-b));pt1.y = cvRound(y0 + 1000*(a));pt2.x = cvRound(x0 - 1000*(-b));pt2.y = cvRound(y0 - 1000*(a));line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA); }
  • 統(tǒng)計概率霍夫線變換

  • 首先, 你要執(zhí)行變換:

    vector<Vec4i> lines; HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );

    帶有以下自變量:

    • dst: 邊緣檢測的輸出圖像. 它應該是個灰度圖 (但事實上是個二值化圖) *?lines: 儲存著檢測到的直線的參數(shù)對??的容器
    • rho?: 參數(shù)極徑??以像素值為單位的分辨率. 我們使用?1?像素.
    • theta: 參數(shù)極角??以弧度為單位的分辨率. 我們使用?1度?(即CV_PI/180)
    • threshold: 要”檢測” 一條直線所需最少的的曲線交點 *?minLinLength: 能組成一條直線的最少點的數(shù)量. 點數(shù)量不足的直線將被拋棄.
    • maxLineGap: 能被認為在一條直線上的亮點的最大距離.
  • 通過畫出檢測到的直線來顯示結(jié)果.

    for( size_t i = 0; i < lines.size(); i++ ) {Vec4i l = lines[i];line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA); }
  • 顯示原始圖像和檢測到的直線:

    imshow("source", src); imshow("detected lines", cdst);
  • 等待用戶按鍵推出程序

    waitKey();
  • 結(jié)果?

    Note

    ?

    得到的結(jié)果使用的是在上面?代碼?部分提到的更高級版代碼. 霍夫線變換的代碼沒有改變, 唯一不同的是在GUI的部分加入了活動條可動態(tài)改變閾值.輸入圖像為:

    通過執(zhí)行統(tǒng)計概率霍夫線變換我們能得到下面的結(jié)果:

    當你使用滑動條來改變?閾值?的時候會觀察到檢測到線的數(shù)目的改變. 這是因為: 如果你設(shè)置了一個更大的閾值, 能檢測到的線的數(shù)目將更少 (你需要更多的點來表示一條能檢測到的直線).

    總結(jié)

    以上是生活随笔為你收集整理的opencv 霍夫线变换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。