1. 程式人生 > >霍夫變換-----特徵提取

霍夫變換-----特徵提取

霍夫變換:從黑白影象中檢測直線和曲線

優點:對資料的不完全或噪聲不是非常敏感。

首先對影象進行邊緣檢測的處理,即霍夫線變換的直接輸入只能是邊緣二值影象。

多尺度霍夫變換(MSHT)是經典霍夫變換(標準霍夫變換SHT)在多尺度下的一個變種。

累計概率霍夫變換(PPHT)是SHT的改進。他在一定的範圍內進行霍夫變換,計算單獨線段的方向機範圍,從而減少計算量,縮短計算時間。

標準霍夫變換SHT原理: 

霍夫變換運用兩個座標空間之間的變換,將在一個(影象)空間中具有相同形狀(數學模型+引數)的曲線或直線,對映到另一個(引數)座標空間的一個點上形成峰值,從而把檢測任意形狀的問題轉化為統計峰值問題

我們知道,一條直線在直角(影象)座標系下可以用y=kx+b表示, 霍夫變換的主要思想是將該方程的引數和變數交換,即用x,y作為(引數、係數),k,b作為(變數),所以直角座標系下的一個點(x1,y1)在直角座標系下表示為一條直線:y1=x1·k+b,其中(k,b)是該直線上的任意點;直角座標系下的一條直線y=kx+b在引數空間表示為一個點:(k,b),為了計算方便,並解決k(直線的斜率)接近無窮大的問題,使用了一種標準直線標識法,將引數空間的座標表示為極座標下的γ和θ。


因為同一條直線上的點對應的引數(k,b)/(γ,θ)是相同的,因此可以先將圖片進行邊緣檢測,然後對影象上每一個非零畫素點,在引數座標下變換為一條直線,那麼在直角座標下屬於同一條直線的點便在引數空間形成多條直線並內交於一點,這一點即為對應直線的引數,所有直線在

(γ,θ)引數空間中得到一系列對應曲線。因此可用該原理進行直線檢測。

Hough變換在計算上的吸引力在於將引數空間進一步分割為所謂的累加器單元,如圖9所示。其中(amax,amin)和(bmax,bmin)為引數值的期望範圍,一般來說,值的最大範圍是-90°<θ<90°和-D<ρ<D,其中D是影象中角點間的距離。 最初,這些單元被設定為0。然後,對於影象平面上的每一個非背景點(xk, yk),令θ等於θ軸上允許的細分值,並通過公式ρ=xkcosθ+yksinθ求出相應的ρ值。然後,將得到的ρ值四 舍五入為最接近的、ρ軸上允許的單元值,相應的累加器單元相加。在這個過程的最後,A(i,j)意味著x-y平面上的Q個點位於線xcosθj+ysinθj=ρi上。ρ-θ平面上的細分數決定了這些點共線的精度。


(1)讀取原始影象,並轉成灰度影象
(2)採用小波邊緣檢測演算法對其進行邊緣檢測,得到二值化的邊緣影象。
(3)對此邊緣影象做Hough變換。
(4)使用函式houghpeaks 做峰值檢測。函式houghpeaks的演算法如下:
       ①找到包含有最大值的Hough變換單元,並記下它的位置;
       ②把上步找到的最大值點的領域中的Hough 變換單元設為0;
       ③重複該步驟,直到找到需要的峰值數為止,或者達到一個指定的閾值時為止。
