opencv中canny演算法理解

2021-06-07 23:05:36 字數 1147 閱讀 2097

opencv canny的應用詳解參見:

canny演算法的基本步驟:

1. 獲取x,y的梯度

2. 非最大值抑制

3. 邊緣跟蹤

第乙個步驟很好理解,獲取x方向、y方向的梯度。opencv中應用sobel運算元來獲取dx,dy。

第二個步驟有點繞口費解,說白了就是在梯度方向上求最大值,來判斷此點是不是邊緣點。梯度方向上是灰度變換最大的方向,只要在這條線上,比較梯度影象的中心點的鄰域即可。如果梯度影象中,中心點大於兩個鄰域的值,則可能為邊緣點,如果小於鄰域的值,則為非邊緣點。

有的實現採用插值的方式來獲取梯度方向上中心點鄰域的值,然後進行比較。而opencv,將影象中心點梯度方向近似為4個方向 0, 45, 90 及135,直接可以利用8鄰域進行比較計算,不用插值的方法。。

這四個方向正好對應8鄰域的橫向、縱向及斜向4個方向。例如 角度 < 22.5度(pi/8) 時,橫向; 角度 > 67.5度時,縱向...

1   2   3

*  *  *

* * *  

0*******0

* * *  

*  *  *

3   2   1

其中#define tg22  (int)(0.4142135623730950488016887242097*(1<

prev_flag的作用,為1代表前乙個畫素點為邊緣點,為0代表前乙個點為非邊緣點。目的是將大於high閾值的、且其前面的仍然是邊緣點的(其實就是連續幾個點是邊緣點)點設定為可能是邊緣點,即標示此點_map[j] = (uchar)0;,不用入棧,後續採用跟蹤的方式再確定為邊緣點。

第三個步驟,採用雙閾值邊緣跟蹤。

如果是梯度在鄰域中是最大值,且大於high閾值,確定是邊緣點,然後以此為中心需找鄰域中滿足低閾值的點。

如果鄰域點滿足其點梯度最大值,且大於low閾值,確定此鄰域點為邊緣點,並遞迴此步驟。

opencv中閾值判斷放在第二步中了,而其第三步僅用來鄰域跟蹤,採用棧迴圈非遞迴的方式實現。將擴充套件已經是邊緣點的8鄰域,將可能是邊緣點的鄰域(_map中為0的點),確定為邊緣點。

其他:獲取乙個區域內的梯度最大值,能很好的細化邊緣。

本質是獲取多個梯度

比較大小

梯度最大值與 閾值比較,而且可能是被蹂躪兩次,確立邊緣點。

reference:

OpenCV中Canny邊緣檢測

具體的canny邊緣檢測原理 1 消除雜訊,使用高斯平滑濾波器卷積降噪 2 計算梯度幅值和方向。利用sobel濾波器。得到x和y方向的導數gx和gy 計算梯度的幅值和方向 g sqrt gx 2 gy 2 a arctan gx gy 梯度的方向近似到四個可能角度之一 一般0,45,90,135 3...

在OpenCV中自適應確定canny演算法的分割門限

在opencv中用canny運算元進行邊緣檢測速度很快,不過有點不爽的就是高低閾值需要輸入。在matlab中,如果不指定閾值的話,由函式自適應確 定,因此仿照matlab中的做法,對canny函式進行了修改,以便當使用者沒有指定高低閾值時,由函式自適應確定閾值。我在opencv原碼庫中增加了乙個函式...

在OpenCV中自適應確定canny演算法的分割門限

在opencv中用canny運算元進行邊緣檢測速度很快,不過有點不爽的就是高低閾值需要輸入。在matlab中,如果不指定閾值的話,由函式自適應確定,因此仿照matlab中的做法,對canny函式進行了修改,以便當使用者沒有指定高低閾值時,由函式自適應確定閾值。我在opencv原碼庫中增加了乙個函式,...