[英]How can I rotate a 3d array (nxnxn) by x degrees around x, y, and z axes?
我有一個用numpy創建的3d數組,我想知道如何通過自定義角度旋轉它,而不僅僅是numpy所具有的rot90
函數。 有人可以幫忙嗎?
3d矩陣表示圖像(例如立方體或其他形狀)即
0:
1 1 1
1 1
1 1 1
1:
1 1
1 1
2:
1 1 1
1 1
1 1 1
編輯:移動解決方案來回答
看看scipy.ndimage.interpolation.rotate函數。
這是因為scipy而不是numpy的原因是通過僅僅修改數組的索引來完成將圖像旋轉90度。 但是,如果要將圖像旋轉任意度數,則必須處理插值,這會給問題增加一層全新的復雜性。 這是因為當您將旋轉圖像旋轉90度時,原始圖像中的所有像素“與旋轉圖像中的像素完美對齊”。 旋轉圖像時通常不是這種情況。
經過一些試驗和錯誤后,我想出了一些代碼用於我的目的(0表示數組中為空,另一個數字表示填充的體素。
def rotate(self, deg_angle, axis):
d = len(self.matrix)
h = len(self.matrix[0])
w = len(self.matrix[0][0])
min_new_x = 0
max_new_x = 0
min_new_y = 0
max_new_y = 0
min_new_z = 0
max_new_z = 0
new_coords = []
angle = radians(deg_angle)
for z in range(d):
for y in range(h):
for x in range(w):
new_x = None
new_y = None
new_z = None
if axis == "x":
new_x = int(round(x))
new_y = int(round(y*cos(angle) - z*sin(angle)))
new_z = int(round(y*sin(angle) + z*cos(angle)))
elif axis == "y":
new_x = int(round(z*sin(angle) + x*cos(angle)))
new_y = int(round(y))
new_z = int(round(z*cos(angle) - x*sin(angle)))
elif axis == "z":
new_x = int(round(x*cos(angle) - y*sin(angle)))
new_y = int(round(x*sin(angle) + y*cos(angle)))
new_z = int(round(z))
val = self.matrix.item((z, y, x))
new_coords.append((val, new_x, new_y, new_z))
if new_x < min_new_x: min_new_x = new_x
if new_x > max_new_x: max_new_x = new_x
if new_y < min_new_y: min_new_y = new_y
if new_y > max_new_y: max_new_y = new_y
if new_z < min_new_z: min_new_z = new_z
if new_z > max_new_z: max_new_z = new_z
new_x_offset = abs(min_new_x)
new_y_offset = abs(min_new_y)
new_z_offset = abs(min_new_z)
new_width = abs(min_new_x - max_new_x)
new_height = abs(min_new_y - max_new_y)
new_depth = abs(min_new_z - max_new_z)
rotated = np.empty((new_depth + 1, new_height + 1, new_width + 1))
rotated.fill(0)
for coord in new_coords:
val = coord[0]
x = coord[1]
y = coord[2]
z = coord[3]
if rotated[new_z_offset + z][new_y_offset + y][new_x_offset + x] == 0:
rotated[new_z_offset + z][new_y_offset + y][new_x_offset + x] = val
self.matrix = rotated
我使用上面代碼的方式是:
cube = Rect_Prism(20, 20, 20) # creates a 3d array similar to above example, just bigger
cube.rotate(20, "x")
cube.rotate(60, "y")
Rect_Prism創建MxNxD矩陣,但在這種情況下為NxNxN。
打印時的結果:
# # # # # # # # # # # #
# # # # # # #
# # # # # # #
# # # # #
# # # # # # # #
# # # # # # #
# # # # # # # # # # # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # # # #
# # # #
# # # # # # # # # # # #
# # # # #
# # # # # # # #
# # # # # # #
# # # # # # #
# # # # # # #
# # # # # #
# # # # # # # # # # # #
我認為你應該考慮數據的“矢量”表示,而不是當前的“光柵”表示。
矢量表示意味着,而不是每個“體素”由其在網格中的位置定義,您將擁有某種體素列表,具有實際的3D坐標。
因此,不是每個體素都是“黑/白”點的MxNxD矩陣,而是可以有一個Mx3矩陣,其中每一行都是一個點,列是X,Y和Z.
這樣,您可以將列表乘以3x3旋轉矩陣,並獲得另一個變換坐標列表。
您將繼續將這些矢量點(或更好的線)“渲染”到柵格矩陣(像素或體素,但您的樣本圖像看起來像3D信息已投影到2D空間)的問題。 有很多技術可以做到這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.