Python中在规则网格上的插值
我一直在努力为我的二维矩阵中的“空”像素进行插值。简单来说,我对一些插值技术有些了解,比如反距离加权、克里金法、双三次插值等等,但并不是很深入。我不太确定从哪里开始(无论是在问题的描述上还是在Python的应用上)。
问题定义:
我有一个MxN的矩阵(规则网格),其中每个像素代表某个测量值(下面的图,以及这个图使用的数据可以在这里找到)。我想利用已有的蓝色像素数据,为“问号区域”(白色区域,大小相同但像素为空)进行插值。
我的问题:
1) 我该如何进行数据插值?能否给我一个简单的例子(比如3x3的矩阵),让我更清楚地理解?
2) 有人能指导我如何在Python环境中执行解决方案的步骤吗?
3) 我该如何在Python中比较不同插值技术的准确性?
4) 你认为根据数据的密度使用不同的插值方法是个好主意吗?
我会很感激你们的回答和建议。
1 个回答
一个合理的解决方案主要取决于你想通过插值像素回答什么问题——需要注意的是:在缺失数据上进行外推可能会导致非常误导的结果!
径向基函数插值 / 核平滑
在Python中,有一种实用的解决方案是使用Scipy的径向基函数插值(可以在这里找到相关信息),这个方法是用来平滑和插值散乱数据的。
假设你有一个矩阵M
和对应的一维坐标数组r
和c
(这样M.shape == (r.size, c.size)
),其中缺失的M的值被设置为nan
,使用线性RBF核的效果还不错,如下所示:
import numpy as np
import scipy.interpolate as interpolate
with open('measurement.txt') as fh:
M = np.vstack(map(float, r.split(' ')) for r in fh.read().splitlines())
r = np.linspace(0, 1, M.shape[0])
c = np.linspace(0, 1, M.shape[1])
rr, cc = np.meshgrid(r, c)
vals = ~np.isnan(M)
f = interpolate.Rbf(rr[vals], cc[vals], M[vals], function='linear')
interpolated = f(rr, cc)
这会生成你上面链接的数据的插值,虽然看起来还不错,但确实显示了缺失样本和真实数据的比例不太理想:
高斯过程回归 / 克里金插值
克里金插值可以通过高斯过程回归的实现来使用(这个实现是基于Matlab的DACE克里金工具箱),在scikit-learn库中可以这样调用:
from sklearn.gaussian_process import GaussianProcess
gp = GaussianProcess(theta0=0.1, thetaL=.001, thetaU=1., nugget=0.01)
gp.fit(X=np.column_stack([rr[vals],cc[vals]]), y=M[vals])
rr_cc_as_cols = np.column_stack([rr.flatten(), cc.flatten()])
interpolated = gp.predict(rr_cc_as_cols).reshape(M.shape)
这会产生与上面的径向基函数示例非常相似的插值。在这两种情况下,有很多参数可以调整——这些选择主要取决于你对数据的假设。(上面RBF示例中使用的线性核的一个优点是它没有自由参数)
图像修复
最后,完全基于视觉的解决方案是使用OpenCV的图像修复功能,尽管这要求使用8位数组(0 - 255),并且没有简单的数学解释。