• 双线性插值


    双线性插值问题描述:
    给定矩形四个点,求矩形内部任意一点的颜色。
    设某一点的颜色为f(x,y)=a+bx+cy+dxy,四个变量四个未知数,可以解此方程

    插值的目的是为了显得平滑。
    也可以自己设计插值,比如:求出点(x,y)到矩形四个点的距离,用这个距离作为每个点的权值,距离越小,权重越大。

    import matplotlib.pyplot as plt
    import numpy as np
    from skimage import data, io
    
    """
    STN:Spatial Transform Network
    
    里面用到了双线性插值,难点就是使用tensorflow实现
    """
    a = data.astronaut()[19:168, 140:316]
    
    
    def get(a, x, y, method):
        xx = a.shape[0] * x
        yy = a.shape[1] * y
        (fx, fy), (tx, ty) = np.floor([xx, yy]), np.ceil([xx, yy])
        fx, fy, tx, ty = np.int32([fx, fy, tx, ty])
        tx = min(tx, a.shape[0] - 1)
        ty = min(ty, a.shape[1] - 1)
        if fx == tx and fy == ty:
            return a[fx, fy]
        elif fx == tx:
            w = (yy - fy) / (ty - fy)
            return w * a[fx, fy] + (1 - w) * a[fx, ty]
        elif fy == ty:
            w = (xx - fx) / (tx - fx)
            return w * a[fx, fy] + (1 - w) * a[tx, ty]
        c = np.empty(3, np.int32)
        if method == 'bilinear':
            A = [
                [1, fx, fy, fx * fy],
                [1, fx, ty, fx * ty],
                [1, tx, fy, tx * fy],
                [1, tx, ty, tx * ty]
            ]
            for i in range(3):
                args = np.linalg.solve(A, [a[fx, fy, i], a[fx, ty, i], a[tx, fy, i], a[tx, ty, i]])
                c[i] = np.dot([1, xx, yy, xx * yy], args)
        elif method == 'distance':
            """
            我自己发明的,按照点到四个点的距离进行加权求和
            """
            ps = np.array([[fx, fy], [fx, ty], [tx, fy], [tx, ty]])
            dis = np.linalg.norm(np.array([xx, yy]) - ps, ord=2, axis=1)
            d = np.sum(dis)
            weight = (d - dis) / d
            weight = weight / np.sum(weight)
            c = np.matmul(weight.reshape(1, 4), a[ps[:, 0], ps[:, 1], :])
        return c
    
    
    def scale(x_scale, y_scale, a, method='bilinear'):
        assert len(a.shape) == 3 and a.shape[2] == 3
        b = np.empty([a.shape[0] * x_scale, a.shape[1] * y_scale, a.shape[2]])
        for i in range(b.shape[0]):
            for j in range(b.shape[1]):
                b[i, j] = np.int32(get(a, i / b.shape[0], j / b.shape[1], method))
        return b.astype(np.uint8)
    
    
    larger = scale(4, 4, a, 'bilinear')
    dis_image = scale(4, 4, a, 'distance')
    fig, axis = plt.subplots(1, 3)
    for ax, img, title in zip(axis, [a, larger, dis_image], ['original', 'bilinear', 'distance']):
        ax.imshow(img)
        ax.axis('off')
        ax.set_title(title)
    plt.show()
    io.imsave('linear.jpg', larger)
    io.imsave('distance.jpg', dis_image)
    io.imsave('original.jpg', a)
    
    
  • 相关阅读:
    bzoj1096 [ZJOI2007]仓库建设
    bzoj2054 疯狂的馒头
    bzoj1597 [Usaco2008 Mar]土地购买
    【洛谷P1083】[NOIP2012]借教室
    【洛谷P1367】蚂蚁
    【洛谷P1886】滑动窗口
    【洛谷P2216】[HAOI2007]理想的正方形
    【题解】洛谷P2914[USACO08OCT]断电Power Failure
    【数据结构】数组模拟链表
    【题解】洛谷P1002过河卒
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/9638322.html
Copyright © 2020-2023  润新知