You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在保留Numpy数组维度的同时无裁剪旋转3D立方体?

解决scipy.ndimage.rotate旋转立方体时的裁剪与维度保留问题

我用解析方程在3D NumPy数组中创建立方体,代码如下(注:原代码存在语法错误,已修正range的终止值):

import numpy as np

A = np.zeros((150, 150, 150))   # 存储立方体的数组
r = 15   # 立方体边长
c = (39, 36, 119)   # 立方体中心坐标
# 修正原代码的语法错误:range终止值补充r
for x in range(c[0] - r, c[0] + r):
    for y in range(c[1] - r, c[1] + r):
        for z in range(c[2] - r, c[2] + r):
            deb = r - max(abs(c[0] - x), abs(c[1] - y), abs(c[2] - z))   # 立方体判定方程
            if deb >= 0: 
                A[x, y, z] = 1

这段代码生成与坐标轴对齐的立方体。随后使用scipy.ndimage.rotate旋转立方体:

import scipy.ndimage

A = scipy.ndimage.rotate(A, np.random.randint(0, 90), reshape=False, axes=(0, 1))

遇到的问题:

  • 设置reshape=False时,数组维度保留,但旋转后的立方体可能被边缘裁剪
  • 设置reshape=True时,立方体完整无裁剪,但数组形状会改变

需要沿用scipy.ndimage.rotate方法,同时实现保留原数组维度和立方体无裁剪的效果。


解决方案思路

核心是先获取完整旋转后的立方体,再将其居中放置到原尺寸的数组中,既保留原维度,又避免裁剪。具体步骤:

  1. 用reshape=True执行旋转,得到完整的旋转后数组(无裁剪)
  2. 计算原数组与旋转后数组的尺寸差,确定居中偏移量
  3. 创建原尺寸的空数组,将旋转后的立方体居中填充进去

代码实现

import numpy as np
import scipy.ndimage

# 1. 创建立方体(修正原代码语法错误)
A = np.zeros((150, 150, 150))
r = 15
c = (39, 36, 119)
for x in range(c[0] - r, c[0] + r):
    for y in range(c[1] - r, c[1] + r):
        for z in range(c[2] - r, c[2] + r):
            deb = r - max(abs(c[0] - x), abs(c[1] - y), abs(c[2] - z))
            if deb >= 0:
                A[x, y, z] = 1

# 2. 执行完整旋转(reshape=True)
rotate_angle = np.random.randint(0, 90)
A_rotated_full = scipy.ndimage.rotate(A, rotate_angle, reshape=True, axes=(0, 1))

# 3. 将完整旋转后的立方体居中放入原尺寸数组
original_shape = A.shape
rotated_shape = A_rotated_full.shape

# 计算各维度的偏移量,确保立方体居中
offset_x = (original_shape[0] - rotated_shape[0]) // 2
offset_y = (original_shape[1] - rotated_shape[1]) // 2
offset_z = (original_shape[2] - rotated_shape[2]) // 2  # 本次旋转未涉及z轴,此处offset_z为0

# 创建原尺寸的空数组
A_final = np.zeros(original_shape)

# 确定填充区域的边界,避免索引越界
x_slice = slice(max(0, offset_x), min(original_shape[0], offset_x + rotated_shape[0]))
y_slice = slice(max(0, offset_y), min(original_shape[1], offset_y + rotated_shape[1]))
z_slice = slice(max(0, offset_z), min(original_shape[2], offset_z + rotated_shape[2]))

# 对应旋转后数组的切片
rot_x_slice = slice(max(0, -offset_x), min(rotated_shape[0], original_shape[0] - offset_x))
rot_y_slice = slice(max(0, -offset_y), min(rotated_shape[1], original_shape[1] - offset_y))
rot_z_slice = slice(max(0, -offset_z), min(rotated_shape[2], original_shape[2] - offset_z))

# 填充立方体
A_final[x_slice, y_slice, z_slice] = A_rotated_full[rot_x_slice, rot_y_slice, rot_z_slice]

补充说明

  • 若旋转涉及其他坐标轴(如(0,2)或(1,2)),只需调整对应的偏移量计算即可
  • 此方法的前提是原数组尺寸足够大,能容纳旋转后的立方体。如果原数组本身过小,即使居中也会裁剪,此时需要先对原数组进行padding,旋转后再裁剪回原尺寸

内容的提问来源于stack exchange,提问作者hnambui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:06:14