21.霍夫變換——直線檢測

1.主要內容

  • 霍夫直線變換介紹
  • 相關API學習

2.霍夫直線變換介紹

  • Hough Line Transform用來做直線變換

  • 前提條件——邊緣檢測以及完成

  • 平面空間到極座標空間轉換

  • 通過霍夫變換我們可以進行一個規則的幾何形狀的檢測,其原理是通過極座標變化將直角座標各個點轉換到極座標空間中,形成一條一條的曲線,圖像中曲線交點所在的位置,我們認爲是同一個直線上的點,然後我們在通過將這些點的極座標再通過公式反算到直角座標空間。
    在這裏插入圖片描述

  • r是距離,在x0,y0不變的情況下,我們每給定一個theta,就得到一個r值,此時我們得到圖一中各角度與r’對應關係的曲線。
    在這裏插入圖片描述

  • 此時,我們把x0,y0向前走一個,再來求函數的極座標,theta和r,不斷的重複該操作,得到圖二所示的結果。這些曲線相交於一點,表明我們這些像素點都屬於同一條直線。
    在這裏插入圖片描述

  • 根據我們圖二得到曲線交點的角度和極徑帶入下面的式子來反算到平面空間上,輸入不同的x,得到不同的y。
    得到的座標點在圖像上則保留,不在圖像上則刪除。
    在這裏插入圖片描述

  • 問題:如何知道這就是圖像中相交的點呢?
    解答:將每條曲線所經過的地方數據加1,由於交點處的數據加的最多,那麼該點最亮。
    在這裏插入圖片描述

  • 對於任意一條直線上的所有點來講,變換到極座標中,從【0·360】空間,可以得到r的大小。屬於同一條直線上點在極座標空間【r,theta】必然在一個點上有最強的信號出現(那個交點),根據此反算到平面座標中就可以得到直線上各點的像素座標。從而得到直線。

  • 從平面座標變換到霍夫空間(極座標)
    在這裏插入圖片描述

3.相關API學習

  • 標準的霍夫變換cv::HoughLines從平面座標轉換到霍夫空間,最終輸出是(threta,r)表示極座標空間。
  • 霍夫變換直線概率cv;;HoughLinesP最終輸出是直線的兩個點(x0,y0,x1,y1)

4.相關API學習

  • cv;;HonghLines
cv::HoughLine(
    InputArray src,   //輸入圖像,必須8—bit的灰度圖像
    OutputArray lines,//輸出的極座標來表示直線
    double rho, //生成極座標的時候像素掃描步長(極座標空間中r的最大值),一般取值1
    double theta,//生成極座標的時候的角度掃描步長,一般取值CV_PI/180,每次移動一度
    int threshold,//閾值,只有獲得足夠交點的極座標點才被看成是直線
    double srn = 0,//是否應用多尺度的霍夫變換,如果不是設置0表示經典霍夫變換(此處的多尺度參考圖像金字塔的相關知識)
    double stn = 0.//是否應用多尺度的霍夫變換,如果不是設置0表示經典霍夫變換
    double min_theta = 0,//表示角度掃描範圍0-180度之間,默認即可
    double max_theta = CV_PI
)//一般是有經驗的開發者使用,需要自己反變換到平面空間
  • cv::HonghLinesP
cv::HoughLineP(
    InputArray src,   //輸入圖像,必須8—bit的灰度圖像
    OutputArray lines,//輸出的極座標來表示直線
    double rho, //生成極座標的時候像素掃描步長
    double theta,//生成極座標的時候的角度掃描步長,一般取值CV_PI/180
    int threshold,//閾值,只有獲得足夠交點的極座標點才被看成是直線
    double minlineLength = 0,//最小直線長度
    double maxLineGap = 0,//最大間隔,比較重要的一個參數
    )//自動反算到平面空間

HonghLinesP檢測效果
在這裏插入圖片描述

  • 演示代碼
//先進行邊緣檢測
imshow("原圖像",src);
Canny(src,src_gray,150,200,3);
cvtColor(src_gray,dst,CV_GRAY2BGR);
//霍夫直線檢測
vector<Vec4f>plines;//將我們霍夫變換得到的結果存放到這個數據中
HonghLinesP(src_gray,plines,1,CV_PI/180,10,0,10);
for(size_t i = 0;i < plines.size();i++){
    Vec4f  h1 = plines[i];
    line(dst,Point(h1[0],h1[1]),Point(h1[2],h1[3]),Scalar(0,0,255),3,LINE_AA);
}  
imshow("輸出圖像",dst);

5.line函數

void  line(
    Mat& img, //要繪製線段的圖像
    Point pt1,//線段的起點
    Point pt2,//線段的終點
    const Scalar& color,//線段的顏色,通過一個Scalar對象定義
    int thickness = 1,//線條的寬度
    int linetType = 8,
    //線條的類型。可以取值8,4,和CV_AA,
    //分別代表8鄰接連接線、4鄰接連接線和反鋸齒連接線
   // 默認值爲8鄰接連接線,爲了獲得更好的效果可以選用CV_AA(採用了高斯濾波)
    int shift = 0 //座標點小數點位數
)

示例:

line(frame,beginPoint,endPoint,Scalar(0,0,255),2)
//畫一條直線,起點爲beginPoint,終點爲endPoint,顏色是紅色,線寬爲2,shift是默認值

6.課外擴展

size_t 數據類型
OpenCV CV_RGB2GRAY與CV_BGR2GRAY的區別
OpenCV的Image Watch插件安裝與使用

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