卷积核#
导言和概念#
卷积模块提供了几个内置内核,以涵盖天文学中最常见的应用。也可以从数组中定义自定义内核,或者组合现有内核来匹配特定的应用程序。
每个滤波器内核都有其响应函数的特征。对于时间序列,我们说的是“脉冲响应函数”,或者我们称之为“点扩散函数”,这个响应函数是由 FittableModel
,在网格上使用 discretize_model()
得到一个可用于对二进制数据进行离散卷积的核数组。
实例#
一维核#
滤波的一个应用是平滑噪声数据。在这种情况下,我们考虑一个有噪声的洛伦兹曲线:
>>> import numpy as np
>>> from astropy.modeling.models import Lorentz1D
>>> from astropy.convolution import convolve, Gaussian1DKernel, Box1DKernel
>>> rng = np.random.default_rng()
>>> lorentz = Lorentz1D(1, 0, 1)
>>> x = np.linspace(-5, 5, 100)
>>> data_1D = lorentz(x) + 0.1 * (rng.random(100) - 0.5)
用 Gaussian1DKernel
标准偏差为2像素:
>>> gauss_kernel = Gaussian1DKernel(2)
>>> smoothed_data_gauss = convolve(data_1D, gauss_kernel)
用 Box1DKernel
宽度为5像素:
>>> box_kernel = Box1DKernel(5)
>>> smoothed_data_box = convolve(data_1D, box_kernel)
下图说明了结果:
在 astropy
卷积函数 convolve
和 convolve_fft
,也可以将内核与 numpy
或 scipy
卷积 array
属性。这在大多数情况下比 astropy
卷积,但如果数据中存在NaN值,则无法正常工作。
>>> smoothed = np.convolve(data_1D, box_kernel.array)
二维核#
由于所有的二维核都是对称的,只需指定一个方向的宽度就足够了。因此,2D内核的使用与1D内核的用法基本相同。这里,我们考虑图像中间一个振幅为1的小高斯形源,并添加10%的噪声:
>>> import numpy as np
>>> from astropy.convolution import convolve, Gaussian2DKernel, Tophat2DKernel
>>> from astropy.modeling.models import Gaussian2D
>>> gauss = Gaussian2D(1, 0, 0, 3, 3)
>>> # Fake image data including noise
>>> rng = np.random.default_rng()
>>> x = np.arange(-100, 101)
>>> y = np.arange(-100, 101)
>>> x, y = np.meshgrid(x, y)
>>> data_2D = gauss(x, y) + 0.1 * (rng.random((201, 201)) - 0.5)
用 Gaussian2DKernel
标准偏差为2像素:
>>> gauss_kernel = Gaussian2DKernel(2)
>>> smoothed_data_gauss = convolve(data_2D, gauss_kernel)
用 Tophat2DKernel
宽度为5像素:
>>> tophat_kernel = Tophat2DKernel(5)
>>> smoothed_data_tophat = convolve(data_2D, tophat_kernel)
原始图像如下所示:
下图说明了应用于模拟数据的几个二维核之间的差异。请注意,与原始图像相比,它的色阶略有不同。
高斯核与Box和Top-Hat相比具有更好的平滑特性。长方体过滤器不是各向同性的,会产生伪影(源显示为矩形)。Ricker小波滤波器去除噪声和缓慢变化的结构(即背景),但在源周围产生负环。过滤器的最佳选择很大程度上取决于应用。
可用内核#
|
2D Airy磁盘内核。 |
|
1D盒过滤器内核。 |
|
二维盒过滤器内核。 |
|
从列表或数组创建筛选器内核。 |
|
一维高斯滤波器核。 |
|
二维高斯滤波核。 |
|
一维Ricker小波滤波器核(有时称为“墨西哥帽”核)。 |
|
二维Ricker小波滤波器核(有时称为“墨西哥帽”核)。 |
|
从1D模型创建内核。 |
|
从二维模型创建内核。 |
|
二维Moffat内核。 |
|
二维环形滤波器内核。 |
|
2D Tophat过滤器内核。 |
|
一维梯形核。 |
|
二维梯形核。 |
核算法#
加减法#
由于卷积是一种线性运算,核可以相互加减。它们也可以与某个数相乘。
实例#
减去核的一个基本例子是高斯滤波器差分的定义:
>>> from astropy.convolution import Gaussian1DKernel
>>> gauss_1 = Gaussian1DKernel(10)
>>> gauss_2 = Gaussian1DKernel(16)
>>> DoG = gauss_2 - gauss_1
另一个应用是用仪器响应函数模型卷积伪数据。例如,如果响应函数可以用两个高斯函数的加权和来描述:
>>> gauss_1 = Gaussian1DKernel(10)
>>> gauss_2 = Gaussian1DKernel(16)
>>> SoG = 4 * gauss_1 + gauss_2
大多数情况下,需要通过显式调用来规范化生成的内核:
>>> SoG.normalize()
卷积#
此外,两个核可以相互卷积,这在用两种不同的核来过滤数据或创建一个新的、特殊的内核时非常有用。
实例#
将两个核相互卷积:
>>> from astropy.convolution import Gaussian1DKernel, convolve
>>> gauss_1 = Gaussian1DKernel(10)
>>> gauss_2 = Gaussian1DKernel(16)
>>> broad_gaussian = convolve(gauss_2, gauss_1)
或多级平滑:
>>> import numpy as np
>>> from astropy.modeling.models import Lorentz1D
>>> from astropy.convolution import convolve, Gaussian1DKernel, Box1DKernel
>>> rng = np.random.default_rng()
>>> lorentz = Lorentz1D(1, 0, 1)
>>> x = np.linspace(-5, 5, 100)
>>> data_1D = lorentz(x) + 0.1 * (rng.random(100) - 0.5)
>>> gauss = Gaussian1DKernel(3)
>>> box = Box1DKernel(5)
>>> smoothed_gauss = convolve(data_1D, gauss)
>>> smoothed_gauss_box = convolve(smoothed_gauss, box)
您宁愿执行以下操作:
>>> gauss = Gaussian1DKernel(3)
>>> box = Box1DKernel(5)
>>> smoothed_gauss_box = convolve(data_1D, convolve(box, gauss))
在大多数情况下,这种方法也比第一种方法快,因为只需要对通常大几倍的数据数组进行一次卷积。
离散化#
为了得到离散卷积的核阵列,在网格上计算核的响应函数 discretize_model()
. 对于离散化步骤,以下模式可用:
模式
'center'
(默认)通过获取bin中心的值来计算网格上的响应函数。>>> from astropy.convolution import Gaussian1DKernel >>> gauss_center = Gaussian1DKernel(3, mode='center')
模式
'linear_interp'
获取存储箱拐角处的值并线性插值中心的值:>>> gauss_interp = Gaussian1DKernel(3, mode='linear_interp')
模式
'oversample'
通过取过采样网格上的平均值来计算响应函数。过采样系数可以用factor
争论。如果过采样因子过大,评估会变慢。
>>> gauss_oversample = Gaussian1DKernel(3, mode='oversample', factor=10)
模式
'integrate'
使用在像素上集成函数scipy.integrate.quad
和scipy.integrate.dblquad
. 此模式非常慢,仅当需要最高精度时才建议使用。
>>> gauss_integrate = Gaussian1DKernel(3, mode='integrate')
特别是在核宽度仅为几个像素的范围内,使用模式是有利的 oversample
或 integrate
在亚像素尺度上保持积分。
归一化#
默认情况下,内核模型是标准化的(即。, \(\int_{{-\infty}}^{{\infty}} f(x) dx = 1\) ). 但是由于内核数组的大小有限,具有无限响应的内核的规范化可能与一个不同。这个偏差的值存储在内核的 truncation
属性。
由于离散化步骤,规范化也可能与一个不同,特别是对于小核函数。这可以部分地由 mode
参数,初始化内核时。(另请参见 discretize_model()
.)设置 mode
到 'oversample'
即使在亚像素尺度上也能保持标准化。
可以通过调用 normalize()
方法或通过设置 normalize_kernel
论证中 convolve()
和 convolve_fft()
功能。后一种方法保持内核本身不变,但使用内核的内部规范化版本。
请注意 RickerWavelet1DKernel
和 RickerWavelet2DKernel
有 \(\int_{{-\infty}}^{{\infty}} f(x) dx = 0\) . 为了定义一个适当的归一化,两个滤波器都是从归一化高斯函数导出的。