二维高斯核函数(python)

今天突然想要去试一试opencv里面的高斯模糊怎么实现,虽然以前已经写过很多次关于高斯核的函数了,但是有个好奇点,那就是一般不填sigma这个参数的时候,opencv是怎么计算的。

关于具体的高斯函数的讲解,已经有人写的很详细了,我就不赘述了,所以给大家个链接有兴趣的可以去看看。

http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html

我这里想做的实验是到底opencv中的高斯模糊函数GaussianBlur使用的高斯核是什么。

但是直接获取这个二维的高斯核貌似是不可行的,opencv提供了一维高斯核获取的函数。

具体参考以下页面

https://docs.opencv.org/2.4.13.2/modules/imgproc/doc/filtering.html#void sepFilter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernelX, InputArray kernelY, Point anchor, double delta, int borderType)

那么此处问题就出来了,如何通过一维高斯核生成二维高斯核。

先获取两个一维高斯核,而后对后一个高斯核进行转置,而后第一个高斯核核第二个高斯核通过矩阵相乘就可以得到一个二维高斯核了。

下面是测试代码

def gaussian_kernel_2d_opencv(kernel_size = 3,sigma = 0):
    kx = cv2.getGaussianKernel(kernel_size,sigma)
    ky = cv2.getGaussianKernel(kernel_size,sigma)
    return np.multiply(kx,np.transpose(ky)) 

然后我需要的是自己写一个二维高斯核函数,此处写法有很多版本,但是我是参考了刚才上面给出的参考链接中的计算方式,同时参考了opencv的源码。

两个地方不一样,一个是opencv当中在计算高斯模版的时候并没有在最后计算除以pi2(sigma**2),而是将每次计算后的数值加起来,最后用1/总和,然后输出的时候将刚才计算的数值乘上本身的像素值。

本来此处写一下公式会比较好理解,但是这里稍微偷懒一下就不给出具体的公式了,大家自行看我下面的代码就OK了。

#kernel_size set (n,n) default
def gaussian_2d_kernel(kernel_size = 3,sigma = 0):
    
    kernel = np.zeros([kernel_size,kernel_size])
    center = kernel_size//2
    
    if sigma == 0:
        sigma = ((kernel_size-1)*0.5 - 1)*0.3 + 0.8
    
    s = 2*(sigma**2)
    sum_val = 0
    for i in range(0,kernel_size):
        for j in range(0,kernel_size):
            x = i-center
            y = j-center
            kernel[i,j] = np.exp(-(x**2+y**2) / s)
            sum_val += kernel[i,j]
            #/(np.pi * s)
    sum_val = 1/sum_val
    return kernel*sum_val

这个计算结果和通过opencv获取一维高斯核通过计算转换为二维高斯核的结果完全一致。此处实验成功。

但是!!通过这个高斯核和图像进行卷积操作的结果和直接通过opencv调用GaussianBlur计算的结果是有所不同的。虽然单纯从数值上来讲,基本都只是差1的大小,但是这说明此函数并不是直接和这个卷积核进行卷积的,而是还做了一点修改。那么具体是什么,我暂时没画时间去查源码,如有了解者希望能够告知我,感激不尽。

最后一个小注意点,上面忘记书写了,卷积核大小在小于等于7的情况下结果是和我自己写的那个函数计算不完全一致的。原因在于opencv源码当中小于等于7的高斯核并不是通过计算给出而是直接给出了结果,所以在小数上有一定差距,估计是效率问题才这么做的。

20190115 修正(源自评论“临京雪月”)

opencv源码当中小于等于7的高斯核并不是通过计算给出而是直接给出了结果。这句话不对,当小于等于7且sigma<=0时候才会使用内置的模板,其余情况同样是计算出来的结果

  • 11
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
高斯核函数是一种常用的核函数,用于支持向量回归(SVR)算法中。在Python中,可以使用numpy和scikit-learn库来实现高斯核函数。 引用\[2\]中给出了一个用于计算高斯核函数函数rbf(x, gamma),其中x是输入数据,gamma是高斯核函数的参数。该函数使用了numpy库中的pdist和squareform函数来计算输入数据的欧氏距离,并通过指数函数计算高斯核函数的值。 另外,引用\[3\]中给出了另一种生成高斯核函数的方法creat_gauss_kernel。该函数使用了numpy库中的meshgrid函数来生成一个二维网格,然后根据高斯核函数的公式计算每个点的值。 你可以根据自己的需求选择使用哪种方法来生成高斯核函数。 #### 引用[.reference_title] - *1* [Python实现基于高斯核函数,线性核函数和多项式核函数的SVR(支持向量回归)及预测算法](https://blog.csdn.net/qq_38773993/article/details/119299230)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [python实现核函数](https://blog.csdn.net/qq_44425179/article/details/130186593)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [图像处理核函数:之高斯核的生成方法 python](https://blog.csdn.net/jasneik/article/details/108150217)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值