(5)一旦在Hough 變換中識別出了一組候選的峰波,則還要留待確定是否存在與這些峰值相關的線段及它們的起始和終止為止。對每一個峰值來說,第一步是找到影象中影響到峰值的每一個非0 值點的位置。為此,編寫函式houghpixls 來實現這一功能。
(6)使用函式houghlines 實現直線邊緣連線,函式houghlines的演算法如下:
       ①將畫素位置旋轉90° - θ ,以便它們大概位於一條垂直線上;
       ②按旋轉的x值來對這些畫素位置排序;
       ③使用函式diff 找到裂口。忽略掉小裂口,這將合併被小空白分離的相鄰線段;
       ④返回比最小閾值長的線段的資訊。

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

    1. 在 笛卡爾座標系: 可由引數: (m,b) 斜率和截距表示.
    2. 在 極座標系: 可由引數: (r,\theta) 極徑和極角表示
    Line variables

    對於霍夫變換, 我們將用 極座標系 來表示直線. 因此, 直線的表示式可為:

    y = \left ( -\dfrac{\cos \theta}{\sin \theta} \right ) x + \left ( \dfrac{r}{\sin \theta} \right )

    化簡得: r = x \cos \theta + y \sin \theta

  2. 一般來說對於點 (x_{0}, y_{0}), 我們可以將通過這個點的一族直線統一定義為:

    r_{\theta} = x_{0} \cdot \cos \theta  + y_{0} \cdot \sin \theta

    這就意味著每一對 (r_{\theta},\theta) 代表一條通過點 (x_{0}, y_{0}) 的直線.

  3. 如果對於一個給定點 (x_{0}, y_{0}) 我們在極座標對極徑極角平面繪出所有通過它的直線, 將得到一條正弦曲線. 例如, 對於給定點 x_{0} = 8 and y_{0} = 6我們可以繪出下圖 (在平面 \theta - r):

    Polar plot of a the family of lines of a point

    只繪出滿足下列條件的點 r > 0 and 0< \theta < 2 \pi.

  4. 我們可以對影象中所有的點進行上述操作. 如果兩個不同點進行上述操作後得到的曲線在平面 \theta - r 相交, 這就意味著它們通過同一條直線. 例如, 接上面的例子我們繼續對點: x_{1} = 9y_{1} = 4 和點 x_{2} = 12y_{2} = 3 繪圖, 得到下圖:

    Polar plot of the family of lines for three points

    這三條曲線在 \theta - r 平面相交於點 (0.925, 9.6), 座標表示的是引數對 (\theta, r) 或者是說點 (x_{0}, y_{0}), 點 (x_{1}, y_{1}) 和點 (x_{2}, y_{2}) 組成的平面內的的直線.


    說明:給定定點(x,y)在極座標對極徑極角平面會出所有通過它的直線,得到一條正弦曲線。(該曲線上任一點均表示通過定點的直線)。幾條曲線(由定點確定的)相交於一點意味著這些定點是共線的。設定直線上點的閾值(個數)來定義多少條曲線交於一點,即可檢測到一條直線。 

函式:

void 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 );

第一個引數:輸入灰度影象

第二個引數:輸出影象

第三個引數:極徑

第四個引數:極角

第五個引數:累加平面閾值

第六個引數:對於多尺寸霍夫變換,只是第三個引數進步尺寸的除數距離。rho/srn.

第七個引數:對於多尺寸霍夫變換,只是第四個引數進步尺寸的除數距離。

示例:

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;

int Dot_amount = 150;
Mat img, img1, dst;

void on_traker(int, void *)
{
	img = imread("d://temp/18.png");
	imshow("原始圖", img);
	Canny(img, img1, 150, 200, 3);
	imshow("邊緣檢測", img1);
	cvtColor(img1, dst, CV_GRAY2BGR);
	vector<Vec2f>lines;
	HoughLines(img1, lines, 1, CV_PI / 180, Dot_amount, 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(x0 - 1000 * (a));
		line(dst, pt1, pt2, Scalar(0, 0, 255), 1, LINE_AA);

	}
	imshow("H效果圖", dst);

}

int main()
{
	
	
	namedWindow("H效果圖1", WINDOW_AUTOSIZE);
	createTrackbar("點數", "H效果圖1", &Dot_amount, 250, on_traker);
	on_traker(Dot_amount, 0);
	while (1)
	{
		int key = waitKey(1);
		if ((char)key == 27)break;
	}

	return 0;
}

累計概率霍夫變換:效果很好

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

第一個引數:輸入灰度影象

第二個引數:輸出檢測的線條

第三個引數:極徑

第四個引數:極角

第五個引數:累加平面閾值

