数字图像处理-6-图像的边缘检测的各种算子

1.卷积核运算

1.1 2个卷积核运算

分别应用两个卷积核,取两个绝对值结果的逐像素最大值。它的原理也不复杂,就是根据传入的2个卷积核,像素运算后取较大值为当前像素值.

    Prewitt / Sobel 等算子用水平核检测垂直边缘、竖直核检测水平边缘,
    取最大值可以响应任意方向的边缘,不遗漏。

    G(x, y) = max(|G1(x, y)|, |G2(x, y)|)
  • python代码
def apply_two_kernels_max(img, kernel1, kernel2, kernel_h, kernel_w, coeff=1.0):
    width, height = img.width, img.height
    result = Image(width, height)

    cx = kernel_w // 2
    cy = kernel_h // 2

    for y in range(height):
        for x in range(width):
            acc1 = 0.0
            acc2 = 0.0
            for ki in range(kernel_h):
                for kj in range(kernel_w):
                    pv = img.get_pixel(x - cx + kj, y - cy + ki)
                    acc1 += pv * kernel1[ki * kernel_w + kj]
                    acc2 += pv * kernel2[ki * kernel_w + kj]

            v1 = abs(acc1 * coeff)
            v2 = abs(acc2 * coeff)
            result.set_pixel(x, y, min(255, max(v1, v2)))

    return result

1.2 n个卷积核

对 N 个卷积核分别运算,取所有结果绝对值的逐像素最大值

	用于 Kirsch 8 方向算子:8 个核各检测一个方向,
	取最大响应作为该点的边缘强度。

    G(x, y) = max_k |G_k(x, y)|
  • ptyon代码
def apply_n_kernels_max(img, kernels, kernel_h, kernel_w, coeff=1.0):

    width, height = img.width, img.height
    result = Image(width, height)

    cx = kernel_w // 2
    cy = kernel_h // 2

    for y in range(height):
        for x in range(width):
            max_val = 0.0
            for kernel in kernels:
                acc = 0.0
                for ki in range(kernel_h):
                    for kj in range(kernel_w):
                        acc += img.get_pixel(x - cx + kj, y - cy + ki) * kernel[ki * kernel_w + kj]
                val = abs(acc * coeff)
                if val > max_val:
                    max_val = val
            result.set_pixel(x, y, min(255, max_val))

    return result

2. Roberts边缘检测算子

Roberts 边缘检测算子,定位精度高,对噪声敏感,计算简单;适合轮廓清晰的图像。它的计算原理就是
在 2×2 像素窗口中,计算两条对角线方向的差分,近似梯度幅度:

    G = sqrt((p0 - p3)² + (p1 - p2)²)

  窗口布局:
    p0  p1
    p2  p3

  等价于两个 2×2 卷积核:
    Gx (主对角):  [ -1  0 ]    Gy (副对角): [  0 -1 ]
                  [  0  1 ]                [  1  0 ]

说白了Roberts算子,就是水平核垂直-双向一阶差分,原理简单.

  • python代码
def roberts(img):
    """
    Roberts 交叉梯度算子
    """
    width, height = img.width, img.height
    result = Image(width, height)

    for y in range(height - 1):
        for x in range(width - 1):
            p0 = img.get_pixel(x,     y)      # 左上
            p1 = img.get_pixel(x + 1, y)      # 右上
            p2 = img.get_pixel(x,     y + 1)  # 左下
            p3 = img.get_pixel(x + 1, y + 1)  # 右下

            gx = p0 - p3   # 主对角差分
            gy = p1 - p2   # 副对角差分
            gradient = math.sqrt(gx * gx + gy * gy)
            result.set_pixel(x, y, min(255, gradient))

    return result
  • 效果图
    在这里插入图片描述

3. Prewitt边缘检测算子

它的原理是用 3×3 窗口的行方向和列方向差分之和逼近偏导数,两方向取最大值:

    Gy (检测水平边缘):   Gx (检测垂直边缘):
      -1  -1  -1            -1   0  +1
       0   0   0            -1   0  +1
      +1  +1  +1            -1   0  +1

    G = max(|Gy|, |Gx|)

它的特点是- 等权系数,计算简单;对噪声有一定的平滑效果;对水平/垂直边缘响应强

  • python代码
