其他分享
首页 > 其他分享> > 数字图像处理的一阶导数算子

数字图像处理的一阶导数算子

作者:互联网

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