19 OpenCV霍夫直線變換HoughLines

一、霍夫變換

霍夫變換是圖像處理中從圖像中識別幾何形狀的基本方法之一,應用很廣泛,也有很多改進算法。主要用來從圖像中分離出具有某種相同特徵的幾何形狀。最基本的霍夫變換是從黑白圖像中檢測直線。在圖像處理中可以通過霍夫變換可以快速的檢測出直線或圓。

二、霍夫直線變換原理

  • 一條直線在圖像二維空間可由兩個變量表示. 如:
    <1>在笛卡爾座標系: 可由參數: 斜率和截距(m,b)表示
    <2>在極座標系: 可由參數: 極徑和極角(r, θ)表示
    在這裏插入圖片描述
  • 用極座標來表示直線,表達式爲
    在這裏插入圖片描述
    即:
    在這裏插入圖片描述
    凡是,通過點(x0,y0)的直線,都可以表示成
    在這裏插入圖片描述
    這就意味着每一對(rθ,θ)代表一條通過點(x0,y0)的直線。
  • 如果對於一個給定點(x0,y0)我們在極座標對極徑極角平面繪出所有通過它的直線, 將得到一條正弦曲線. 例如, 對於給定點x0= 8 和y0= 6 我們可以繪出下圖 (此時,rθ和θ爲變量):
    在這裏插入圖片描述
  • 對圖像中所有的點進行上述操作. 如果兩個不同點進行上述操作後得到的曲線在平面 θ-r 相交, 這就意味着它們通過同一條直線. 例如,接上面的例子我們繼續對點xxx1= 9 和yyy1= 4和點 x2= 12 和y2= 3 繪圖, 得到下圖:
    在這裏插入圖片描述
    這三條曲線在平面相交於點 (0.925, 9.6), 座標表示的是參數對 θ-r 或者是說點(x0,y0), 點(x1,y1)和點(x2,y2)組成的平面內的的直線。
  • 以上的說明表明,一般來說, 一條直線能夠通過在平面 θ-r 尋找交於一點的曲線數量來檢測。而越多曲線交於一點也就意味着這個交點表示的直線由更多的點組成. 一般來說我們可以通過設置直線上點的閾值來定義多少條曲線交於一點我們才認爲檢測到了一條直線。而霍夫變換,它追蹤圖像中每個點對應曲線間的交點. 如果交於一點的曲線的數量超過了閾值, 那麼可以認爲這個交點所代表的參數對(θ,rθ)在原圖像中爲一條直線。
  • 從平面座標變換到霍夫空間(極座標)
    在這裏插入圖片描述

三、OpenCV中的霍夫直線變換

  • 霍夫線變換是一種用來尋找直線的方法. 在使用霍夫線變換之前, 首先要對圖像進行邊緣檢測的處理,也即霍夫線變換的直接輸入只能是邊緣二值圖像
  • OpenCV支持三種不同的霍夫線變換,它們分別是:
    • 標準霍夫變換(Standard Hough Transform,SHT),由HoughLines函數調用
    • 多尺度霍夫變換(Multi-Scale Hough Transform,MSHT),由HoughLines函數調用。
    • 累計概率霍夫變換(Progressive Probabilistic Hough Transform ,PPHT),由HoughLinesP函數調用。

其中,多尺度霍夫變換(MSHT)爲經典霍夫變換(SHT)在多尺度下的一個變種。累計概率霍夫變換(PPHT)算法是標準霍夫變換(SHT)算法的一個改進,它在一定的範圍內進行霍夫變換,計算單獨線段的方向以及範圍,從而減少計算量,縮短計算時間。之所以稱PPHT爲“概率”的,是因爲並不將累加器平面內的所有可能的點累加,而只是累加其中的一部分,該想法是如果峯值如果足夠高,只用一小部分時間去尋找它就夠了,這樣可以實質性地減少計算時間。

  • HoughLines
