无法使用Mathplotlib.pyplot显示Scipy插值网格数据

时间:2019-03-28 23:57:37

标签: python numpy scipy imagemagick

我主要是Python / Numpy / Scipy的新手,但是非常了解图像处理和Imagemagick。我的最终目标是使用Python / Numpy / Scipy将2个稀疏数据网格插值成图像,然后可以将它们用作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.show以外,我工作最多。但是,我希望有人能指出我做错了什么。

#!/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.12950391 129.13466567 129.14438372 129.15604101 129.16453265]  [128.77872804 128.78027629 128.78368175 128.79182482 128.7988161]  [128.41763609 128.42225153 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(均通过Mac OSX Sierra上的MacPorts安装)

1 个答案:

答案 0 :(得分:0)

默认情况下,griddata()的参数 fill_value 设置为 nan 。 负数较大的原因是将 nan 转换为 int 的结果。您可以尝试删除.astype(int)