網(wǎng)站首頁 編程語言 正文
Gaussian smoothing
總的來說,Canny邊緣檢測可以分為四個步驟:
由于邊緣檢測對噪聲敏感,因此對圖像應(yīng)用高斯平滑以幫助減少噪聲。
具體做法是,采用一個5*5的高斯平滑濾波器對圖像進(jìn)行濾波處理。
Computing the gradient magnitude and orientation
對平滑后的圖像,在水平、垂直兩個方向上使用Sobel算子(如下圖)計算梯度大小,得到兩個方向上的一階導(dǎo)數(shù)Gx與Gy。
在得到兩個方向上的梯度之后,對這兩個向量求和,得到這一點處的梯度大小與方向。
采用四舍五入,將梯度方向確定為上下左右與四個對角線方向之一(45°的倍數(shù))。
Non-maxima suppression
在得到梯度大小與方向之后,對圖像進(jìn)一步掃描,去除不構(gòu)成邊緣的不重要的像素信息,這里采用的方法是非極大值抑制——在每個像素處,檢查像素是否在其梯度方向的鄰域中是局部最大值,只保留局部最大值的梯度。
在上圖中,點A位于邊緣上。梯度方向與邊緣方向垂直。為了確定要不要保留A點作為邊緣,需要將A點處的梯度大小與B、C兩點的梯度大小比較,如果A點的梯度大小不是局部最大,則將該點抑制。
因此,從結(jié)果上講,NMS其實是將B、C兩點抑制了,它們不會出現(xiàn)在結(jié)果中,因此這一步的效果是“thin edges”。
Hysteresis thresholding
定義上界與下界兩個閾值,并規(guī)定:
- 任何梯度強(qiáng)度大于上界的像素都是邊;
- 任何梯度強(qiáng)度小于下界的像素都不是邊;
- 任何梯度介于兩個閾值之間的可能是邊,此時考察它們的連通性,如果它們和第一種情況(確定是邊緣的像素)相連接,就認(rèn)為它們是邊緣,否則認(rèn)為它們不是邊緣。
在上圖中,A點在maxVal閾值之上,確定是邊緣。C介于兩個閾值之間,但與A相連,因此它也是邊緣。B介于兩個閾值之間,它所在的曲線上并沒有任何像素點的梯度強(qiáng)度在maxVal之上,因此它不是邊緣。
需要指出的是,上面四步操作之后得到的是strong edges。
OpenCV實現(xiàn)
OpenCV提供了cv.Canny()方法,該方法將輸入的原始圖像轉(zhuǎn)換為邊緣圖像。
該方法的原型為:
cv.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]]) -> edges
cv.Canny(dx, dy, threshold1, threshold2[, edges[, L2gradient]]) -> edges
image參數(shù)是array格式的輸入圖像。threshold1與threshold2分別是我們的下界閾值與上界閾值。apertureSize是用于查找圖像梯度的Sobel核的大小,默認(rèn)為3。L2gradient指定了求梯度幅值的公式,是一個布爾型變量,默認(rèn)為False。當(dāng)它為True時,使用L2,否則使用L1。
下面是具體代碼:
def canny_detect(image_path, show=True):
# 讀取圖像
image = cv2.imread(image_path, 0)
# 獲取結(jié)果
edges = cv2.Canny(image, 100, 200)
if show:
# 繪制原圖
plt.subplot(121)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.xticks([])
plt.yticks([])
# 繪制邊緣圖
plt.subplot(122)
plt.imshow(edges, cmap='gray')
plt.title('Edge Image')
plt.xticks([])
plt.yticks([])
plt.show()
return edges
canny_detect('images/2.jpeg')
效果:
原文鏈接:https://blog.csdn.net/qq_41112170/article/details/125728783
相關(guān)推薦
- 2022-05-13 分布式架構(gòu)Redis中有哪些數(shù)據(jù)結(jié)構(gòu)及底層實現(xiàn)原理_Redis
- 2022-08-12 python利用winreg生成桌面路徑及實現(xiàn)掃描二維碼圖片返回相關(guān)信息_python
- 2022-10-15 C++回調(diào)函數(shù)實現(xiàn)計算器和qsort_C 語言
- 2021-12-05 C語言SetConsoleCursorInfo函數(shù)使用方法_C 語言
- 2021-11-25 Linux命令unzip詳解_Linux
- 2022-06-16 docker?maven?plugin快速部署微服務(wù)的詳細(xì)流程_docker
- 2022-10-02 C++數(shù)據(jù)結(jié)構(gòu)之紅黑樹的實現(xiàn)_C 語言
- 2022-05-07 以tensorflow庫為例講解Pycharm中如何更新第三方庫_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支