sobel算子及python实现

简介

 sobel算子是图像边缘检测的最重要的算子之一,在机器学习、数字媒体、计算机视觉等领域起着重要作用。由Irwin Sobel在1968年的一次博士课题讨论会上提出。本文主要介绍了Sobel算子的计算过程,python实现过程和python中相关函数的介绍。方便读者实际使用。

原理

 边缘是指在图像上像素灰度变化最显著的地 方,边缘检测算子则利用图像边缘灰度的突变来检 测边缘。Sobel算子包含两组3×3的滤波器,分别对水平及垂直方向上的边缘敏感。

Gx=x1x4x7x2x5x8x3x6x9=121000121(1) (1) G x = [ x 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 ] = [ − 1 0 1 − 2 0 2 − 1 0 1 ]

Gy=x1x4x7x2x5x8x3x6x9=101202101(2) (2) G y = [ x 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 ] = [ 1 2 1 0 0 0 − 1 − 2 − 1 ]

 让两个方向模板分别沿着 x x 轴、y轴与图像做卷积,方向是从上到下和从左到右。将模板的中 心和图像上的某个像素重合,并将该像素周围的点 与模板上对应的系数相乘,如式 (3) ( 3 ) 和式 (4) ( 4 ) 所示,其 中 Gx G x Gy G y 分别代表经横向及纵向边缘检测的图像梯度值。

Gx=(x3+2x6+x9)(x1+2x3+x5)(3) (3) G x = ( x 3 + 2 x 6 + x 9 ) − ( x 1 + 2 x 3 + x 5 )

Gy=(x7+2x8+x9)(x1+2x2+x3)(4) (4) G y = ( x 7 + 2 x 8 + x 9 ) − ( x 1 + 2 x 2 + x 3 )

  图像上每个像素点的横向及纵向梯度值通过如 下式 (5) ( 5 ) 结合,来计算该点梯度值 G G 的大小:

(5)G=Gx2+Gy2

 为了减少运算时间,提高运算效率,可以使用绝 对值求和近似的方法代替开平方:

G=|Gx|+|Gy|(6) (6) G = | G x | + | G y |

  最后选取合适的阈值,将像素点的灰度值与阈 值进行比较,若大于阈值,则该点则为图像边缘点。 由于Sobel算 子对于象素的位置的影响做了加权,可以降低边缘 模糊程度,与Prewitt算子、Roberts算子相比效果更好。

python实现

 sobel算子在python中的实现有两种途径:opencv和skimage。全部代码如下:

from skimage import data,filters,img_as_ubyte
import matplotlib.pyplot as plt
import cv2

# 图像读取
img = data.camera()
plt.imshow(img,plt.cm.gray)

'''**********skimage*************'''
# sobel边缘检测
edges = filters.sobel(img)
# 浮点型转成uint8型
edges = img_as_ubyte(edges)
# 显示图像
plt.figure()
plt.imshow(edges,plt.cm.gray) 

# sobel 水平方向边缘检测
edgesh = filters.sobel_h(img)
edgesh = img_as_ubyte(edgesh)
plt.figure()
plt.imshow(edgesh,plt.cm.gray)

# sobel 竖直方向边缘检测
edgesv = filters.sobel_v(img)
edgesv = img_as_ubyte(edgesv)
plt.figure()
plt.imshow(edgesv,plt.cm.gray) 

'''**********opencv*************'''
# sobel边缘检测
edges = cv2.Sobel(img,cv2.CV_16S,1,1) 
# 浮点型转成uint8型
edges = cv2.convertScaleAbs(edges) 
plt.figure()
plt.imshow(edges,plt.cm.gray) 

# sobel 水平方向边缘检测
edges = cv2.Sobel(img,cv2.CV_16S,1,0) 
edgesh = cv2.convertScaleAbs(edgesh) 
plt.figure()
plt.imshow(edgesh,plt.cm.gray) 

# sobel 竖直方向边缘检测
edges = cv2.Sobel(img,cv2.CV_16S,0,1) 
edgesv = cv2.convertScaleAbs(edgesv) 
plt.figure()
plt.imshow(edgesv,plt.cm.gray) 
效果

原图
原图


这里写图片描述
基于skimage的全方向sobel检测


这里写图片描述
基于skimage的竖直方向sobel检测


这里写图片描述
基于skimage的水平向sobel检测


这里写图片描述
基于opencv的全方向sobel检测


这里写图片描述
基于opencv的竖直方向sobel检测


这里写图片描述
基于opencv的水平向sobel检测

以下是使用Sobel算子进行图像边缘检测的Python代码实现的示例: ```python import cv2 def sobelEdgeDetection(image_path='image.jpg'): img = cv2.imread(image_path, 0) img = cv2.resize(img, (450, 450)) sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3) sobel_x = cv2.convertScaleAbs(sobel_x) sobel_y = cv2.convertScaleAbs(sobel_y) sobel_combined = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0) cv2.imshow('Original Image', img) cv2.imshow('Sobel Edge Detection', sobel_combined) cv2.waitKey(0) cv2.destroyAllWindows() if __name__ == '__main__': sobelEdgeDetection() ``` 这段代码首先使用`cv2.imread`加载图像,然后使用`cv2.resize`调整图像的大小。接下来,分别使用`cv2.Sobel`计算水平和垂直方向上的边缘强度。`ksize=3`表示使用3x3的卷积核。然后,使用`cv2.convertScaleAbs`将结果转换为绝对值,并使用`cv2.addWeighted`将两个结果按比例相加得到最终的边缘图像。最后,使用`cv2.imshow`显示原始图像和边缘检测结果,并使用`cv2.waitKey`等待用户关闭窗口。 请注意,此代码仅为示例,你可能需要根据自己的需求进行适当的修改。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [sobel算子python实现](https://blog.csdn.net/weixin_41500849/article/details/80611263)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [Sobel(索贝尔),Scharr(沙尔)和Laplacian(拉普拉斯)算子——python实现](https://blog.csdn.net/Keep_Trying_Go/article/details/125227338)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值