wordpress主题制作/深圳网站关键词优化公司
点击此处返回总目录
这节介绍Sobel算子的函数及使用。
1. Sobel函数介绍
1.1 参数ddepth ddepth指 处理结果图像深度。通常情况下,可以将该参数的值设置为-1, 让处理结果与原始图像保持一致。 但是在处理的时候,我们不采用通常的情况,也就是不写为-1。为什么呢?
如图,在计算图中黑色块位置的左右边界的Sobel算子的时候,左边界A处右边 - 左边 = -255,右边界B处 右边 - 左边 = 255。
针对-255(左边界A),因为图像像素值为0-255,所以要对-255进行处理。 一般有两种处理结果: (1)处理为0。处理为0之后就变成黑色了,如右边上图所示,就看不出来了。因此这种方法只能计算出右边界。 (2)取绝对值变成255。如右边下图所示,可以看到左右边界。我们一般采用这种方式。
在垂直方向上是同样的道理:
如果将-255处理为0,那只能得到下边界的值,得不到上边界的值。
基于上面的考虑,ddepth就不要写成-1了(-1就是指使用np.uint8,当出现负数的时候np.uint8会将负数处理为0),而是使用cv2.CV_64F,这样就能够保留-255了。
还有一个问题,既然保留了负数的值,还要变成绝对值才行。我们再使用下面的函数将负数的值变成256色位图。
后面两个参数我们不用,只用第一个就行了。
1.2 参数dx、dy 如果要计算x轴方向的边界,则dx = 1, dy = 0 如果要计算y轴方向的边界,则dx = 0, dy = 1
实际上,计算x方向的梯度,使用的是下面的卷积核:
计算y轴方向的梯度,使用的是下面的卷积核:
以上是分别计算x和y方向的梯度,但我们在计算sobel算子的时候,要用到x和y的梯度。有两种方式来计算:
第一种方式,设为1,1。这种方式不太严谨,我们更多的是使用第二种方式。 第二种方式,分别计算,然后相加dst = dx + dy。当然为了使得像素值不超过255,一般加一个系数。比如,dst = dx * 0.5 + dy * 0.5。 当然,我们不需要自己加,opencv提供了一个函数addWeighted()。
具体的计算就是:
比如:
1.3 参数kernel 核我们一般不用,不用就表示是3。如果用的话,可以设成一个奇数。 3的意思就是3行3列的卷积核。
2. Sobel函数的使用
例1:使用默认值-1,只能得到右边界
1,0表示计算x轴方向的梯度。-1表示使用np.uint8类型,这样就会把负数处理为0,从而导致左边界显示不出来。
结果:
例2:不使用默认值了,但是还是不行
结果:
不使用默认值-1了,但是结果还是只有右边界。要想出现左边界,怎么办呢?还要取绝对值。
例3:正确的得到水平边界的方法
结果:
这样左右边界就都有了。
例4:正确地得到垂直边界的方法 同理,可以求垂直方向上的梯度。
结果:
例5:正确地计算sobel算子
结果:
可以看到,把边界都计算出来了。
例6: 我们再来对比一下,两种方式计算sobel算子有什么不同。 结果:
我们可以看到最后的结果,使用方式一,不能很好的提取边界信息。 注意:我们使用别的图像,使用方式一也能得到边界,但是得到的边界不完整,这样就会导致错误,比如:
|