人工智能第5课-Canny边缘检测算法、透视变换

边缘提取

1. 边缘提取

梯度:记向量(矢量)
滤波/卷积
边缘有正负之分,就像导数有正值也有负值一样:由暗到亮为正,由亮到暗为负
求边缘幅度的算法:sobel、prewitt、laplace、Canny算子

2. 图像锐化

图像锐化是为了突出图像上的物的边缘、轮廓,或某些线性目标要素的特征。这种滤波方法提高了地物边缘与周围像元之间的反差,因此也被称为边缘增强。

图像平滑

目的是使图像亮度平缓渐变,减小突变梯度,改善图像质量。
在这里插入图片描述

3. Prewitt、Sobel算子

Sobel算子

对x方向求导,得到的是y方向的边缘;
对y方向求导,得到的是x方向的边缘。
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
dst = cv2.addWeighted(absX,0.5,absY,0.5,0)

Prewitt算子

就是图像平滑 Gx,Gy

4. Canny边缘检测算法

  1. 对图像进行灰度化
  2. 对图像进行高斯滤波:
    根据待滤波的像素点及其邻域点的灰度值按照一定的参数规则进行加权平均。这样可以有效滤去理想图像中叠加的高频噪声。
  3. 检测图像中的水平、垂直和对角边缘(如Prewitt,Sobel算子等)。
  4. 对梯度幅值进行非极大值抑制(非极大值抑制,简称为NMS算法,英文为Non-Maximum Suppression。其思想是搜素局部最大值,抑制非极大值。)
    1. 将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。
    2. 如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为边缘点,否则该像素点将被抑制(灰度值置为0)在这里插入图片描述
      根据C点坐标求梯度,求dTmp1,dTmp2,用插值算法求f(x,y)像素值。
      如果c>tmp1 and c > tmp2
  5. 用双阈值算法检测和连接边缘
    4-5步是Canny的重点-做减法。
    在这里插入图片描述

代码:

# -*- coding: utf-8 -*-
'''@Time: 2024/5/5 17:43

'''
import numpy as np
import matplotlib.pyplot as plt
import math

if __name__ == '__main__':
    pic_path = '../lenna.png'
    img = plt.imread(pic_path)
    print("image", img)
    if pic_path[-4:] == '.png':  # .png图片在这里的存储格式是0到1的浮点数,所以要扩展到255再计算
        img = img * 255  # 还是浮点数类型
    img = img.mean(axis=-1)  # 取均值的方法进行灰度化

    # 1、高斯平滑
    # sigma = 1.52  # 高斯平滑时的高斯核参数,标准差,可调
    sigma = 0.5  # 高斯平滑时的高斯核参数,标准差,可调
    dim = 5  # 高斯核尺寸
    Gaussian_filter = np.zeros([dim, dim])  # 存储高斯核,这是数组不是列表了
    tmp = [i - dim // 2 for i in range(dim)]  # 生成一个序列
    n1 = 1 / (2 * math.pi * sigma ** 2)  # 计算高斯核
    n2 = -1 / (2 * sigma ** 2)
    for i in range(dim):
        for j in range(dim):
            Gaussian_filter[i, j] = n1 * math.exp(n2 * (tmp[i] ** 2 + tmp[j] ** 2))
    Gaussian_filter = Gaussian_filter / Gaussian_filter.sum()#归一化
    dx, dy = img.shape
    img_new = np.zeros(img.shape)  # 存储平滑之后的图像,zeros函数得到的是浮点型数据
    tmp = dim // 2
    img_pad = np.pad(img, ((tmp, tmp), (tmp, tmp)), 'constant')  # 边缘填补
    for i in range(dx):
        for j in range(dy):
            img_new[i, j] = np.sum(img_pad[i:i + dim, j:j + dim] * Gaussian_filter)
    plt.figure(1)
    plt.imshow(img_new.astype(np.uint8), cmap='gray')  # 此时的img_new是255的浮点型数据,强制类型转换才可以,gray灰阶
    plt.axis('off')

    # 2、求梯度。以下两个是滤波用的sobel矩阵(检测图像中的水平、垂直和对角边缘)
    sobel_kernel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
    sobel_kernel_y = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]])
    img_tidu_x = np.zeros(img_new.shape)  # 存储梯度图像
    img_tidu_y = np.zeros([dx, dy])
    img_tidu = np.zeros(img_new.shape)
    img_pad = np.pad(img_new, ((1, 1), (1, 1)), 'constant')  # 边缘填补,根据上面矩阵结构所以写1
    for i in range(dx):
        for j in range(dy):
            img_tidu_x
  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值