ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-05-02 23:57:50  阅读:807  来源: 互联网

标签:gray plt img gradient 梯度 数字图像处理 filter 一阶 算子


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有