边缘检测中非极大值抑制简单解释
首先要明白的是:
(a.) canny算子中非最大抑制(Non-maximum suppression)是回答這樣一個問題: “當前的梯度值在梯度方向上是一個局部最大值嗎?” 所以,要把當前位置的梯度值與梯度方向上兩側的梯度值進行比較.
(b.) 梯度方向垂直于邊緣方向, 這一點不要誤解.
-
Q1: 插值是何意?為啥取g1,g2為一組,g3,g4為一組計算插值?
A: 首先, 雖然插值是有必要的,但是沒有說必須要插值. 例如, Wikipedia里[1]的canny算子一文中的所講的非最大值抑制就只是在0\90\45\135度梯度方向上進行的. 每個像素點梯度方向按照相近程度用這四個方向來代替,這種情況下,非最大值抑制所比較的相鄰兩個像素就是:
0 : 左邊 和 右邊
90 : 上邊 和 下邊
45 : 右上 和 左下
135: 左上 和 右下
這樣做的好處是簡單, 但是, 這種簡化的方法無法達到最好的效果, 因為, 自然圖像中的邊緣梯度方向不一定是沿著這四個方向的. 因此, 就有很大的必要進行插值, 目的是找出在一個像素點上最能吻合其所在梯度方向的兩側的像素值.
然而, 通過argtan(gx/gy)得到的方向可以是-90~90度內的任何值, 但是, 因為實際數字圖像中的像素點是離散的二維矩陣, 所以, 處在真正中心位置C處的梯度方向兩側的點是不一定存在的, 或者說是一個亞像素(sub pixel)點, 而這個不存在的點, 以及這個點的梯度值就必須通過對其兩側的點進行插值來得到.
至此, 插值的目的我講述了一遍.
舉個直觀的例子,就是上面貼的那張圖.
這個圖給出的情況是, gy > gx 且 gx*gy > 0(注意: gx*gy>0是因為圖像坐標系中y軸是朝下的.)
藍色的直線代表梯度方向. g1, g2, g3, g4四個點以及插值點dTemp1, dTemp2 的位置如圖所示.
對應的代碼是:
g1 = pnMag[nPos-imageWidth-1] ;
g3 = pnMag[nPos+imageWidth+1] ;
g2 = pnMag[nPos-imageWidth] ;
g4 = pnMag[nPos+imageWidth] ;
下面解釋, 插值公式為什么是:
dTmp1 = weight*g1 + (1-weight)*g2 ;
dTmp2 = weight*g3 + (1-weight)*g4 ;
這里: weight = fabs(gx)/fabs(gy) = ctan(theta), theta為梯度方向.
上面那個公式變一下就可以變換成:
weight = |dTemp1-g2|/|g1-g2| = |dTemp1-g2|/|C-g2| = ctan(theta);
而從我畫的圖中可以直觀的看出,
在由 <,C, g2, dTemp1>組成的三角形中, 正好符合這個公式.(這里我沒有太care正負號,只是為了給你一個直觀解釋)
講到這里,應該你的后兩個問題都不成問題了吧.
Q2: 原理上是比較3*3矩陣內相鄰像素點是不是最大值,他為何比較g1,g2,g3,g4就完事了
A: 最大值抑制中的比較最大值不是看是不是3*3矩陣內的最大值, 而是看是不是梯度方向上的局部最大值. 否則就成了一個3*3的最大值濾波了. 為什么比較g1~g4, Q1的回答中已經講清楚了.
Q3: 為何要分X,Y方向導數誰大兩種情況比較
A: 把X, Y方向導數誰大兩種情況分開只是為了編程上的方便. 你也可以分四種情況分別進行最大值抑制.
轉載自:https://bbs.csdn.net/topics/370004267 中visionfans的回答
總結
以上是生活随笔為你收集整理的边缘检测中非极大值抑制简单解释的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从技术分工的角度来看996.ICU
- 下一篇: 组合算法问题