日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【算法随记一】Canny边缘检测算法实现和优化分析。

發布時間:2025/3/8 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【算法随记一】Canny边缘检测算法实现和优化分析。 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  以前的博文大部分都寫的非常詳細,有很多分析過程,不過寫起來確實很累人,一般一篇好的文章要整理個三四天,但是,時間越來越緊張,后續的一些算法可能就以隨記的方式,把實現過程的一些比較容易出錯和有價值的細節部分加以描述,并且可能需要對算法本身有一定了解的朋友才能明白我所描述的一些過程了。

  那這個系列的開篇,我們以Canny邊緣檢測算法為頭吧。

  相關參考資料:

  1、Canny邊緣檢測算法的實現。??

  2、OpenCV(五)——超細節的Canny原理及算法實現??

  3、OpenCV 之 邊緣檢測??

  4、Opencv 3.0\opencv\sources\modules\imgproc\src\canny.cpp

? ? ? ? Canny邊緣檢測是邊緣檢測算法領域里最為著名的算法,其標準實現過程就是下面五個步驟:

?  ?1、高斯模糊。

  2、 計算梯度幅值和方向。

  3、非最大值抑制。

  4、 雙閥值。

  5、 滯后邊界跟蹤

  個人認為,第一步可以不作為標準流程,在OpenCV的實現里,也沒有他,有些文章里也說了可以用保邊濾波來代替標準的高斯模糊的過程,其實,用高斯模糊,在其他參數相同的情況下,模糊后的結果線條會更少,這是因為模糊后邊緣部分的細節有所丟失,這樣在后續的非最大值抑制步驟里強邊緣和若邊緣的數據量會有所減少。

? ? ? ?不過這個步驟帶來的另外一個好處就是,算法的計算時間會減少,這主要是由于邊緣信息的減少讓最后一步的滯后邊界跟蹤計算量大為減少。

  在計算梯度幅值和方向時,最開始的Canny算法使用的時2領域,這個計算量要少,但能表達的邊緣信息還是不夠強烈,所以現在一般都采用Sobel算子的方式,計算處X和Y方向的梯度和幅值,在幅值計算過程中,可以使用L1范數(絕對值之和),也可以使用L2范數(歐式距離),兩者在結果上還是稍有差異的,總體來說,L2范數的結果稍微好一點。

  計算這個的過程,我們可以借助SSE圖像算法優化系列九:靈活運用SIMD指令16倍提升Sobel邊緣檢測的速度(4000*3000的24位圖像時間由480ms降低到30ms)?一文的相關技巧來加速,當我們需要使用L2范數時,這個結果是個浮點數,為了提高后續的處理速度,我們可采用 LinePM[X] = sqrtf((float)((Gx * Gx + Gy * Gy) << 12));這樣的過程把他定點化,保存到unsigned short類型里,即可以節省內存,有能有利于后續的處理,而且在本例中計算的精度也能夠保證了。

  非最大值抑制過程,也就是根據當前點的梯度的方向,比較當前幅值及其周邊2個位置的幅值,如果當前幅值是他們的最大值,則該點需保留,否則,該點舍棄。那么這里的實現過程可以和后面的雙閾值處理放置在同一個過程中,這樣可以多方面提高算法速度,因為,如果當前的幅值小于小的閾值,哪怕他是局部最大值,我們也要舍棄他,所以就根本不用計算他,而在確定某個點是改保留時,通過進一步判斷其和大的閾值之間的關系,可以同時確定他是否為強邊緣,或者弱邊緣。

  在這個過程中,我們可以像OpenCV那樣采用簡易的判斷,把梯度分為[0,22.5],[22.5 ?67.5],[67.5 90]三個范圍,在小于22.5度時,只需比較當前左右兩個點的幅值,當大于67.5度時,比較上下兩個點的幅值,否則,比較對角線上兩個點的幅值。

  另外一種方式就是如下圖所示,進行插值比較: ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

  這種方式理論上講更為精確一些,但是帶來主要時計算量的增加。

? ? ? ?在采用OpenCV方法實現時,前面的幅值計算部分,我們可以考慮不用開平方,因為我們只需要比較大小,平方值大,同樣也就代表原始值大,當然這個時候我們需要對用戶輸入的LowThreshold和HighThreshold進行同步的平方處理。

? ? ? ?在滯后邊界跟蹤方面,我覺得有一篇文章講的比較好,我直接引用他的說法:?

    那么問題來了,弱邊緣到底是邊緣,還是由于噪點導致的梯度突變。

    判定依據有多種。有的人是判定弱邊緣點的8鄰域中是否存在強邊緣,如果有則將弱邊緣設置成強的。沒有就認為是假邊緣。

    另一種方案是用搜索算法,通過強邊緣點,搜索8領域是否存在弱邊緣,如果有,以弱邊緣點為中心繼續搜索,直到搜索不到弱邊緣截止。

?  ?我看大部分人用的都是第二種方案,第二種方案也有二種實現方式,一個時遞歸法,一個是普通的循環法,遞歸容易導致堆棧溢出,還是使用循環法,速度快,而且效果穩定。

  整個實現過程種,除了計算梯度和幅值時,可以使用SSE加速外,其他的過程由于有太多的判斷和使用不連續位置的內存等原因,是不太可能用SSE進行加速的。

? ? ? ?在內存占用方面,只需要梯度和幅值方面的數據(分別用signed short和unsigned short類型來保存),大約用6倍大小的圖像內存,另外,為了能處理邊緣像素,還需要一點點額外的小內存(注意在非最大值抑制時也可以使用Sobel邊緣檢測算法那個文章里的那種技巧來處理邊緣)。

  針對這個過程,我們編制了一個UI界面,比較測試各個算法的結果:

? ? ? ? ? ??

  下面進行一些簡單的測試:

? ? ? ?

          原圖                ?   ? ? ? ? ? ? ?無預處理,L1Gradient, OpenCV版抑制,低閾值50,高閾值150

? ? ???

無預處理,L2Gradient, OpenCV版抑制,低閾值50,高閾值150 ? ? ? ? ??無預處理,L1Gradient, 精確版抑制,低閾值50,高閾值150

?? ? ??

??無預處理,L2Gradient, 精確版抑制,低閾值50,高閾值150      高斯模糊0.5,L2Gradient, 精確版抑制,低閾值50,高閾值150

?? ? ?

? 高斯模糊1,L2Gradient, 精確版抑制,低閾值50,高閾值150 ? ? ? 保邊濾波,L2Gradient, 精確版抑制,低閾值50,高閾值150

  看得出,不同的配置還是有不同的效果的。但是硬要說誰號誰壞,可能還是難以肯定。

  另外,測試中發現使用精確版本的抑制在線條拐角的地方可能連續性會比OpenCV版本要好一些,不會出現斷裂。

  在耗時方面,其實這個函數的效果和很多參數還是有關的,正如前面所說,如果進行了預處理,耗時會短一些,如果低閾值越大,耗時也越短,選用OpenCV的抑制算法速度也能有所提高。測試2500*2000的灰度圖,大概需要60ms.

  測試Demo:http://files.cnblogs.com/files/Imageshop/SSE_Optimization_Demo.rar。

? ?

?

轉載于:https://www.cnblogs.com/Imageshop/p/10664478.html

總結

以上是生活随笔為你收集整理的【算法随记一】Canny边缘检测算法实现和优化分析。的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。