第六個引數:最低線段長度

第七個引數:點點之間的最大距離

示例:

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;

int Dot_amount = 150;
Mat img, img1, dst;

void on_traker(int, void *)
{
	img = imread("d://temp/16.jpg");
	imshow("原始圖", img);
	Canny(img, img1, 150, 200, 3);
	imshow("邊緣檢測", img1);
	cvtColor(img1, dst, COLOR_GRAY2BGR);
	vector<Vec4i>lines;
	HoughLinesP(img1, lines, 1, CV_PI / 180, Dot_amount,50, 10);
	for (size_t i = 0; i < lines.size(); i++)
	{
		Vec4i l = lines[i];
		line(dst,Point(l[0],l[1]),Point(l[2],l[3]), Scalar(0, 0, 255), 1, LINE_AA);

	}
	imshow("H效果圖", dst);

}

int main()
{


	namedWindow("H效果圖1", WINDOW_AUTOSIZE);
	createTrackbar("點數", "H效果圖1", &Dot_amount, 250, on_traker);
	on_traker(Dot_amount, 0);
	while (1)
	{
		int key = waitKey(1);
		if ((char)key == 27)break;
	}

	return 0;
}

霍夫圓變換-----------霍夫梯度法原理

霍夫圓變換的基本原理和上面講的霍夫線變化大體上是很類似的,只是點對應的二維極徑極角空間被三維的圓心點x, y還有半徑r空間取代。

void HoughCircles( InputArray image, OutputArray circles,
                               int method, double dp, double minDist,
                               double param1 = 100, double param2 = 100,
                               int minRadius = 0, int maxRadius = 0 );

  • 第一個引數,InputArray型別的image,輸入影象,即源影象,需為8位的灰度單通道影象。
  • 第二個引數,InputArray型別的circles,經過呼叫HoughCircles函式後此引數儲存了檢測到的圓的輸出向量,                       每個向量由包含了3個元素的浮點向量(x, y, radius)表示。
  • 第三個引數,int型別的method,即使用的檢測方法,目前OpenCV中就霍夫梯度法一種可以使用,它的識別符號                     為CV_HOUGH_GRADIENT,在此引數處填這個識別符號即可。
  • 第四個引數,double型別的dp,用來檢測圓心的累加器影象的解析度於輸入影象之比的倒數,且此引數允許創                    建一個比輸入影象解析度低的累加器。上述文字不好理解的話,來看例子吧。例如,如果dp= 1                          時,累加器和輸入影象具有相同的解析度。如果dp=2,累加器便有輸入影象一半那麼大的寬度和高                    度。
  • 第五個引數,double型別的minDist,為霍夫變換檢測到的圓的圓心之間的最小距離,即讓我們的演算法能明顯區                  分的兩個不同圓之間的最小距離。這個引數如果太小的話,多個相鄰的圓可能被錯誤地檢測成了一個                  重合的圓。反之,這個引數設定太大的話,某些圓就不能被檢測出來了。
  • 第六個引數,double型別的param1,有預設值100。它是第三個引數method設定的檢測方法的對應的引數。                   對當前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示傳遞給canny邊緣檢測運算元的高閾                       值,而低閾值為高閾值的一半。
  • 第七個引數,double型別的param2,也有預設值100。它是第三個引數method設定的檢測方法的對應的引數。對當前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示在檢測階段圓心的累加器閾值。它越小的話,就可以檢測到更多根本不存在的圓,而它越大的話,能通過檢測的圓就更加接近完美的圓形了。
  • 第八個引數,int型別的minRadius,有預設值0,表示圓半徑的最小值。
  • 第九個引數,int型別的maxRadius,也有預設值0,表示圓半徑的最大值。

過點(x1,y1)的所有圓可以表示為(a1(i),b1(i),r1(i)),過點(x2,y2)的所有圓可以表示為(a2(i),b2(i),r2(i)),過點(x3,y3)的所有圓可以表示為(a3(i),b3(i),r3(i)),如果這三個點在同一個圓上,那麼存在一個值(a0,b0,r0),使得 a0 = a1(k)=a2(k)=a3(k) 且b0 = b1(k)=b2(k)=b3(k) 且r0 =  r1(k)=r2(k)=r3(k),即這三個點同時在圓(a0,b0,r0)上。
從下圖可以形象的看出:

