你的計算是正確的,但我們強烈建議您不使用atan(y/x)
定義,因爲這個計算是不認識的漸變的角度駐留在象限的,否則atan(y/x)
與如果不正確,您的組件會錯誤地將角度報告爲-45度。您應該使用atan2
。
現在內部的imgradient
是非常簡單的。我想指出imgradient
報告的角度是假設y
座標從下到上增加。另外,imgradient
應報告指向最大變化率的方位角。在圖像的情況下,這指向我們從暗像素向亮像素前進的方向。
如果您提供sobel
標誌爲imgradient
,則首先調用imgradientxy
並致電fspecial('sobel')
。事實上,imgradientxy
這部分是要記住什麼是重要的(起始線75:MATLAB R2015a):
case 'sobel'
h = -fspecial('sobel'); %// Align mask correctly along the x- and y- axes
Gx = imfilter(I,h','replicate'); %'
if nargout > 1
Gy = imfilter(I,h,'replicate');
end
注意的fspecial
輸出的負執行以及在提供的評論那條線。這是爲了確保檢測水平邊緣的掩模(即Gy
)是y-down(如其在計算機圖形學中通常已知的那樣)。具體而言,圖像的原點位於左上角,而不是左下角。
這是如何的座標系統的圖形表示在y
-down佈置:
![](https://upload.wikimedia.org/wikipedia/commons/d/d2/Clockwise_rotation.png)
來源:Wikipedia - Rotation Matrix
這樣,求出取向時,有一個額外的要求,以確保梯度的方向的角度相對於我們習慣的座標系統。因此,在找到漸變的方位角時,需要先計算角度,然後再根據標準慣例計算角度,然後再求出座標。
追求您尋求的梯度定義是傳統系統的座標從底部到頂部增加。否定是必需的,事實上,如果您檢查imgradient
的源代碼,這也恰恰是在代碼的127線(版本R2015a)正在做:
Gdir = atan2(-Gy,Gx)*180/pi; %// Radians to degrees
你可能會問自己,爲什麼有一個需要否定蒙版並在找到方向後再次否定y
座標。之所以會這樣,是因爲修改過的蒙版需要適當地捕捉到漸變的大小,所以我們將蒙版取消一次並找到漸變的大小,然後我們取消座標,以便我們可以找到相對於傳統座標的角度系統。
在你的情況下,假定Gx = 765
和Gy = -765
,用這些量入上式,得到:
>> Gy = 765;
>> Gx = -765;
>> Gdir = atan2(-Gy,Gx)*180/pi
Gdir =
-135
這是有意義的,因爲梯度方向對應於朝向變化的最大速率的方向。 -135度意味着我們指向西南方向,因爲我們正在從暗像素向光像素前進。
現在,如果您諮詢您的第三個示例圖像,imgradient
報告的角度確實是正確的。簡單地畫一條從黑暗區域到明亮區域的線條,看看它與x
軸線所成的角度,它與向右增加的列對齊。第一個角度+90度是有意義的,因爲我們從底部到頂部跟隨黑暗區域和光線。這與圖像顛倒的情況類似。第三種情況是我們以前見過的情況,第四種情況僅僅是第三種情況旋轉了180度,所以自然地,從黑暗到光線的取向角度現在是+45度,而不是先前的-135度。
非常感謝很多人!精美的解釋! –
@NavdeepSony完全沒有問題:)我很高興有幫助。祝你好運! – rayryeng
我對Gdir感到困惑。我認爲Gdir是最大強度變化的方向,邊緣總是與它正交。我對嗎?當我使用'gx = [ - 1 0 1; -2 0 2; -1 0 1]和gy = [ - 1 -2 -1; 0 0 0; 1 2 1]'我的答案與imgradient相匹配,但我無法解釋結果。例如,對於案例1:我得到了'Gdir = 90',這是一條駐留在y(y-down)上的線,我認爲這是顯示強度變化。情況2:'Gdir = -90',顯示強度向上變化,但情況3:'Gdir = -135',這是邊緣存在的角度。有什麼問題? –