
个人学习笔记:用sobel算子将RGB图片的轮廓提取出来
分成两个步骤:
1、将RGB转为灰度图:
分别对三个通道进行计算,RGB代表红绿蓝三种颜色,这个公式的含义就是对三种颜色进行加权处理,获得最后的灰度图(opencv提供了RGB2GRAY的功能,可以作为对比)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import numpy as np import imageio def rgb2gray(rgb): """ convert rgb image into gray Args: rgb: grb image with numpy type Returns: gray: gray image """ gray = rgb[:, :, 0] * 0.299 + rgb[:, :, 1] * 0.587 + rgb[:, :, 2] * 0.114 return gray image_in = imageio.imread("desk.jpg") gray = rgb2gray(image_in) imageio.imsave(im=gray.astype(np.uint8), uri="gray_image.jpg")
下面首先来看一下原始的RGB图(上自习的时候拍的,水平和垂直边缘都很多啊):

然后就是转换以后的灰度图,现在只能感受到亮度差,看不出来颜色是什么了:

2、将灰度图用sobel算子处理
sobel算子可以用来提取图片的边缘,那么什么是图片的边缘呢?我的认为,就是比如颜色图片或者是物体的轮廓(纯粹个人理解)。据说啊,sobel算子并没有发表在论文中,仅仅是在一次博士生讨论会中提出来的,这么厉害的东西居然没有发论文,要是引用的时候参考文献怎么写?有点跑题。。。
sobel模板就是3x3的矩阵,分为水平检测和垂直检测。之前看数字图像处理就感觉很玄幻,不知道为什么下面这种卷积核就能把图像的边缘找到:

把这个3x3的卷积核与灰度图进行卷积计算,就能得到边缘了。
现在想想,还是不太懂。感觉上看,就是右边的像素减去左边的像素:如果左边和右边的像素值越接近(同一物体或者同一颜色或者没有任何断层),那么差值就越小,也就是没有边缘;反之,如果右边和左边不是连续的,那么减法获得的结果就会很大,也就出现了轮廓。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31def sobel(image): """ implement sobel compute on a single gray image Args: image: a gray image Returns: the image that have been processd by sobel Raises: ValueError: the input's shape image must bigger than sobel(3x3) """ # change the data type of input image into np.uint8(cheaper compute cost) image = image.astype(np.uint8) assert len(image.shape) == 2 if image.shape[0] < 3 or image.shape[1] < 3: raise ValueError("The width and height of input image must bigger than 3") # create temp image container sobel_image_x = np.zeros(shape=image.shape) sobel_image_y = np.zeros(shape=image.shape) # create sobel sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) sobel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]]) for i in range(image.shape[0]-2): for j in range(image.shape[1]-2): # have to use np.abs() to make sure the value is positive sobel_image_x[i, j] = np.abs(np.sum(image[i:i+3, j:j+3] * sobel_x)) sobel_image_y[i, j] = np.abs(np.sum(image[i:i+3, j:j+3] * sobel_y)) sobel_image = np.sqrt(sobel_image_x*sobel_image_x + sobel_image_y*sobel_image_y).astype(np.uint8) return sobel_image
上面的代码流程如下:
(1)数据类型转换与输入数据尺寸检测
(2)创建X和Y方向的边缘图像容器,定义sobel算子
(3)卷积(求abs,也就是绝对值,是因为差值可能是负数)
1
2
3
4image_in = imageio.imread("desk.jpg") rgb = rgb2gray(image_in) sobel_image = sobel(rgb) imageio.imsave(im=sobel_image, uri="sobel_image.jpg")
处理前后 对比 :

最后
以上就是等待月光最近收集整理的关于sobel算子_用sobel算子提取图片内容的轮廓的全部内容,更多相关sobel算子_用sobel算子提取图片内容内容请搜索靠谱客的其他文章。
发表评论 取消回复