【问题标题】:Gaussian filter in PyTorchPyTorch 中的高斯滤波器
【发布时间】:2021-09-04 22:22:25
【问题描述】:

我正在寻找一种仅使用 PyTorch 函数将高斯滤波器应用于图像(张量)的方法。使用 numpy,等效代码为

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# Define 2D Gaussian kernel
def gkern(kernlen=256, std=128):
    """Returns a 2D Gaussian kernel array."""
    gkern1d = signal.gaussian(kernlen, std=std).reshape(kernlen, 1)
    gkern2d = np.outer(gkern1d, gkern1d)
    return gkern2d

# Generate random matrix and multiply the kernel by it
A = np.random.rand(256*256).reshape([256,256])

# Test plot
plt.figure()
plt.imshow(A*gkern(256, std=32))
plt.show()

我找到的最接近的建议是基于this post:

import torch.nn as nn

conv = nn.Conv2d(in_channels = 1, out_channels = 1, kernel_size=264, bias=False)
with torch.no_grad():
    conv.weight = gaussian_weights

但它给了我错误NameError: name 'gaussian_weights' is not defined。我怎样才能让它发挥作用?

【问题讨论】:

  • 我认为gaussian_weights 应该是由高斯构成的内核,例如scipy.signal.gaussian
  • 是的,我也有同样的想法。所以现在问题变成了:有没有办法在不使用 Numpy 和/或明确指定权重的情况下定义高斯核(或 2D 高斯)?
  • 也许这个discuss.pytorch.org/t/…可以帮助你
  • 这里的pytorch实现:forums.fast.ai/t/…

标签: python pytorch


【解决方案1】:

是的,我也有同样的想法。所以现在问题变成了:有没有办法在不使用 Numpy 和/或明确指定权重的情况下定义高斯核(或 2D 高斯)?

是的,这很容易。只需查看signal.gaussian 的函数文档即可。有一个指向source code 的链接。那么该方法的作用如下:

def gaussian(M, std, sym=True):
    if M < 1:
        return np.array([])
    if M == 1:
        return np.ones(1, 'd')
    odd = M % 2
    if not sym and not odd:
        M = M + 1
    n = np.arange(0, M) - (M - 1.0) / 2.0
    sig2 = 2 * std * std
    w = np.exp(-n ** 2 / sig2)
    if not sym and not odd:
        w = w[:-1]
    return w

你很幸运,因为在 Pytorch 中转换很简单,(几乎)只需将 np 替换为 torch 就完成了!

另外,请注意,torch 中的 np.outer 等效为 ger。

【讨论】:

    【解决方案2】:

    使用了上面的所有代码,并更新了 Pytorch 修订版 torch.outer

    import torch
    def gaussian_fn(M, std):
        n = torch.arange(0, M) - (M - 1.0) / 2.0
        sig2 = 2 * std * std
        w = torch.exp(-n ** 2 / sig2)
        return w
    
    def gkern(kernlen=256, std=128):
        """Returns a 2D Gaussian kernel array."""
        gkern1d = gaussian_fn(kernlen, std=std) 
        gkern2d = torch.outer(gkern1d, gkern1d)
        return gkern2d
    
    # Generate random matrix and multiply the kernel by it
    A = np.random.rand(256*256).reshape([256,256])
    A = torch.from_numpy(A)
    guassian_filter = gkern(256, std=32)
    
    ax=[]
    f = plt.figure(figsize=(12,5))
    ax.append(f.add_subplot(131))
    ax.append(f.add_subplot(132))
    ax.append(f.add_subplot(133))
    ax[0].imshow(A, cmap='gray')
    ax[1].imshow(guassian_filter, cmap='gray')
    ax[2].imshow(A*guassian, cmap='gray')
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-02
      • 2011-02-15
      • 2018-10-03
      • 1970-01-01
      • 2013-03-29
      • 2023-04-09
      • 2018-01-26
      • 2013-02-01
      相关资源
      最近更新 更多