人工智能之传统图像识别:sobel 算法
令 x = [[1, 0, -1], [2, 0, -2], [1, 0, -1]] y = [[1, 2, 1], [0, 0, 0], [-1, -2, -1]] ,我们可以观察得到:当图像和x 或者 y 进行卷积操作时候,若图像灰度值完全一致,那么结果就全是0,反之,如果图像的灰度值变化比较大,那么结果会是一个比较大的数据。x 和 y 的区别在于: x 检测的是横向的,y 检测的是纵向的。
通过这种方式,就可以通过值的大小分辨出哪里是边缘
代码实现如下:原代码地址来自:Sobel算法原理及代码,笔者使用的是python3.6, 对于代码少做修改,并添加了更多的注释。
代码:
from PIL import Image
import numpy as np
import matplotlib.pyplot as pyplot
import pylab
im =Image.open('test.jpg')
# 这里的im.size 是一个iterable 的数据,并且只迭代2次,分别赋值给 w 和 h
w, h = im.size
# (w,h) 是一个元组,np.zeros 的第一个参数要的是int 或者元组类型,生成一个对应的全是0的数组,这里生成的是一个,x行,y列的数组
res = np.zeros((w, h))
# 这里的 x y ,分别是卷积核,用于获得边界的
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)):
# 获得一个 3*3 的像素组成的数列
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)
var_x = sum(sum(sub * sobel_x))
var_y = sum(sum(sub * sobel_y))
var = max(abs(var_x),abs(var_y))
# 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()
网友评论