数字图像处理的一阶导数算子
作者:互联网
1.边缘
何谓边缘?
边缘一般是指灰度变化最显著的地方。而一说到变化,很容易就能想到用导数,在二维图像中,导数就变成了梯度。因此可以将边缘认为是图像梯度的极值。
2.图像的梯度
①概念部分
图像梯度可以表示为:
图像梯度的方向:
梯度的幅度:
以x方向为例,梯度的计算公式为:
因为图像是离散的,水平方向上像素的最小间距为1,所以ϵ=1,所以将上面公式进行离散化表示:
直白的意思就是相邻两个像素点的差值。
那么离散后的幅度为:
为了降低计算量,平方和开方可近似看作绝对值,即:
②例子
在实际情况下x变化方向应该是竖直方向的,为了省空间我把它写成横着了。
③用梯度算子获取梯度图
下面尝试着获取图片的梯度图:
可以看出,梯度图里的一些梯度较大值能够大致描绘出图像的边缘信息。
④更多的梯度算子
将上述的梯度算子与原图作卷积即可得到梯度图像。结果图如下:
⑤测试代码
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
#计算梯度图
def calculate_gradient(image,filter_x,filter_y):
row=image.shape[0]
column=image.shape[1]
filter_r=filter_x.shape[0]
filter_c=filter_x.shape[1]
gradient = np.zeros((row, column))
for i in range(1, row - 1):
for j in range(1, column - 1):
gradient_x = 0
gradient_y = 0
for k in range(filter_r):
for l in range(filter_c):
gradient_x += image[i + k - 1, j + l - 1] * filter_x[k, l]
gradient_y += image[i + k - 1, j + l - 1] * filter_y[k, l]
gradient[i, j] = abs(gradient_x) + abs(gradient_y)
return gradient
def rgb2gray(rgb):
return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
def show_img(image_path):
img=plt.imread(image_path)
img_gray=rgb2gray(img)
plt.figure()
plt.subplot(1, 3, 1)
plt.title("原图")
plt.imshow(img)
plt.subplot(1,3,2)
plt.title("灰度图")
plt.imshow(img_gray,cmap='gray') # plt.imshow()函数默认显示三通道图像,若把灰度图当作彩色图图片会变绿
plt.subplot(1,3,3)
plt.title("梯度图")
gradient=calculate_gradient(img_gray,roberts_x,roberts_y) # 计算一阶导数得到梯度图
# gradient = calculate_gradient(img_gray, prewitt_x, prewitt_y)
# gradient = calculate_gradient(img_gray, sobel_x, sobel_y)
plt.imshow(gradient,cmap='gray')
plt.show()
roberts_x=np.array([[1,0],
[0,-1]])
roberts_y = np.array([[0, -1],
[1, 0]])
prewitt_x= np.array([[-1, 0,1],
[-1,0, 1],
[-1,0, 1]])
prewitt_y= np.array([[1,1,1],
[0,0,0],
[-1,-1, -1]])
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]])
def show_pic(image_path):
img = plt.imread(image_path)
img_gray = rgb2gray(img)
plt.figure()
plt.subplot(1, 3, 1)
plt.title("roberts")
plt.imshow(calculate_gradient(img_gray,roberts_x,roberts_y),cmap='gray')
plt.subplot(1, 3, 2)
plt.title("prewitt")
plt.imshow(calculate_gradient(img_gray, prewitt_x, prewitt_y), cmap='gray')
plt.subplot(1, 3, 3)
plt.title("sobel")
plt.imshow(calculate_gradient(img_gray, sobel_x, sobel_y), cmap='gray')
plt.show()
show_pic("lena.jpg")
参考:
https://blog.csdn.net/saltriver/article/details/78987096
标签:gray,plt,img,gradient,梯度,数字图像处理,filter,一阶,算子 来源: https://blog.csdn.net/coolyuan/article/details/116330159