hough變換是如何檢測出直線和圓的? - 鈺央 - 計算機視覺·影象處理 首先,分析過點(x1,y1)的所有圓(a1(i),b1(i),r1(i)),當確定r1(i)時 ,(a1(i),b1(i))的軌跡是一個以(x1,y1,r1(i))為中心半徑為r1(i)的圓。那麼,所有圓(a1(i),b1(i),r1(i))的組成了一個以(x1,y1,0)為頂點,錐角為90度的圓錐面。
三個圓錐面的交點A 既是同時過這三個點的圓。

相關推薦

變換-----特徵提取

霍夫變換:從黑白影象中檢測直線和曲線。 優點:對資料的不完全或噪聲不是非常敏感。 首先對影象進行邊緣檢測的處理,即霍夫線變換的直接輸入只能是邊緣二值影象。 多尺度霍夫變換(MSHT)是經典霍夫變換(標準霍夫變換SHT)在多尺度下的一個變種。 累計概率霍夫變換(PPHT)是S

變換鐳射線中心提取(基於opencv)

平臺: VS2017 C++ OPENCV3庫 效果: 原圖 結果: 原圖: 結果: 步驟: 1.圖片預處理,引數可以自己調整 //邊緣檢測 Canny(srcImage, dstImage, 210, 250, 3); //灰度化 cvtCo

變換提取圓心座標,並擬合直線

<span style="font-family:Microsoft YaHei;font-size:14px;">#include <cmath> #include <opencv2/opencv.hpp> using namespac

20、【opencv入門】變換變換變換合輯

