Numpy 使用Scipy实现二维递归空间滤波器

Numpy 使用Scipy实现二维递归空间滤波器,numpy,image-processing,recursion,scipy,signal-processing,Numpy,Image Processing,Recursion,Scipy,Signal Processing,至少,我想知道如何实现标题中所述的目标。具体来说,signal.lfilter似乎是scipy中差分方程滤波器的唯一实现,但它是1D,如文档所示。我想知道如何实现如所述的2D版本。如果这像“兄弟,使用这个功能”一样简单,请让我知道,原谅我的幼稚,并随意忽略文章的其余部分 我是DSP新手,承认可能有不同的方法来回答我的问题,因此我将解释更广泛的目标,并给出问题的背景,希望有人知道我希望如何使用Scipy,或者可能是一种比我明确要求的更好的方法 简单来说,我使用矢量化计算方法(Numpy/Scipy

至少,我想知道如何实现标题中所述的目标。具体来说,signal.lfilter似乎是scipy中差分方程滤波器的唯一实现,但它是1D,如文档所示。我想知道如何实现如所述的2D版本。如果这像“兄弟,使用这个功能”一样简单,请让我知道,原谅我的幼稚,并随意忽略文章的其余部分

我是DSP新手,承认可能有不同的方法来回答我的问题,因此我将解释更广泛的目标,并给出问题的背景,希望有人知道我希望如何使用Scipy,或者可能是一种比我明确要求的更好的方法

简单来说,我使用矢量化计算方法(Numpy/Scipy)来实现蒙特卡罗模拟,以改进简单的for循环。我已经成功地将我的大部分操作抽象为数组计算/线性代数,但有一些特定的操作(递归计算)没有达到我的直觉,当我去寻找其他人是如何完成这类操作的时候,我不断地进入数字信号处理世界(或机器学习,但那些“框架”)(他们非常固执己见)。我的大多数谷歌搜索结果都指向scipy.signal或scipy.ndimage库引用的原因在这一点上我很清楚,在接受我的数据的“signal”表示之后,我花了相当长的时间(对于一个不是我自己的字段来说,这差不多是合理的)加快学习曲线,尝试从这些库中找出我需要的东西

我的模拟需要在n个周期内更新代表系统状态的数据向量,然后将整个过程重复“蒙特卡罗”次数。n个周期中的每个周期中的更新本质上是递归的,因为下一个周期取决于前一个周期的状态。它可以表示为如上所述的差分方程。此外,理论上,该向量在步长不均匀的点网格上建立索引。下面是一个示例向量
y
及其理论网格
t

y = np.r_[0.0024, 0.004, 0.0058, 0.0083, 0.0099, 0.0133, 0.0164]
t = np.r_[0.25, 0.5, 1, 2, 5, 10, 20]
对于n个“更新”中的每一个,我需要迭代地执行许多操作来
y
。具体来说,我使用有限差分近似计算沿曲线y(t)的曲率,并使用每个点的结果在下一次更新之前调整相应的y(t)。在循环中,这相当于在每次迭代中用所需的更新来替换变量重新分配

y += some_function(y) 
这不仅看起来效率低下,而且考虑到y是一个向量,向量化看起来很直观。此外,我对沿n次更新保存每个“更新的”y(t)感兴趣,这将需要一个len(y)xn维的数据结构。此时,为什么不在阵列中就地执行更新呢?这就是问题所在。我已经成功地将许多更新操作矢量化为“Numpy方式”(例如向每个点添加随机变量),但有些操作在数组世界中显得过于复杂

具体地,如上所述,使用相邻的两个元素来计算每个元素上的曲率,然后使用该结果来更新数组的下一行,然后执行自己的曲率“更新”。我能够实现非递归版本(每行都不考虑其“更新的自我”)。使用ndimage通用_过滤器执行曲率操作的前一行)。考虑到不均匀的网格,对于内核封装中的每个三元组,我都有唯一的系数(内核权重)(如果我有一个统一的网格,则不总是使用y''的

[1,-2,1]
)。最后一部分已经迫使我使用ndimage的空间过滤器,而不是1d卷积。我要指出的是,math.exchange post中讨论了一些概念上相似的东西,在我看来,只有第三个回答突出地提到了“卷积”的数学概念之间的区别它应该与需要两个连续过滤操作或一个巧妙合并的内核的通用空间过滤内核相关联

无论如何,这似乎并没有真正解决我的问题,因为这不是2D递归过滤,而是有一个向后看的内核足迹。此外,我认为我的结论是它不适用,因为它只允许以与递归大小成正比的方式进行“递归”(在空间过滤世界中向后看的内核足迹)。这意味着,如果我想过滤n行中的每一行,并合并所有先前行上的计算,那么它将需要一个太大的卷积内核(无论如何,对于我的n行来说)。如果我理解正确,递归线性滤波器在算法上更有效,因为它使用另一个伴生向量(z)返回(用于计算)在前n个样本上应用的自身结果(达到影响算法稳定性的水平)。在我的例子中,我只需要在输出信号
y[n-1]
处回顾一步,就可以从
x[n]
处的曲率计算
y[n]
,因为其余的结果就像一个累加。signal.lfilter适用于此,但我不能用它来计算曲率,因为这需要一个至少可以“看到”其左右邻域(像素)的内核封装,这就是我最终使用通用_过滤器的原因

在我看来,我应该能够同时使用一个过滤器,即空间过滤和递归过滤;或者不知何故,我错过了如何在数学上简化/组合(多重核的卷积?)

这似乎是一个常见的问题,但在信号处理和图像滤波中,可能很少同时进行这两项工作。也许这就是为什么您不单独使用信号库来实现