常见的卷积核及其应用

拉普拉斯变换

标准拉普拉斯算子
常见的卷积核及其应用_图像处理
扩展至对角区域
常见的卷积核及其应用_边缘检测_02
其中拉普拉斯变换常在图像处理中强调灰度值的突变得到的图层与原图像叠加在一起可以得到锐化的效果。

sobel算子

sobel算子常用边缘检测其中sobel算子分为两种一种为水平方向的一种为垂直方向的。

水平方向:
常见的卷积核及其应用_边缘检测_03
垂直方向:
常见的卷积核及其应用_图像处理_04

高斯算子

使用Python生成高斯模糊核(或称为高斯算子)函数。这个函数会返回一个大小为 (ksize, ksize) 的高斯核,其中 ksize 是核的大小(例如,3表示3x3的核),sigma 是高斯函数的标准差。

import numpy as np

def gaussian_kernel(ksize, sigma):
    """Generate a Gaussian kernel."""
    # 初始化高斯核为0
    kernel = np.zeros((ksize, ksize))
    
    # 计算高斯核中心
    center = ksize // 2

    # 填充高斯核
    for i in range(ksize):
        for j in range(ksize):
            diff_x = i - center
            diff_y = j - center
            kernel[i, j] = np.exp(-(diff_x**2 + diff_y**2) / (2 * sigma**2))
    
    # 归一化高斯核,使其和为1
    kernel /= np.sum(kernel)
    
    return kernel

# 示例使用:
ksize = 5
sigma = 1.0
print(gaussian_kernel(ksize, sigma))

运行上述代码,它会返回一个5x5的高斯核。同时可以通过更改 ksizesigma 的值来生成不同大小和模糊程度的高斯核。

常见的卷积核及其应用_边缘检测_05

应用

import cv2
import numpy as np
import matplotlib.pyplot as plt


def fspecial(mode='average', *params):
    """
    生成相应的卷积核模版
    :param mode: average 均值滤波器,laplace 拉普拉斯算子,sobel_x 水平方向上的sobel算子,sobel_y 垂直方向上的sobel算子,prewitt prewitt算子,gaussian 高斯核
    :param params: 对均值滤波器的大小控制,以及高斯核的控制
    :return:
    """
    if mode == 'average':
        size = params[0] if params else 3
        return np.ones((size, size)) / size * size
    elif mode == 'laplace':
        return np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
    elif mode == 'sobel-x':
        return np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
    elif mode == 'sobel-y':
        return np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
    elif mode == 'prewitt':
        return np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]])
    elif mode == 'gaussian':
        size = params[0] if params else 3
        sigma = params[1] if len(params) > 1 else 0.5
        ax = np.arange(-size // 2 + 1., size // 2 + 1.)
        xx, yy = np.meshgrid(ax, ax)
        kernel = np.exp(-0.5 * (xx ** 2 + yy ** 2) / (sigma ** 2))
        return kernel / np.sum(kernel)
    else:
        raise ValueError("Unsupported filter type")


def imfilter(I, K, is_padding=True, mode=None):
    """
    卷积计算
    :param I: 原始图像
    :param K: 卷积核
    :param is_padding: 是否填充
    :param mode: 填充模式
    :return: 卷积计算结果
    """
    k = K.shape[0]
    p = k // 2
    if is_padding:
        if mode is None:
            I = np.pad(I, pad_width=p)
        else:
            I = np.pad(I, pad_width=p, mode=mode)

    h, w = I.shape
    I_conv = np.zeros((h - k + 1, w - k + 1))

    for i in range(p, h - p):
        for j in range(p, w - p):
            I_conv[i - p, j - p] = sum(sum(I[i - p:i + p + 1, j - p:j + p + 1] * K[0:k, 0:k]))

    return tounit8(I_conv)


def tounit8(I_conv):
    """
    归一化处理,将图像放缩至[0,255]
    :param I_conv: 图像
    :return: 图像归一化的结果
    """
    return ((I_conv - I_conv.min()) / (I_conv.max() - I_conv.min()) * 255).round()


if __name__ == '__main__':
    img = cv2.imread("./img/lenna.jpg", cv2.IMREAD_GRAYSCALE)

    K_aver = fspecial("average")
    K_lap = fspecial("laplace")
    K_sobel = fspecial("sobel-x")
    K_gauss = fspecial("gaussian", 5, 5)
    K_prewitt = fspecial("prewitt")

    img_aver = imfilter(img, K_aver, is_padding=True, mode='edge')
    img_lap = imfilter(img, K_lap)
    img_sobel = imfilter(img, K_sobel, is_padding=True, mode='reflect')
    img_gauss = imfilter(img, K_gauss, is_padding=False)
    img_prewitt = imfilter(img, K_prewitt)

    fig = plt.figure(figsize=(12, 7))
    grid = plt.GridSpec(2, 3)

    ax_original = fig.add_subplot(grid[0, 0])
    ax_original.imshow(img, cmap='gray')
    ax_original.axis('off')
    ax_original.set_title("original img")

    ax_aver = fig.add_subplot(grid[0, 1])
    ax_aver.imshow(img_aver, cmap='gray')
    ax_aver.axis('off')
    ax_aver.set_title("img after aver")

    ax_gauss = fig.add_subplot(grid[0, 2])
    ax_gauss.imshow(img_gauss, cmap='gray')
    ax_gauss.axis('off')
    ax_gauss.set_title('img after gauss')

    ax_sobel = fig.add_subplot(grid[1, 0])
    ax_sobel.imshow(img_sobel, cmap='gray')
    ax_sobel.axis('off')
    ax_sobel.set_title('img after sobel-x')

    ax_lap = fig.add_subplot(grid[1, 1])
    ax_lap.imshow(img_lap, cmap='gray')
    ax_lap.axis('off')
    ax_lap.set_title('img after lap')

    ax_prewitt = fig.add_subplot(grid[1, 2])
    ax_prewitt.imshow(img_prewitt, cmap='gray')
    ax_prewitt.axis('off')
    ax_prewitt.set_title('img after prewitt')

    plt.show()

常见的卷积核及其应用_边缘检测_06