代码之家  ›  专栏  ›  技术社区  ›  fmw42

scipy插值网格数据

  •  0
  • fmw42  · 技术社区  · 6 年前

    我主要是一个python/numpy/scipy新手,但对图像处理和imagemagick很熟悉。我的最终目标是使用python/numpy/scipy将两个稀疏的数据网格插入到图像中,然后在imagemagick中用作X和Y位移映射,将一个网格扭曲到另一个网格中。我有点追随 https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html .

    我有一个图像(SRC):

    enter image description here

    我最终想要扭曲到(dst),尽管图像和扭曲过程与这里提出的问题(网格相交值除外)无关:

    enter image description here

    我有两组X、Y控制点,每个图像中有一个控制点,如中所示 http://www.fmwconcepts.com/misc_tests/grid16_control_points2.txt

    我已经计算了zx=xsrc xdst+127.5和zy=ysrc ydst+127.5作为dstx、dsty坐标的值,我想在整个129x129图像上插入这些值。(请注意,附加的127.5用于imagemagick使用——上面的位移图图像中的任何值将朝一个方向移动,下面的值将朝相反的方向移动)

    下面的“我的代码”不显示任何错误消息,也不显示任何图像。我想我工作最多,除了PLT节目。但是,我希望有人能指出我做错了什么。

    #!/bin/python3.7
    
    """
    
    Use interpolation on a grid of x,y,z values, where z is either xdiff or ydiff for use as imagemagick 2D displacement maps
    
    """
    
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.interpolate import griddata as griddata
    from PIL import Image
    
    # test grid data is from https://imagemagick.org/Usage/distorts/#polynomial (zx and zy are xsrc-xdst and ysrc-ydst)
    
    # python lists of x,y dst control points and zx=xsrc-xdiff, zy=ysrc-ydiff offsets to be interpolated over full image of size 129x129
    xy = [[8.5,7.5], [20.5,5.5], [33.5,3.5], [48.5,1.5], [64.5,1.5], [80.5,1.5], [95.5,3.5], [109.5,5.5], [121.5,7.5], [5.5,20.5], [17.5,16.5], [31.5,14.5], [46.5,12.5], [64.5,11.5], [81.5,12.5], [97.5,15.5], [111.5,16.5], [123.5,19.5], [2.5,33.5], [14.5,31.5], [29.5,28.5], [45.5,26.5], [64.5,24.5], [83.5,26.5], [99.5,28.5], [113.5,31.5], [125.5,33.5], [1.5,48.5], [12.5,47.5], [26.5,45.5], [43.5,42.5], [64.5,40.5], [85.5,42.5], [103.5,45.5], [116.5,46.5], [127.5,48.5], [0.5,64.5], [11.5,64.5], [24.5,64.5], [41.5,64.5], [64.5,64.5], [87.5,64.5], [103.5,64.5], [117.5,64.5], [128.5,64.5], [1.5,80.5], [12.5,81.5], [25.5,83.5], [42.5,86.5], [64.5,87.5], [86.5,86.5], [103.5,83.5], [116.5,81.5], [127.5,80.5], [2.5,95.5], [14.5,97.5], [28.5,100.5], [45.5,103.5], [64.5,104.5], [83.5,102.5], [100.5,100.5], [114.5,97.5], [125.5,95.5], [5.5,109.5], [17.5,111.5], [30.5,114.5], [46.5,116.5], [64.5,117.5], [81.5,116.5], [97.5,114.5], [111.5,111.5], [123.5,109.5], [8.5,121.5], [19.5,123.5], [33.5,125.5], [48.5,127.5], [64.5,127.5], [80.5,127.5], [95.5,125.5], [109.5,123.5], [121.5,120.5]]
    zx = [119.5, 123.5, 126.5, 127.5, 127.5, 127.5, 128.5, 130.5, 134.5, 122.5, 126.5, 128.5, 129.5, 127.5, 126.5, 126.5, 128.5, 132.5, 125.5, 129.5, 130.5, 130.5, 127.5, 124.5, 124.5, 126.5, 130.5, 126.5, 131.5, 133.5, 132.5, 127.5, 122.5, 120.5, 123.5, 128.5, 127.5, 132.5, 135.5, 134.5, 127.5, 120.5, 120.5, 122.5, 127.5, 126.5, 131.5, 134.5, 133.5, 127.5, 121.5, 120.5, 123.5, 128.5, 125.5, 129.5, 131.5, 130.5, 127.5, 124.5, 123.5, 125.5, 130.5, 122.5, 126.5, 129.5, 129.5, 127.5, 126.5, 126.5, 128.5, 132.5, 119.5, 124.5, 126.5, 127.5, 127.5, 127.5, 128.5, 130.5, 134.5]
    zy = [120.5, 122.5, 124.5, 126.5, 126.5, 126.5, 124.5, 122.5, 120.5, 123.5, 127.5, 129.5, 131.5, 132.5, 131.5, 128.5, 127.5, 124.5, 126.5, 128.5, 131.5, 133.5, 135.5, 133.5, 131.5, 128.5, 126.5, 127.5, 128.5, 130.5, 133.5, 135.5, 133.5, 130.5, 129.5, 127.5, 127.5, 127.5, 127.5, 127.5, 127.5, 127.5, 127.5, 127.5, 127.5, 127.5, 126.5, 124.5, 121.5, 120.5, 121.5, 124.5, 126.5, 127.5, 128.5, 126.5, 123.5, 120.5, 119.5, 121.5, 123.5, 126.5, 128.5, 130.5, 128.5, 125.5, 123.5, 122.5, 123.5, 125.5, 128.5, 130.5, 134.5, 132.5, 130.5, 128.5, 128.5, 128.5, 130.5, 132.5, 135.5]
    
    # convert python lists to numpy arrays
    axy = np.asarray(xy, dtype=float)
    azx = np.asarray(zx, dtype=float)
    azy = np.asarray(zy, dtype=float)
    
    # define integer grid onto which to interpolate
    grid_x, grid_y = np.mgrid[0:129, 0:129]
    
    # do interpolations
    xdisplace = griddata(axy, azx, (grid_x, grid_y), method='cubic')
    ydisplace = griddata(axy, azy, (grid_x, grid_y), method='cubic')
    
    # replace all NAN with zero
    xxdisplace = np.nan_to_num(xdisplace, copy=True)
    yydisplace = np.nan_to_num(ydisplace, copy=True)
    
    # Note: 3rd order polynomial interpolation can go wild and produce NAN values outside the normal range
    # replace all NAN with zero
    xxdisplace = np.nan_to_num(xdisplace, copy=True)
    yydisplace = np.nan_to_num(ydisplace, copy=True)
    
    # replace zero with 127.5
    xxdisplace[xxdisplace == 0] = 127.5
    yydisplace[yydisplace == 0] = 127.5
    
    # display a subsection to examine interpolation
    xxdsub = xxdisplace[0:5, 0:5]
    print(xxdsub)
    
    # display another subsection to examine interpolation
    xxdsub = xxdisplace[60:65, 60:65]
    print(xxdsub)
    
    # save images
    xdimg = Image.fromarray(xxdisplace.astype('uint8'))
    ydimg = Image.fromarray(yydisplace.astype('uint8'))
    xdimg.save('xdimg.png')
    ydimg.save('ydimg.png')
    
    # display images
    plt.figure()
    plt.imshow(xxdisplace.astype('uint8'))
    plt.imshow(yydisplace.astype('uint8'))
    plt.show()
    


    我修改了我的原始代码来添加代码,用零替换NaN,然后用127.5替换零。但我没有收到错误信息,也没有显示图像。(在其他脚本中,plt.imshow()工作正常)。

    第一个xdsub现在只包含127.5的值(从nan开始)

    [[127.5 127.5 127.5 127.5 127.5]
     [127.5 127.5 127.5 127.5 127.5]
     [127.5 127.5 127.5 127.5 127.5]
     [127.5 127.5 127.5 127.5 127.5]
     [127.5 127.5 127.5 127.5 127.5]]
    


    第二个xdsub数据显示了合理的插值数据。

    【129.129950391 129.13466567 129.14438372 129.15604101 129.16453265】 【128.77872804 128.78027629 128.78368175 128.79182482 128.7988161】 [128.41763609 128.4225153 128.4226885 128.42491114 128.43014312] 【128.0492988 128.05418802 128.05800038 128.05793775 128.05925686】 【127.68687259 127.68699624 127.68719118 127.68750429 127.68722127】】


    关于我的代码的任何建议都将是最受欢迎的。

    我使用的是python 3.7.2、numpy 1.16.1、scipy 1.2.1和matplotlib 3.0.2(所有这些都是通过MacPorts安装在Mac OSX Sierra上的)

    0 回复  |  直到 6 年前
        1
  •  0
  •   bollence    6 年前

    默认 griddata() 的参数 填充值 设置为 . 大量负数的原因是转换的结果 int . 您可以尝试删除 .astype(int) .