设置我的示例
首先,我将使用一个不同的示例,因为我想知道我应该得到什么结果。我的示例是一个 100x100x100 的数组,其中包含一个半径为 50 的球。
我采用了this answer 的代码来绘制它。
n = 100
def distance_from_center(x,y,z):
V = np.stack([x-n/2,y-n/2,z-n/2])
return np.linalg.norm(V, axis=0)
ball = np.fromfunction(distance_from_center, (n, n, n), dtype='float')
ball = (ball > 50).astype('int')
基本解决方案
你可以用 4 行代码来做这样的事情。所以在我变得更花哨之前,我会先这样做。我的第一片是从一个角落到另一个角落。像这样:
我已经用绿色标记了我要切片的位置。
t = np.arange(n)
slice = ball[t,t,:]
plt.matshow(slice.T, cmap='gray')
plt.gca().set_aspect(1/2**(1/2))
请注意,我必须将纵横比设置为 2 的平方根的 1,因为对角线方向上的 50 个像素比普通方向上的 50 个像素要长。图片看起来像预期的那样。两边都有空白,因为数组的角为其提供了空间,但我们仍然得到一个圆圈。
您可以像这样进行其他切割,但您总是在考虑如何获得整数坐标。
更复杂的解决方案
另一种方法是只取任何坐标并在您不能完美命中的点之间进行插值。
import itertools
class Image_knn():
def fit(self, image):
self.image = image.astype('float')
def predict(self, x, y, z):
image = self.image
weights_x = [(1-(x % 1)).reshape(-1), (x % 1).reshape(-1)]
weights_y = [(1-(y % 1)).reshape(-1), (y % 1).reshape(-1)]
weights_z = [(1-(z % 1)).reshape(-1), (z % 1).reshape(-1)]
start_x = np.floor(x)
start_y = np.floor(y)
start_z = np.floor(z)
return sum([image[np.clip(np.floor(start_x + x), 0, image.shape[0]-1).astype('int'),
np.clip(np.floor(start_y + y), 0, image.shape[1]-1).astype('int'),
np.clip(np.floor(start_z + z), 0, image.shape[1]-1).astype('int')]
*weights_x[x]*weights_y[y]*weights_z[z]
for x,y,z in itertools.product(range(2),range(2),range(2))])
image_model = Image_knn()
image_model.fit(ball)
fig, ax = plt.subplots(nrows=3,ncols=3)
ax = ax.reshape(-1)
我将给出一个使用不同切片的示例,其中一个方向是 z 方向,另一个是包含左下角和右下角不同点的方向。首先是指示切割位置的 3d 图:
现在我计算切割的坐标并绘制它们。这次我可以保持纵横比,因为我在更长的方向上使用了更多的点。请注意,我将第二个点的坐标放在绘图的标题中。
fig, ax = plt.subplots(nrows=3,ncols=3)
ax = ax.reshape(-1)
for i,x in enumerate(np.linspace(0,100,9)):
p = np.array([0,100])
q = np.array([100,100-x])
distance = np.round(np.linalg.norm(q-p)).astype('int')
t = np.linspace(0,1,distance)
xy = t.reshape(-1,1)*q+(1-t).reshape(-1,1)*p
r,s = np.meshgrid(np.arange(100), np.arange(distance))
x = xy[s][:,:,0].reshape(-1)
y = xy[s][:,:,1].reshape(-1)
z = r.reshape(-1)
out = image_model.predict(x,y,z)
ax[i].imshow(out.reshape(distance, 100).T, cmap='gray',vmin=0,vmax=1)
ax[i].set_title(tuple(q.astype('int')))