接收 最大 sta point hci 都在 imread 創建 滾動 一、引言   在圖像處理和計算機視覺領域中,如何從當前的圖像中提取所需要的特征信息是圖像識別的關鍵所在。在許多應用場合中需要快速準確地檢測出直線或者圓。其中一種非常有效的解決問題的方法是霍夫(Hough

『OpenCV3』變換

opencv 檢測 輸入 圖像 oat 霍夫變換 分享圖片 一條直線 ann 霍夫變換常用於檢測直線特征,經擴展後的霍夫變換也可以檢測其他簡單的圖像結構。 在霍夫變換中我們常用公式 ρ = x*cosθ + y*sinθ 表示直

opencv 簡單的實現變換(改進版)

//霍夫變換 輸入單通道二值影象 檢測直線數量 void HoughLines(Mat &img,int n) { int i,j; //行列 int row = img.rows; int col = img.cols; //極徑最大值為 對角線+寬 int max_r

影象處理(八)——變換

霍夫變換是一種特徵檢測(feature extraction),被廣泛應用在影象分析(image analysis)、電腦視覺(computer vision)以及數位影像處理(digital image processing)。 霍夫變換是用來辨別找出物件中的特徵,例如:線條。

8.變換:線條——動手編碼、演示_4

目錄 動手編碼 霍夫演示 動手編碼 我們將在這裡花一分鐘來演示一下,如何使用Matlab構建霍夫變換。 我再重複一遍,在你們的習題集上,你們要做一些Hough程式碼。 你不能使用已經存在的Hough實現,也不能使用其他任何人的Hough實現。 因為事實證明,當你去寫你

8.變換:線條——投票原理、空間、線的極座標表示_2

目錄 投票原理 霍夫空間 線的極座標表示 投票原理 就像我之前說的,檢查每一行是不可能的,即使是一臺非常非常快的電腦。 我們要做的是讓資料告訴我們,讓資料決定線在哪裡。 因為這是民主,我們該怎麼辦?   我們要做的是投票。 因此,投票是一種通用的技術

8.變換:線條——的效果、噪聲對的影響、拓展_5

目錄 霍夫的效果 噪聲對霍夫的影響 霍夫拓展 本環節結束 霍夫的效果 這裡我將給你們展示一個Hough執行在真實影象上的例子來告訴你們它做得好和做得不好。 這是一張美國足球場的照片: 這是美式足球,你知道,用的球不是圓的。 我們執行一個有味道的邊緣探測器

8.變換:線條——介紹、引數模型、直線擬合_1

目錄 介紹 引數模型 直線擬合 介紹 到目前為止,我們一直在做影象處理,你把一個影象 和 應用一些函式相加得到一個新的影象我標記為。 這很好,整個課程,實際上是整個職業生涯,數以萬計的PHD寫在影象處理上。 但這不是我們來這裡的原因。 我們來談談真正的計

8.變換:線條——基本的變換演算法、變換的複雜性、例子_3

目錄 基本的霍夫變換演算法 霍夫變換的複雜性 霍夫例子 基本的霍夫變換演算法 說到演算法,我們來看一下: 我們將使用直線的極座標引數化,極座標表示。 還有一種叫Hough累加器(陣列)的東西,它只是用來表示要收集選票的東西。 在這種情況下是二維的,箱子代表不

變換原理

看到網上一堆講原理講得亂七八糟還抄襲的部落格,把自己看懵了……轉手一wiki發現寫得很清晰,這裡貼上來供學習。 對於直角座標系(笛卡爾座標系)平面的一條直線的斜截式: y

20180911影象處理之變換

原理介紹 霍夫變換在檢測各種形狀的的技術中非常流行,如果你要檢測的形狀可以用數學表示式寫出,你就可以是使用霍夫變換檢測它。及時要檢測的形狀存在一點破壞或者扭曲也可以使用。我們下面就看看如何使用霍夫變換檢測直線。 一條直線可以用數學表示式y = mx + c 或者 = x

影象處理四:變換

一、霍夫變換思想(Hough Transform)         霍夫變換主要是利用圖片所在的空間和霍夫空間之間的變換,將圖片所在的直角座標系中具有形狀的曲線或直線對映到霍夫空間的一個點上形成峰值,從而將檢測任意形狀的問題轉化成了計算峰值的問題;

9.變換:圓——介紹、用Hough檢測圓、圓的Hough變換_1

目錄 介紹 介紹 畫好直線之後,記住,線是引數模型最簡單的形式,現在我們來看看更復雜的東西,也就是圓。 這是圓的方程,其中 a 和 b 是中心,r 是半徑: 現在我們假設半徑已知。我們只需要找到這些點的位置。 這裡有一個圓,在這個圓上有三個點,這裡的藍

OpenCV(C++) 基礎(四)-- 邊緣檢測與變換

1. 邊緣檢測 Sobel():靈活調整水平或者垂直邊緣檢測,基於高斯平滑和微分求導 void Sobel(src, dst, depth, dx, dy, ksize=3); // depth: 對應影象型別 // dx, dy: x,y方向的差分階數,控制在x,y軸上

控制閥值的變換 檢測線條

該樣例可以通過改變影象上的閥值滑動條,生成不同閥值下的影象! 發現閥值在30多的時候,畫的線條是最多的,最大的閥值200和最小的閥值不一定是畫線條數最多的! 程式碼如下: #include <opencv2/opencv.hpp> #include

Opencv2.4學習::變換(1)線變換

霍夫變換 特點: 用於識別幾何形狀 不受旋轉角度影響  線變換基本原理 對於上述不理解的,可以看下面: 對於某直線,可以過原點作其法向量,假設在 ρ為原點到直線距離 和 θ已知的情況下 因此,該直線的   截距=ρ/sin θ   ,     斜率=  -1

Opencv2.4學習::變換(2)圓變換

霍夫圓變換 基本原理  關於基本原理,其思想大概跟霍夫線變換相似,但是有兩種說法。 第一種: 在霍夫線變換中,笛卡爾X-Y直角座標系中的直線,變換到霍夫空間中則為1個點 因此類比可得,笛卡爾X-Y直角座標系中的圓,變換到abr空間中,則為一條曲線,具體如下: