大家好,欢迎来到IT知识分享网。
前言
上节课我们学习了梯度的知识,学习了如何去计算梯度,本节我们继续学习计算梯度的方法,本节我们学习使用Sobel算子计算梯度,这与上节课梯度计算方法有所不同,一般如果需要准确地计算图像的梯度信息,特别是对边缘信息感兴趣,通常会选择Sobel、Scharr或Laplacian算子。而如果更关注形态学特征或者想要一种简单快速的边缘检测方法,可以考虑使用cv2.morphologyEx。
一、sobel算子的概念
二、sobel算子的计算方式
sobel算子包括两个3×3的卷积核,分别用于计算图像在水平和垂直方向上的梯度。
Gx是水平方向的梯度,Gy是垂直方向的梯度,最终2个值的绝对值相加就是最终的梯度结果。
这2个卷积核的内容如下:
我们来分析一下这个公式:卷积核内容为什么要这样设置,以及这个公式为什么这样计算,有什么底层的逻辑。
首先我们看下横向梯度的计算方式,假如卷积核覆盖的图像像素点如下:
那结合上面的横向卷积核的内容 他的计算公式为:(p3-p1)+(2p6-2p4)+(p9-p7).
而卷积核的内容实际上是代表的权重。比如离中心点越近权重越高。因为我们目的是进行边缘检测,而边缘通常指的是图像中灰度变化较大的地方,而像素值的变化通常发生在边缘附近。通过将离中心点最近的像素的权重设置为2或-2,可以加大边缘处灰度变化对卷积结果的影响,从而更好地突出边缘特征。如下图:(实际卷积核不是图示这么大 图只是为了方面演示查看)
和之前课程中讲到的卷积核一样,卷积核在图像上移动
当我么卷积核范围没有灰度变化时,通过公式计算就没有产生梯度,一旦当卷积核范围产生了灰度变化 比如
通过上面公式我们计算卷积核中心点位置 也就是图像p5的位置 就有值了。
当卷积核在移动到没有灰度变化的地方 就不会产生梯度
现在有个问题:当卷积核移动到图像右边边缘时
按照我们的计算公式,右边减左边,在这个位置右边减左边肯定是小于0了,默认opencv处理是小于0的就置为0 但是我们右边也有边缘置为0就是看不到边缘了,不符合我们的要求了,那怎么办呢。在回到上面的公式
这就是我们使用绝对值的原因。
三、具体实现
import cv2 # 读取图像 image = cv2.imread('yunfeng.jpg') # 转换为灰度图像 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 使用Sobel算子计算水平方向和垂直方向的梯度 grad_x = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=3) grad_y = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=3) # 计算梯度的幅值 gradient_magnitude = cv2.magnitude(grad_x, grad_y) # 显示结果 cv2.imshow('Original', image) cv2.imshow('sobel', cv2.convertScaleAbs(gradient_magnitude)) cv2.waitKey(0) cv2.destroyAllWindows()
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/127212.html