void cv::HoughLines  ( InputArray  image,  
  OutputArray  lines,  
  double  rho,  
  double  theta,  
  int  threshold,  
  double  srn = 0,  
  double  stn = 0,  
  double  min_theta = 0,  
  double  max_theta = CV_PI  
 ) 

image: 8位單通道二進制圖像,可以載入任意圖像由函數修改成此格式
lines: 輸出直線矢量,每一條線有兩個元素的矢量(ρ
, θ)表示,ρ是離座標原點(0, 0)也就是圖像左上角的距離,θ是弧度線條旋轉角度(0度表示垂直線,π/2度表示水平線)。
rho: 以像素爲單位的距離精度,其它表述還有是直線搜索時的進步尺寸的單位半徑
theta: 以弧度爲單位的角度精度。其它表述還有是直線搜索時的進步尺寸的單位角度。
threshold: 累加平面的閾值參數,即識別某部分爲圖中的一條直線時它在累加平面中必須達到的值。大於閾值threshold的直線纔可以被檢測通過並返回到結果中
srn: 對於多尺度的霍夫變換,這是第三個參數進步尺寸rho的除數距離。粗略的累加器進步尺寸直接是第三個參數rho, 而精確的累加器進步尺寸爲rho/srn。有默認值0
stn對於多尺度霍夫變換,stn表示第四個參數進步尺寸的單位角度theta的除數距離。且如果srn和stn同時爲0, 就表示使用經典的霍夫變換,扶着這兩個參數都應該爲正數。經典霍夫變換和多尺度霍夫變換就是在這進行區分的。有默認值0

  • HoughLinesP
void cv::HoughLinesP    (   InputArray      image,
        OutputArray     lines,
        double      rho,
        double      theta,
        int     threshold,
        double      minLineLength = 0,
        double      maxLineGap = 0 
    )   

image: 8位單通道二進制圖像,可以載入任意圖像由函數修改成此格式
lines: 線段輸出矢量,每一條之先都由四個矢量元素(x1, y1, x2, y2)表示,其中(x1, y1)和(x2, y2)分別是檢測到直線線段的兩個端點。
rho: 以像素爲單位的直線搜尋步長
theta: 以弧度爲單位的直線搜尋步長
threshold: 累加器閾值參數,只有大於threshold的直線結果才能被檢測通過並返回到結果中
minLineLength: 線段長度最小值,如果線段長度小於這個值則線段結果不顯示,有默認值0
maxLineGap: 允許點連接到相同直線的中間距離的最大值,如果超過這個最大值則點不會被劃分到該直線。有默認值0

此函數在HoughLines的基礎上末尾加了一個代表Probabilistic(概率)的P,表明它可以採用累計概率霍夫變換(PPHT)來找出二值圖像中的直線,最終輸出是直線的兩個點(x0,y0,x1,y1);標準的霍夫變換HoughLines從平面座標轉換到霍夫空間,最終輸出是(θ,rθ)表示極座標空間。

四、示例

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
	//1. 讀取圖像
	Mat src, canny, dst;
	src = imread("images/12.png");
	imshow("src", src);

	//2. 獲取邊緣
	Canny(src, canny, 100, 200);
	imshow("canny", canny);
	//3. 轉成灰度圖像
	cvtColor(canny, dst, CV_GRAY2BGR);//將二值圖轉換爲RGB圖顏色空間,這裏重新創建一張空Mat也行
	//4. 霍夫變換檢測
	vector<Vec4f> plines;//保存霍夫變換檢測到的直線
	HoughLinesP(canny, plines, 1, CV_PI / 180, 10, 0, 10);//提取邊緣時,會造成有些點不連續,所以maxLineGap設大點
	//5. 顯示檢測到的直線
	Scalar color = Scalar(0, 0, 255);//設置顏色
	for (size_t i = 0; i < plines.size(); i++)
	{
		Vec4f hline = plines[i];
		line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), color, 3, LINE_AA);//繪製直線
	}
	imshow("plines", dst);

	waitKey(0);
	return 0;
}

在這裏插入圖片描述

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