Ian*_*rts 4 python numpy convolution scipy smoothing
我想知道是否有人可以帮助我将SciPy 食谱中的平滑示例扩展到 2D 问题。
该脚本非常适用于平滑一维函数,并且它们还提供了在两个轴上进行二维平滑的代码(即模糊图像)。
但是,我想将此函数应用于 2D 数据集,但仅沿一个轴(x 方向)。我可以循环执行此操作,方法是检查 y 中的每个切片,应用一维卷积,然后重建数组。但这似乎是糟糕的编码技术。
因此,我想知道如何在 2D 中做到这一点?我想我需要做一个2D内核与重量仅沿一个方向变化,但我不知道如何做到这一点,或卷积功能的使用(numpy.convolve,scipy.signal.convolve,scipy.ndimage.filters.convolve1d等)
看起来您应该能够ny=1执行 2D 图像的 1D 卷积,但这表明食谱函数实际上使用的是长度2 * n + 1内核。这让我认为您可以使用ny=0,但这会0/0在内核的定义中创建一个。所以,那里也没有运气。:( 基于此,我认为食谱不适合您的目的,因此我提供了另一种方法来执行您的要求。
要仅沿 1 维通过卷积对 2D 数组进行平滑处理,您需要做的就是制作一个沿其中一个维度的形状为 1 的 2D 数组(内核),
import numpy as np
kern = np.ones((11, 1)) # This will smooth along columns
Run Code Online (Sandbox Code Playgroud)
并将其归一化,使其总和为 1,
kern /= kern.sum()
Run Code Online (Sandbox Code Playgroud)
然后将它与你的信号进行卷积,
import scipy.signal as signal
X, Y = np.mgrid[-70:70, -70:70]
Z = np.cos((X**2+Y**2)/200.) + np.random.normal(size=X.shape)
Z_smooth = signal.convolve(Z, kern)
Run Code Online (Sandbox Code Playgroud)
上面我使用了“boxcar”内核(常量值),很多人认为它有些粗糙。人们通常更喜欢使用更锐利或更平滑的过滤器(例如“汉宁”或“高斯”,如食谱中所述)。
kern_hanning = signal.hanning(11)[:, None]
kern_hanning /= kern_hanning.sum()
kern_gauss7 = signal.gaussian(11, 7)[:, None]
kern_gauss7 /= kern_gauss7.sum()
kern_gauss3 = signal.gaussian(11, 3)[:, None]
kern_gauss3 /= kern_gauss3.sum()
Run Code Online (Sandbox Code Playgroud)
这些不同的窗户看起来像这样,
应用这些过滤器后,你会得到类似的东西,
请注意,'Gauss7' 内核与 boxcar 几乎相同,因此它在输出中产生非常相似的结果。另一方面,汉宁窗口要精细得多,因此它可以对数据产生更清晰的过滤器(环上的拖尾现象要少得多)。
也许最简单的选择是使用以下中的一维滤波器之一scipy.ndimage.filters:
from scipy import ndimage
from scipy.misc import lena
img = lena()
# a uniform (boxcar) filter with a width of 50
boxcar = ndimage.uniform_filter1d(img, 50, 1)
# a Gaussian filter with a standard deviation of 10
gauss = ndimage.gaussian_filter1d(img, 10, 1)
Run Code Online (Sandbox Code Playgroud)
您还可以使用过滤器的非一维版本,如下所示:(ndimage.gaussian_filter(img, (0, 10))即将您不想平滑的轴的过滤器宽度设置为 0)。
要平滑任意内核,您可以使用scipy.ndimage.convolve1d:
import numpy as np
kern = np.hanning(50) # a Hanning window with width 50
kern /= kern.sum() # normalize the kernel weights to sum to 1
hanning = ndimage.convolve1d(img, kern, 1)
Run Code Online (Sandbox Code Playgroud)
以下是各种输出的样子:
from matplotlib import pyplot as plt
fig, ax = plt.subplots(2, 2, figsize=(8, 8))
ax[0, 0].imshow(img)
ax[0, 0].set_title('Original')
ax[0, 1].imshow(boxcar)
ax[0, 1].set_title('Boxcar filter (width = 50)')
ax[1, 0].imshow(gauss)
ax[1, 0].set_title(r'Gaussian filter ($\sigma$ = 10)')
ax[1, 1].imshow(hanning)
ax[1, 1].set_title(r'Hanning window (width = 50)')
for aa in ax.flat:
aa.set_axis_off()
fig.tight_layout()
plt.show()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7236 次 |
| 最近记录: |