【发布时间】:2023-03-03 06:48:21
【问题描述】:
我主要是 Python/Numpy/Scipy 新手,但非常了解图像处理和 Imagemagick。我的最终目标是使用 Python/Numpy/Scipy 将 2 个稀疏的数据网格插入到图像中,然后这些图像可以用作 Imagemagick 中的 x 和 y 置换贴图,从而将一个数据变形为另一个数据。我有点关注https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html。
我有一张图片(src):
我最终想要变形为 (dst),尽管该图像和变形过程与此处提出的问题无关(网格交点值除外):
我有两组 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 安装)
【问题讨论】:
-
我用 PIL xdimg.show() 替换了 plt.imshow(xxdisplace.astype('uint8')) 并且它有效。它也适用于 Skimage io.imshow()。但我仍然想了解如何使用 plt.imshow 使其显示。 它似乎启动了 matplotlib.pyplot,但随后立即关闭它,好像数据不兼容。 使用 OpenCV cv2 读取和图像,然后使用 Mathplotlib.pyplot 显示工作正常。
标签: python numpy scipy imagemagick