1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 边缘检测Sobel laplacian canny算子

边缘检测Sobel laplacian canny算子

时间:2019-12-19 19:15:36

相关推荐

边缘检测Sobel laplacian canny算子

1.图像边缘检测

图像边缘检测对于分析图像中的内容、实现图像中物体的分割、定位等具有重要的作用。边缘检测大大减少了源图像的数据量,剔除了与目标不相干的信息,保留了图像重要的结构属性。常用的图像边缘检测方法分为以下两种:

一阶导数的边缘算子:

通过模板作为核与图像的每个像素点做卷积和运算,然后选取合适的阈值来提取图像的边缘。代表算子为sobel、scharr算子。二阶导数的边缘算子:

通过求取二阶导数为0来寻找边界,代表laplacian算子。

2.Sobel算子

2.1Sobel算子原理:

sobel算子需要先将图像转为灰度图,然后通过图像平滑操作,进行过滤噪声,然后使用sobel算子。

转化为灰度图像后用图像与卷积因子进行卷积运算。分别得到x方向和y方向的梯度值。

分别求水平Gx和竖直方向的导数Gy。

再求出该点整体的导数。得到该点的导数的方法有很多,可以用平方根的方式,或者绝对值求和等。下面展示平方根的方法。

得到的G可以与设定的阈值进行比较,如果大于某一阈值,可以认为该点为边缘点。

2.2代码实现

自定义sobel边缘检测算法:def calculate_Sobel(img, threshold):height,width = img.shape[::-1]G_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])G_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])result = np.zeros(img.shape)for i in range(0, width - 2):for j in range(0, height - 2):v = sum(sum(G_x * img[i:i + 3, j:j + 3]))h = sum(sum(G_y * img[i:i + 3, j:j + 3]))result[i + 1, j + 1] = np.sqrt((v ** 2) + (h ** 2))for i in range(0, width):for j in range(0, height):if result[i, j] < threshold:result[i, j] = 0return result

2.3API接口

cv.Sobel(src,depth,dx,dy,dst,ksize,scale,delta,borderType)

src:传入的图像

ddepth:图像的深度

dx dy:指求导的阶数。0表示这个方向上没有求导,取值为0、1。

ksize:指Sobel算子的大小,即卷积核的大小,必须为奇数1、3、5、7,默认为3。

注意:如果ksize = -1,就演变为3*3的Scharr算子。

scale:缩放导数的比例常数,默认情况为没有伸缩系数。

borderType:图像边界的模式,默认cv2.BORDER_DEFAULT。

注:Sobel算子是在两个方向计算的,最后还需要用cv2.addWeighted()函数将其组合起来.

#Api代码:x = cv2.Sobel(img, cv2.CV_16S, 1, 0)y = cv2.Sobel(img, cv2.CV_16S, 0, 1)Scale_absX = cv2.convertScaleAbs(x)Scale_absY = cv2.convertScaleAbs(y)result = cv2.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)

3.Laplacian算子

3.1laplacian算子原理

对x和y的二阶求偏导相加

因此,laplacian算子的卷积核如下。还是用图像与卷积核相乘。该点的梯度值就是周围的值相加 - 中心值的四倍。

3.2代码实现

#自定义def calculate_laplacian(img):temLaplacian = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])height, width = img.shape[::-1]result = np.zeros(img.shape)for i in range(0, width - 2):for j in range(0, height - 2):result[i + 1][j + 1] = np.abs(sum(sum(temLaplacian * img[i:i + 3, j:j + 3])))return result

API接口:

cv.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

ddepth:输出图片的数据深度

dst:输出图像,大小和类型与 src 相同

ksize:计算二阶导数滤波器的孔径大小,必须为正奇数,可选项

scale:缩放比例因子,可选项,默认值为 1

delta:输出图像的偏移量,可选项,默认值为 0

borderType:边界扩充的类型,注意不支持对侧填充(BORDER_WRAP)

4.Canny算子

Canny算子在检测算法中比较优秀。该算法的步骤如下:

1.高斯平滑进行降噪

2.计算梯度强度和方向。采用的是sobel算子

3.非极大值抑制。通常灰度变化的地方都比较集中,将局部范围内的梯度方向上,灰度变化最大的保留下来,其它的不保留,这样可以剔除掉一大部分的点。将有多个像素宽的边缘变成一个单像素宽的边缘。即“胖边缘”变成“瘦边缘”。

4.双阈值筛选。通过非极大值抑制后,仍然有很多的可能边缘点,进一步的设置一个双阈值,即低阈值(low),高阈值(high)。灰度变化大于high的,设置为强边缘像素,低于low的,剔除。在low和high之间的设置为弱边缘。进一步判断,如果其领域内有强边缘像素,保留,如果没有,剔除。

Api接口如下:

Canny(image, th1, th2, edges=None, apertureSize=None, L2gradient=None)

image参数表示8位输入图像。

threshold1参数表示设置的低阈值。

threshold2参数表示设置的高阈值,一般设定为低阈值的3倍 (根据Canny算法的推荐)。

edges参数表示输出边缘图像,单通道8位图像。

apertureSize参数表示Sobel算子的大小

blur = cv.GaussianBlur(image, (3, 3), 0)edge_output = cv.Canny(img, 50, 150)

5.总结

Laplacian算子对噪声比较敏感,由于其算法可能会出现双像素边界,常用来判断边缘像素位于图像的明区或暗区,很少用于边缘检测;Sobel算子考虑了综合因素,对噪声较多的图像处理效果更好。canny算子效果比较好,对于噪声比较敏感,结合几种不同算子的优点衍生而来。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。