sobel算子针对被检测点,在像素点灰度计算过程中,考虑到了像素点3*3领域上的8个方向的像素点,并将所有点的灰度值进行加权差,并根据加权差的结果来确定被检测点的灰度值。
Gx:
-1 | 0 | +1 |
---|---|---|
-2 | 0 | +2 |
-1 | 0 | +1 |
Gy:
-1 | -2 | -1 |
---|---|---|
0 | 0 | 0 |
+1 | +2 | +1 |
查过很多论文对于下面写法,发现很多论文是通过坐标系理论来进行表示。但是实际上,当我们在代码实现的过程中,是通过像素值和模板进行卷积,所以这和理论上还是有一个小差距。
坐标系:
x-1, y-1 | x, y-1 | x+1, y-1 |
---|---|---|
x-1, y | x, y | x+1, y |
x-1,y+1 | x, y+1 | x+1, y+1 |
Gx=(-1)*f(x-1, y-1)+0*f(x, y-1)+(+1)*f(x+1,y-1)+
(-2)*f(x-1, y)+0*f(x, y)+(+2)*f(x+1,y)+
(-1)*f(x-1, y+1)+0*f(x, y+1)+(+1)*f(x+1,y+1)
Gx=(+1)*f(x-1, y-1)+(+2)*f(x, y-1)+(+1)*f(x+1,y-1)+
(0)*f(x-1, y)+0*f(x, y)+(0)*f(x+1,y)+
(-1)*f(x-1, y+1)+(-2)*f(x, y+1)+(-1)*f(x+1,y+1)
数组表示像素值表示:
x-1, y-1 | x-1, y | x-1, y+1 |
---|---|---|
x, y-1 | x, y | x, y+1 |
x+1,y-1 | x+1, y | x+1, y+1 |
Sobel算子详细代码,与数学公式完全对照,例如:
import Image
import numpy as np
import matplotlib.pyplot as pyplot
import pylab
im =Image.open('Bikesgray.jpg')
w,h = im.size
res = np.zeros((w, h))
sobel_x =[[-1, 0, 1],[-2, 0, 2],[-1, 0, 1]]
sobel_y =[[-1, -2, 1],[0, 0, 0],[1, 2, -1]]
for x in range(1, (w-1)):#注意初始值问题,是从第二个开始的
for y in range(1, (h-1)):
sub =[[im.getpixel((x-1, y-1)), im.getpixel((x-1, y)), im.getpixel((x-1, y+1))],\
[im.getpixel((x, y-1)), im.getpixel((x, y)), im.getpixel((x, y+1))], \
[im.getpixel((x+1, y-1)), im.getpixel((x+1, y)), im.getpixel((x+1, y+1))]]
sub = np.array(sub)
roberts_x = np.array(sobel_x)
roberts_y = np.array(sobel_y)
var_x =sum(sum(sub * sobel_x))
var_y = sum(sum(sub * sobel_y))
#var = max(abs(var_x),abs(var_y))备注1
var = abs(var_x) + abs(var_y)
res[x][y] = var#把var值放在x行y列位置上
pyplot.imshow(res, cmap=pyplot.cm.gray)#输出图片可能颜色有问题,用cmap=pyplot.cm.gray进行改颜色
pylab.show()
备注1:
标准的求方是求梯度变化率,也就是求梯度的二范数(欧式距离),但是这个需要平方还要开根,所以为了计算简便不会直接用标准算法,而是用其他简单的代替:
1.用1范数代替,即S=|Gx|+|Gy|
2.用最大范数代替,即S=max(|Gx|,|Gy|)