您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關為什么opencv的canny函數檢測邊緣的效果和matlab的不同,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
可以明顯的看出matlab的邊緣更為細膩。
首先回顧一下傳統的canny算法的主要步驟:
1、使用sobel差分算子求出灰度圖像的x和y方向導數;
2、求出圖像各點梯度大小及其方向;
3、設置高低兩個閾值,梯度大于高閾值為強邊像素點,大于低閾值為潛在可能是較弱的邊緣點;
4、在經過一次篩選剩下的強邊緣點中沿著梯度方向進行非極大值抑制;
5、順著二次篩選后的強邊點尋找鄰近的弱邊點得到最終的邊緣。
opencv和matlab都基本按照以上步驟得到各自的canny 函數,但一般來說處理之前都先對圖像進行模糊平滑,這樣得到的效果更好。opencv更注重實時性,所以連平滑都作為可選項放在函數外,而matlab則 更注重質量,除了加入平滑操作外,還有其他一系列的優化操作,以下逐項比較。
1、模糊平滑
這一項其實對生成的邊緣效果影響十分大,平滑的越流暢則生成的邊緣越圓滑,一 般使用高斯低通濾波;那么濾波器的大小以及高斯分布的方差是兩個關鍵的參數,通過實驗確定取什么值最優,但一般用5×5和方差為2的就可以 了,opencv的cvSmooth函數可以進行平滑,一般都是使用輸入和輸出都是8位深的圖像,而matlab是把圖像轉換為浮點類型后進行平滑操作, 這樣一來從精度上說matlab就已經更勝一籌了,因為這直接決定后面的求導運算得到的兩個方向導數的精度。
2、梯度
在sobel的運用上兩者是一致的,但是求梯度的方向的算法兩者是截然不同 的,但本質一樣,效果經過筆者測試基本相同。在梯度的大小方面,opencv提供了歐式距離和哈密頓距離兩種度量方式,前者是平方和后開方,后者是直接絕 對值的加和,opencv默認使用后者,我們知道((x2+y2)/2)1/2>=(|x|+|y|)/2,以及|x|+|y|>=(x2+y2)1/2 所以理論上使用哈密頓距離也基本符合真實數值,但總歸是有精度上的差別,這也是為什么有人說opencv的canny不如matlab好的第二個原因了,在cv.h里面可以通過修改CV_CANNY_L2_GRADIENT來進行切換。
3、閾值
這里的閾值是梯度大小是否能夠通過的開關,opencv的閾值都采用手工設置的方式,而matlab是把所有點的強度作出直方圖,保留一定百分比的強邊緣,這個步驟的差別不會影響結果的質量,但是在速度上當然會有差別,這是速度和方便程度的矛盾。
4、薄邊效果
經過非極大值抑制后的邊緣基本上是一到兩個像素點的寬度,最終希望得到一個線 寬的邊緣,opencv只是通過簡單的判斷來防止并行或者并列出現兩個強邊像素,這種簡單的薄邊手法會導致邊緣的斷裂,而matlab采用了Louisa Lam, Seong-Whan Lee, and Ching Y. Wuen, "Thinning Methodologies-A Comprehensive Survey," IEEE TrPAMI, vol. 14, no. 9, pp. 869-885, 1992. 這邊文章的方法進行兩次薄邊處理,效果相當好,所得的邊緣十分圓滑。
綜上所述,要想opencv的效果和matlab的差不多就必須在平 滑上下功夫,梯度的大小要用歐式距離度量,另外要加入matlab的薄邊算法,這樣一來處理時間大概會增加一倍,但也基本可以滿足實時處理。另外在一般視 覺應用中可以把算法修改為一個閾值,去掉強弱邊連接這一步驟以提高速度.
關于為什么opencv的canny函數檢測邊緣的效果和matlab的不同就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。