在matlab中我们可以通过interp2在矩形网格内进行曲线插值,那么在python中有没有有类似的函数呢?有,并且有很多,都在scipy.interpolate模块中。这篇博客主要说两个比较相似的:interp2d和rectBivariateSpline。两者比较相似,如果输入是规整的网格点,那么使用rectBivariateSpline会更快。下面给一些介绍和例子:

官方文档:interp2d   rectBivariateSpline 

一些例子:rectBivariateSpline例子

有上面的文档相信已经够了,这里强调用法中几点注意事项:

  • 输入虽然标识为x,y,但事实上第一个参数是axis=0,第二个参数对应axis=1
  • rectBivariateSpline中控制插值函数阶次的参数是kx,ky
  • interp2d中控制插值方法的参数是kind  ,kind=’cubic’ 表示三次插值
  • 这两个函数,输入参数x,y均为x和y方向上的网格向量
  • 在调用插值时,如果需要采样的点构成一个正立的矩形网格的话,那么输入x和y就输入向量就可以,它会输出 x*y 坐标空间上的2d插值结果。如果需要插值的是一系列离散的点,或者不构成正立网格,那么输入的x和y就是一系列点的坐标,它会输出(x,y)坐标空间上离散点的插值结果。指示插值点规则的参数是grid,默认是true的。

我们先看一个grid=True的例子,利用插值缩放图像(resample)的例子:

# 需要導入模塊: from scipy import interpolate [as 別名]
# 或者: from scipy.interpolate import RectBivariateSpline [as 別名]
def resample_2d(array, sample_pts, query_pts):
    ''' Resamples 2D array to be sampled along queried points.

    Args:
        array (numpy.ndarray): 2D array.

        sample_pts (tuple): pair of numpy.ndarray objects that contain the x and y sample locations,
            each array should be 1D.

        query_pts (tuple): points to interpolate onto, also 1D for each array.

    Returns:
        numpy.ndarray.  array resampled onto query_pts via bivariate spline.

    '''
    xq, yq = np.meshgrid(*query_pts)
    interpf = interpolate.RectBivariateSpline(*sample_pts, array)
    return interpf.ev(yq, xq) 

我们再看一个grid=False的例子,利用插值旋转图像(rotation)的例子:

# 需要導入模塊: from scipy import interpolate [as 別名]
# 或者: from scipy.interpolate import RectBivariateSpline [as 別名]
def rotate_ground(original, theta, horizon=60, half_height=360 / 2, focal=1.0):
        height, width, channel = original.shape
        # the target grids
        yp = range(height - horizon, height)
        xp = range(0, width)

        # from pixel to coordinates
        y0 = (np.array(yp) - half_height) * 1.0 / half_height
        x0 = (np.array(xp) - width / 2) / (width / 2.0)

        # form the mesh
        mesh = MyDataset.generate_meshlist(x0, y0)
        # compute the source coordinates
        st = math.sin(theta)
        ct = math.cos(theta)
        deno = ct * focal + st * mesh[:, 0]
        out = np.array([(-st * focal + ct * mesh[:, 0]) / deno, mesh[:, 1] / deno])

        # interpolate
        vout = []
        for i in range(3):
            f = interpolate.RectBivariateSpline(y0, x0, original[- horizon:, :, i])
            values = f(out[1, :], out[0, :], grid=False)
            vout.append(values)

        lower = np.reshape(vout, (3, width, horizon)).transpose((2, 1, 0)).astype("uint8")

        # compute the upper part
        out = np.reshape(out[0, :], (width, horizon))
        out = out[:, 0]
        f = interpolate.interp1d(x0, original[:-horizon, :, :], axis=1,
                                 fill_value=(original[:-horizon, 0, :], original[:-horizon, -1, :]),
                                 bounds_error=False)
        ans = f(out)
        ans = ans.astype("uint8")

        return np.concatenate((ans, lower), axis=0) 

谢谢,希望能有帮助!

发表评论

邮箱地址不会被公开。 必填项已用*标注