OpenCV之sobel算子详解

Brigitte ·
更新时间:2024-11-14
· 925 次阅读

原理

sobel算子是一种计算不同方向上梯度的工具。原理是使用卷积核对图像进行处理。
如果想计算x方向梯度,我们就需要这样的一个卷积核
在这里插入图片描述
以卷积核的中心为中心,将卷积核与图像上像素值一一对应,卷积核上的数字相当于系数。利用如下公式即可计算出卷积核中心的x方向梯度。
在这里插入图片描述
同理,如果想要计算y方向的梯度,卷积核应该是这样的,公式也是同理。

我们求得了某一像素x方向和y方向的梯度,那么该像素的梯度容易得出:

在这里插入图片描述
但是这个公式比较难算,所以我们一般直接把这个公式化作:
在这里插入图片描述

Sobel函数

opencv中提供给我们封装好的Sobel算子函数,不需要我们一一计算。
其构造函数如下:

cv2.Sobel(src,ddepth,dx,dy,ksize)

参数解释:

src:原图 ddepth:处理结果图像深度,一般我们都填-1,即与原图深度相同。但在这里我们需要填写cv2.CV_64F。简单来说就是如果填写-1,我们在计算梯度时产生的负数就会被程序默认为0,导致有一边的边缘出不来。而cv2.CV_64F范围更大,可以保留负数。 dx:计算x方向的梯度 dy:计算y方向的梯度 ksize:卷积核的尺寸。默认为3,即3*3的矩阵。

函数在使用时。如果我们想要计算x方向的梯度:

cv2.Sobel(src,ddepth,1,0,ksize)

反之,计算y方向的梯度

cv2.Sobel(src,ddepth,0,1,ksize)

当然,想要计算总梯度直接dx=1,dy=1也是可以的,但是效果十分不好。不建议使用这种方法。
我们通常使用的方法是按权相加法。按权相加x方向梯度和y方向梯度。使用cv2.addWeight()函数,该函数支持五个参数:

src1:第一幅图像 weight1:第一幅图像的权重 src2:第二幅图像 weight2:第二幅图像的权重 修改值

我们还要注意一件事。在我们分别计算完x、y方向的权值时,里面是有负数的。我们需要对这些负数取绝对值,否则照样会被归为0。
取绝对值的函数是cv2.convertScaleAbs(img)

例程: import numpy as np import cv2 img=cv2.imread('D://zopencv//qi.jpg',0) mask_x=cv2.Sobel(img,cv2.CV_64F,1,0)#计算x方向梯度 mask_y=cv2.Sobel(img,cv2.CV_64F,0,1) img_x=cv2.convertScaleAbs(mask_x)#取绝对值 img_y=cv2.convertScaleAbs(mask_y) mask=cv2.addWeighted(img_x,0.5,img_y,0.5,0)#按权相加 #mask=cv2.Sobel(img,cv2.CV_64F,1,1) Archie=cv2.resize(mask,None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)#图片太大了,缩小图片 cv2.imshow('Archie',Archie) cv2.waitKey(0) cv2.destroyAllWindows()

这是按权相加得到的边缘图
在这里插入图片描述
这是直接取dx=1,dy=1得到的边缘图
在这里插入图片描述
差距一目了然。


作者:嘉 禾 天 橙 国 际 大 影 院♡♡



sobel opencv

需要 登录 后方可回复, 如果你还没有账号请 注册新账号