具有方向性的高斯滤波

一般高斯滤波

高斯滤波器是一类根据高斯函数的形状来选择权值的线性平滑滤波器。

常用的零均值离散高斯滤波器函数:

g(x)=exp( -x^2/(2 sigma^2)

其中,高斯分布参数Sigma决定了高斯函数的宽度。对于图像处理来说,常用二维零均值离散高斯函数作平滑滤波器。

def gaussian_kernel_generator(N=1, sigma=1.0):
    # N = 1 # 模板的半径
    # sigma = 1.0 # 高斯分布的标准差

    # 计算高斯滤波模板的行数和列数
    rows = 2 * N + 1
    cols = 2 * N + 1

# 创建一个空的数组,用于存放高斯滤波模板的系数
    gaussian_kernel = np.zeros((rows, cols))

# 遍历数组中的每个元素,根据高斯函数的公式计算其值
    for i in range(rows):
        for j in range(cols):
        # 计算元素相对于中心的坐标
            x = j - N
            y = i - N
        # 计算高斯函数的值
            gaussian_kernel[i, j] = np.exp(- (x ** 2 + y ** 2) / (2 * sigma ** 2)) / (2 * np.pi * sigma ** 2)

# 对高斯滤波模板进行归一化,使其系数之和为1
    gaussian_kernel = gaussian_kernel / np.sum(gaussian_kernel)
    return gaussian_kernel

具有方向性的高斯滤波

有时候,我们希望滤波器在某个方向上的滤波效果更强,最简单的办法就是旋转滤波核

def rotate_kernel(kernel, theta):
    # 获取数组的行数和列数
    rows, cols = kernel.shape
    # 创建一个新的数组,用于存放旋转后的结果
    rotated_kernel = np.zeros((rows, cols))
    # 遍历数组中的每个元素
    for i in range(rows):
        for j in range(cols):
            # 计算元素相对于中心的坐标
            x = j - (cols - 1) / 2
            y = i - (rows - 1) / 2
            # 计算旋转后的坐标
            x_rot = x * np.cos(theta) + y * np.sin(theta)
            y_rot = -x * np.sin(theta) + y * np.cos(theta)
            # 计算旋转后的坐标对应的数组下标
            i_rot = int(round(y_rot + (rows - 1) / 2))
            j_rot = int(round(x_rot + (cols - 1) / 2))
            # 判断旋转后的下标是否在数组范围内,如果是,则将原始元素的值赋给旋转后的位置
            if 0 <= i_rot < rows and 0 <= j_rot < cols:
                rotated_kernel[i_rot, j_rot] = kernel[i, j]
    # 返回旋转后的数组
    rotated_kernel = rotated_kernel / np.sum(rotated_kernel)
    return rotated_kernel

应用滤波

def filter_array(array,gaussian_kernel):
    rows, cols = array.shape
    kernel_size = gaussian_kernel.shape[0]

# 扩充数组的边缘,使得滤波器可以覆盖到所有的元素,填充值为0
    array_padded = cv2.copyMakeBorder(array, kernel_size // 2, kernel_size // 2, kernel_size // 2, kernel_size // 2, cv2.BORDER_CONSTANT, value=0)

# 创建一个空的数组,用于存放滤波后的结果
    filtered_array = np.zeros((rows, cols))

# 遍历扩充后的数组中的每个元素,进行卷积运算
    for i in range(kernel_size // 2 , array_padded.shape[0] - kernel_size // 2 ):
        for j in range(kernel_size // 2, array_padded.shape[1] - kernel_size // 2):
        # 获取滤波器覆盖的子数组
            sub_array = array_padded[i - kernel_size // 2 : i + kernel_size // 2 + 1, j - kernel_size // 2 : j + kernel_size // 2 + 1]
        # 计算滤波器和子数组的乘积之和
            filtered_value = np.sum(gaussian_kernel * sub_array)
        # 将滤波后的值赋给输出数组
            filtered_array[i - kernel_size // 2, j - kernel_size // 2] = filtered_value
     
    return filtered_array