imgproc模組 霍夫圓變換

2021-08-02 16:12:39 字數 3282 閱讀 5022

1.目的

(1)如何使用opencv的houghcircles在影象中檢測圓區域

2.原理

[1]標準霍夫變換

霍夫圓變換可以根據霍夫線變換來實現 ,通過極座標來表示圓(a,b)表示圓心,r表示半徑,則圓表示為:

x = a + rcosθ

y = b + rsinθ

θ的值為0-360

一開始我們假設r是已知的,那麼我們就可以把x,y空間的公式變換為關於a、b空間的公式:

a = x1 – rcosθ

b = y1 – rsinθ

x1、y1為x、y空間中的每乙個非零畫素點,如此一來,後面的變換就可以跟霍夫線變換一樣操作了。

具體操作步驟為:

①、讀取一副影象

②、檢測邊緣,產生一副二值影象

③、對於每個非零畫素轉換到ab空間中

④、對於每個ab空間中的點,進行累加

⑤、提取數量最多的點作為圓點

ps:在上面提到r是假設已知的,那麼當r是未知的情況怎麼辦?其實很簡單,就是將r設定為1、2、3……這樣子已知下去,慢慢試,再對r和圓心數量進行閾值就可以了。

[2]霍夫梯度法

霍夫梯度法的原理是這樣的。

首先對影象應用邊緣檢測,比如用canny邊緣檢測。

然後,對邊緣影象中的每乙個非零點,考慮其區域性梯度,即用sobel()函式計算x和y方向的sobel一階導數得到梯度。

利用得到的梯度,由斜率指定的直線上的每乙個點都在累加器中被累加,這裡的斜率是從乙個指定的最小值到指定的最大值的距離。

同時,標記邊緣影象中每乙個非0畫素的位置。

然後從二維累加器中這些點中選擇候選的中心,這些中心都大於給定閾值並且大於其所有近鄰。這些候選的中心按照累加值降序排列,以便於最支援畫素的中心首先出現。

接下來對每乙個中心,考慮所有的非0畫素。

這些畫素按照其與中心的距離排序。從到最大半徑的最小距離算起,選擇非0畫素最支援的一條半徑。

如果乙個中心收到邊緣影象非0畫素最充分的支援,並且到前期被選擇的中心有足夠的距離,那麼它就會被保留下來。

這個實現可以使演算法執行起來更高效,或許更加重要的是,能夠幫助解決三維累加器中 會產生許多雜訊並且使得結果不穩定的 稀疏分布問題。

霍夫梯度法的缺點:

<1> 在霍夫梯度法中,我們使用sobel導數來計算區域性梯度,那麼隨之而來的假設是,其可以視作等同於一條區域性切線,並這個不是乙個數值穩定的做法。在大多數情況下,這樣做會得到正確的結果,但或許會在輸出中產生一些雜訊。

<2> 在邊緣影象中的整個非0畫素集被看做每個中心的候選部分。因此,如果把累加器的閾值設定偏低,演算法將要消耗比較長的時間。

<3> 因為中心是按照其關聯的累加器值的公升序排列的,並且如果新的中心過於接近之前 已經接受的中心的話,就不會被保留下來。且當有許多同心圓或者是近似的同心圓時,霍夫梯度法的傾向是保留最大的乙個圓。可以說這是一種比較極端的做法,因 為在這裡預設sobel導數會產生雜訊,若是對於無窮解析度的平滑影象而言的話,這才是必須的。 (實際上可以設定min_dist來解決該問題)

ps:opencv中實現的是霍夫梯度法

3.部分**解釋

(1)houghcircles

/*

houghcircles引數解釋

edge:通過邊緣檢測獲得的二值影象,一般可以使用canny邊緣檢測運算元

circles:檢測到的圓的引數(圓心point([0],[1]),半徑radius([2]))

cv_hough_gradient:霍夫梯度法

dp = 1:累加器影象的反比解析度

min_dist = src_gray.rows/8: 檢測到圓心之間的最小距離

param_1 = 200: canny邊緣函式的高閾值

param_2 = thresh:圓心檢測閾值

min_radius:最小能夠檢測的圓大小

max_radius:最大能夠檢測的圓大小

ps:min_radius, max_radius預設值為0,當max_radius設定為0時候,可以檢測任意大小的圓

*/houghcircles(edge, circles, cv_hough_gradient, 1, edge.rows/8, 200, thresh, 0, edge.rows/2);

4.完整**

(1)commoninclude.h

#ifndef common_include

#define common_include

#include

#include

using

namespace

std;

#include

#include

#include

using

namespace cv;

#endif

(2)houghcircles.cpp

#include"commoninclude.h"

int thresh = 50;

int max_thresh = 200;

mat src, gray, edge, dst;

char windowname = "houghcircles";

void houghcirclestrans(int, void*)

imshow(windowname, dst);

}int main(int argc, char** argv)

src = imread(argv[1]);

if(!src.data)

namedwindow(windowname, cv_window_autosize);

//高斯平滑,去除雜訊

gaussianblur(src, src, size(5,5), 0, 0);

//轉換成灰度影象

cvtcolor(src, gray, cv_bgr2gray);

imshow("gray", gray);

//canny邊緣檢測

canny(gray, edge, 50, 200, 3);

createtrackbar("thresh", windowname,

&thresh, max_thresh,

houghcirclestrans);

houghcirclestrans(0,0);

waitkey(0);

return(0);

}

參考文獻

1.

缺點 霍夫圓 霍夫圓變換

對於直線來說,一條直線能有引數極徑級角表示,而對圓來說我們需要三個引數來表示乙個圓 在opencv中,我們常常通過乙個叫 霍夫梯度法 的方法來解決圓變換的問題。霍夫梯度法的原理 1 首先對影象應用邊緣檢測,比如canny邊緣檢測 2 然後對邊緣影象中的每乙個非零點,考慮其區域性梯度,即用sobel函...

霍夫圓變換

對於直線來說,一條直線能有引數極徑級角表示,而對圓來說我們需要三個引數來表示乙個圓 在opencv中,我們常常通過乙個叫 霍夫梯度法 的方法來解決圓變換的問題。霍夫梯度法的原理 1 首先對影象應用邊緣檢測,比如canny邊緣檢測 2 然後對邊緣影象中的每乙個非零點,考慮其區域性梯度,即用sobel函...

缺點 霍夫圓 霍夫變換

霍夫變換是一種特徵提取,被廣泛應用在影象分析 電腦視覺以及數字影像處理。霍夫變換是用來辨別找出物件中的特徵,例如 線條。他的演算法流程大致如下,給定乙個物件 要辨別的形狀的種類,演算法會在引數空間中執行投票來決定物體的形狀,而這是由累加空間 accumulator space 裡的區域性最大值來決定...