def prewitt(img):
    """
    Prewitt 算子


    ky = [  # 检测水平方向灰度变化(Gy)
        -1.0, -1.0, -1.0,
         0.0,  0.0,  0.0,
         1.0,  1.0,  1.0,
    ]
    kx = [  # 检测垂直方向灰度变化(Gx)
        -1.0,  0.0,  1.0,
        -1.0,  0.0,  1.0,
        -1.0,  0.0,  1.0,
    ]
    return apply_two_kernels_max(img, ky, kx, 3, 3, 1.0)
  • 效果图
    在这里插入图片描述

4. Sobel边缘检测算子

它的原理是 在 Prewitt 基础上,对中心行/列赋予 2 倍权重,增强边缘响应:

    Gy (检测水平边缘):   Gx (检测垂直边缘):
      -1  -2  -1            -1   0  +1
       0   0   0            -2   0  +2
      +1  +2  +1            -1   0  +1

    G = max(|Gy|, |Gx|)

它的特点:
中心行/列加倍权重使对边缘的方向性更强,抗噪性优于 Prewitt,
是实际中最常用的一阶微分边缘检测算子。

  • python代码
def sobel(img):

    ky = [
        -1.0, -2.0, -1.0,
         0.0,  0.0,  0.0,
         1.0,  2.0,  1.0,
    ]
    kx = [
        -1.0,  0.0,  1.0,
        -2.0,  0.0,  2.0,
        -1.0,  0.0,  1.0,
    ]
    return apply_two_kernels_max(img, ky, kx, 3, 3, 1.0)
  • 效果图
    在这里插入图片描述

5. Krisch边缘检测

  • 原理
    使用 8 个 3×3 卷积核,分别检测 8 个主要方向(N/NE/E/SE/S/SW/W/NW)
    的边缘。每个核将 5 个系数 (+5) 放在一侧,其余 8 个系数设为 -3,
    中心为 0,使核和为 0(无直流响应)。

    对每个像素,计算 8 个方向的响应并取最大值,缩放 0.5 防止溢出:
      G(x, y) = 0.5 × max_k(|G_k|)
    
  • 特点:

    • 各向异性,能精确检测特定方向的边缘;
    • 取 8 个方向的最大值,等效于检测最显著方向的边缘;
    • 比 Sobel 对方向性更敏感。
  • python代码

def kirsch(img):
    kernels = [
        # K1 — 上方 (N)
        [ 5.0,  5.0,  5.0,
         -3.0,  0.0, -3.0,
         -3.0, -3.0, -3.0],
        # K2 — 右上 (NE)
        [-3.0,  5.0,  5.0,
         -3.0,  0.0,  5.0,
         -3.0, -3.0, -3.0],
        # K3 — 右方 (E)
        [-3.0, -3.0,  5.0,
         -3.0,  0.0,  5.0,
         -3.0, -3.0,  5.0],
        # K4 — 右下 (SE)
        [-3.0, -3.0, -3.0,
         -3.0,  0.0,  5.0,
         -3.0,  5.0,  5.0],
        # K5 — 下方 (S)
        [-3.0, -3.0, -3.0,
         -3.0,  0.0, -3.0,
          5.0,  5.0,  5.0],
        # K6 — 左下 (SW)
        [-3.0, -3.0, -3.0,
          5.0,  0.0, -3.0,
          5.0,  5.0, -3.0],
        # K7 — 左方 (W)
        [ 5.0, -3.0, -3.0,
          5.0,  0.0, -3.0,
          5.0, -3.0, -3.0],
        # K8 — 左上 (NW)
        [ 5.0,  5.0, -3.0,
          5.0,  0.0, -3.0,
         -3.0, -3.0, -3.0],
    ]
    return apply_n_kernels_max(img, kernels, 3, 3, 0.5)
  • 效果图
    在这里插入图片描述

6. 拉普拉斯算子

  • 原理:
    二维拉普拉斯算子是各向同性的二阶微分算子:

      ∇²f = ∂²f/∂x² + ∂²f/∂y²
    
    8邻域离散近似(卷积核和为 0,保证对均匀区域响应为零):
    
      -1  -1  -1
      -1  +8  -1
      -1  -1  -1
    
  • 特点:
    各向同性,对任意方向边缘响应相同;对噪声敏感;
    会在边缘两侧产生正负响应(取绝对值后显示为双边缘)。
    “”"

  • python代码

def laplacian(img):
    """
    Laplacian(拉普拉斯)算子


    kernel = [
        -1.0, -1.0, -1.0,
        -1.0,  8.0, -1.0,
        -1.0, -1.0, -1.0,
    ]
    return apply_kernel(img, kernel, 3, 3, 1.0, absolute=True)
  • 效果图
    在这里插入图片描述

7. 高斯-拉普拉斯算子

  • 原理:
    先用高斯滤波器平滑图像(抑制噪声),再应用拉普拉斯算子检测边缘。
    将「高斯平滑 + 拉普拉斯」两步合并为一个 5×5 卷积核(σ ≈ 1.4):

      -2   -4   -4   -4   -2
      -4    0   +8    0   -4
      -4   +8  +24   +8   -4   × 0.25
      -4    0   +8    0   -4
      -2   -4   -4   -4   -2
    
  • 特点:

    • 先平滑再微分,比直接拉普拉斯对噪声更鲁棒;
    • 5×5 核相比 3×3 具有更大的平滑效果;
    • 缩放系数 0.25 用于将输出归一化到合理范围。
  • python代码

def gauss_laplacian(img):
    kernel = [
        -2.0, -4.0, -4.0, -4.0, -2.0,
        -4.0,  0.0,  8.0,  0.0, -4.0,
        -4.0,  8.0, 24.0,  8.0, -4.0,
        -4.0,  0.0,  8.0,  0.0, -4.0,
        -2.0, -4.0, -4.0, -4.0, -2.0,
    ]
    return apply_kernel(img, kernel, 5, 5, 0.25, absolute=True)
  • 效果图
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值