meshgrid
在三维图的绘制过程中,一般需要 x , y , z x,y,z x,y,z之间的对应关系,但对于图像而言,其 x , y x,y x,y轴坐标是体现在像素栅格中的,从而图像矩阵中的像素强度,其实表示的是 z z z轴的坐标,这种情况下如果想绘制三维散点图,就需要生成图像像素对应的坐标网格。
在Numpy
中,最常用的坐标网格生成函数,就是meshgrid
,其用法可参考下面的示例
x = [0,1,2,3,4]
y = [0,1,2,3]
xv, yv = np.meshgrid(x, y)
print(xv)
'''
[[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]]
'''
print(yv)
'''
[[0 0 0 0 0]
[1 1 1 1 1]
[2 2 2 2 2]
[3 3 3 3 3]]
'''
即xv为
[ 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 ] \begin{bmatrix} 0&1&2&3&4\\ 0&1&2&3&4\\ 0&1&2&3&4\\ 0&1&2&3&4\\ \end{bmatrix} 00001111222233334444
而yv为
[ 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 ] \begin{bmatrix} 0&0&0&0&0\\ 1&1&1&1&1\\ 2&2&2&2&2\\ 3&3&3&3&3\\ \end{bmatrix} 01230123012301230123
直观地说,就是对输入的 x , y x,y x,y变量,分别向 y y y轴和 x x x轴方向进行了扩张。
mgrid和ogrid
mgrid
是比meshgrid
更加简单的一种数据结构,其特点是直接通过魔法函数实现了坐标网格的生成。
>>> xv, yv = np.mgrid[0:2, 2:5]
>>> print(xv)
[[0 0 0]
[1 1 1]]
>>> print(yv)
[[2 3 4]
[2 3 4]]
当然,这个维度可以是任意的,而且步长也可以是任意的,
>>> np.mgrid[1:5]
array([1, 2, 3, 4])
>>> np.mgrid[1:10:5]
array([1, 6])
>>> np.mgrid[1.1:10]
array([1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1, 9.1])
如果翻阅源码,会发现mgrid
是MGridClass()
的一个实例,MGridClass
则是nd_grid
的一个子类,在nd_grid
中,实现了__getitem__
这个魔法函数,从而达成了[]
的索引方法。
ogrid
的用法与mgrid
相同,二者都是nd_grid
的子类,但生成的数组不同,直接看案例
>>>ogrid[0:5,0:5]
[array([[0],
[1],
[2],
[3],
[4]]), array([[0, 1, 2, 3, 4]])]
indices
如果想干脆一点,只是生成从0开始的等间隔的坐标网格,那么这里最推荐的是indices
,这个函数只需输入维度,就可以完成网格的创建。
接下来打开一张图片演示一下
import numpy as np
import matplotlib.pyplot as plt
img = plt.imread('test.jpg')
ax = plt.subplot(projection='3d')
gray = img[:,:,1]
yMat, xMat = np.indices(gray.shape)
ax.plot_surface(xMat, yMat, gray)
ax.axis('off')
plt.show()
效果为
最后总结一下indices, meshgird, mgrid的等价形式
indices | indices([M,N]) |
meshgrid | meshgrid(np.arange(M), np.arange(N)) |
mgrid | mgrid[:M,:N] |