高斯滤波的python实现

针对高斯滤波的理解

高斯滤波的本质也是一个卷积在图像上移动相乘的结果,具体原理可以参考最下面的链接,讲的比较详细。而高斯函数的公式与分布如下图
在这里插入图片描述在这里插入图片描述
而图像中常用为二位高斯函数,如下
在这里插入图片描述
所以我们要做的是通过该函数得到一个矩阵,我们假设矩阵的中心点为(x0,y0),矩阵中任意一点的高斯值就应该是
f ( x , y ) = A e x p ( − ( ( x 0 − x ) 2 + ( y 0 − y ) 2 ) / ( 2 ∗ σ 2 ) ) . f(x, y) = Aexp(-((x_0-x)^2 + (y_0-y)^2) / (2*\sigma^{2})). f(x,y)=Aexp(((x0x)2+(y0y)2)/(2σ2)).
当矩阵的长宽确定时,矩阵内每个(x, y)与(x0, y0)之间的距离是固定的,所以我们可调的参数只有A,sigma。但我们通常取A为1,所以高斯函数核的生成代码如下所示,我们假设x0,y0的值都为0,所以可以得到下x,y的相对位置。

#   生成双边核
def kernel_generate(ds, sigma=1.1):
    s = 0
    k = np.zeros((2*ds + 1, 2*ds + 1))
    for x in range(-ds, ds + 1):
        for y in range(-ds, ds + 1):
            k[x + ds, y + ds] = math.exp(-(x * x + y * y) / (2* sigma*sigma))
            s += k[x + ds, y + ds]
    return k / s

我们可以运行这段代码,打印高斯矩阵的结果,这是一个3x3大小的核(2*ds+1)

print(kernel_generate(ds=1, sigma=1.1))

在这里插入图片描述
有了高斯核以后,其计算过程类似于均值滤波
在这里插入图片描述
实际代码如下

import cv2
import math
import numpy as np
from tqdm import *
import numba as nb


#   生成双边核
def kernel_generate(ds, a=1.1):
    s = 0
    k = np.zeros((2*ds + 1, 2*ds + 1))
    for x in range(-ds, ds + 1):
        for y in range(-ds, ds + 1):
            k[x + ds, y + ds] = math.exp(-(x * x + y * y) / (2* a*a))
            s += k[x + ds, y + ds]
    # print(k / s)
    return k / s


#   对图像进行边缘镜像处理
def set_border_sym(image_data, ksize):
    h_, w_, c_ = image_data.shape
    border = int((ksize - 1) / 2)
    result_data = np.zeros((h_ + ksize - 1, w_ + ksize - 1, c_))
    for c in range(c_):
        for i in range(h_ + 2 * border):
            if i < border:
                y_ori = border - i
            elif i > h_ + border - 1:
                y_ori = (h_ + border - 1) - (i - (border + h_ - 1)) - border
            else:
                y_ori = i - border
            for j in range(w_ + 2 * border):
                if j < border:
                    x_ori = border - j
                elif j > w_ + border - 1:
                    x_ori = (w_ + border - 1) - (j - (border + w_ - 1)) - border
                else:
                    x_ori = j - border
                result_data[i, j, c] = image_data[y_ori, x_ori, c]
    return result_data.astype("uint8")


def gauss_filtering(image_pad_data, ksize):
    h_, w_, c_ = image_pad_data.shape
    result_data = np.zeros_like(image_pad_data)
    border = int((ksize - 1) / 2)
    #   定义卷积核大小
    k_ = kernel_generate(border, a=1.1)

    #   对图像分图层进行处理
    for c in range(c_):
        #   输入的是填充后的图像,但索引要从原图像素处开始
        for y in range(border, h_ - border):
            for x in range(border, w_ - border):
                #   获得(x, y)处的像素参考框,然后与k逐像素相乘并求和
                reference_matrix = image_pad_data[y-border:y+border + 1, x-border:x+border+1, c]
                sum_ref = 0
                for i in range(ksize):
                    for j in range(ksize):
                        sum_ref += reference_matrix[i, j] * k_[i, j]

                result_data[y, x, c] = sum_ref

    return result_data[border:h_ - border, border:w_ - border, :].astype("uint8")


if __name__ == "__main__":
    ori_image = cv2.imread("../../data/image/lena.png")

    #   cv2自带的均值滤波  cv2.blur(原始图像,核大小)

    cv2_result = cv2.GaussianBlur(ori_image, (5, 5), 1.1)

    sym_border_image = set_border_sym(ori_image, 5)
    result_data_median = gauss_filtering(sym_border_image, 5)

    cv2.imshow("ori_image", ori_image)
    # cv2.imshow("zero_border_image", zero_border_image)
    cv2.imshow("sym_border_image", sym_border_image)
    cv2.imshow("cv2_result", cv2_result)
    cv2.imshow("result_data_gauss", result_data_median)
    cv2.waitKey(0)



结果如下:
在这里插入图片描述

参考:链接: 高斯滤波详解 python实现高斯滤波

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值