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原碼庫中增加了乙個函式,...