Numpy 最快的 3D 到 2D 投影
Numpy fastest 3D to 2D projection
我有一个二进制数据的 3D 数组。我想将其投影到 3 个 2D 图像 - 侧面,正面,鸟瞰图。
我写了代码:
for x in range(data.shape[2]):
for y in range(data.shape[0]):
val = 0
for z in range(data.shape[1]):
if data[y][z][x] > 0:
val = 255
break
side[y][x] = val
但是对于 ~700x300x300 矩阵来说,这太慢了(75 秒!)。
完成此任务最快的方法是什么?
编辑:
为了保存图像,我使用了:
sideImage = Image.fromarray(side)
sideImage.convert('RGB').save("sideImage.png")
您可以按如下方式计算:
>>> data = np.random.random_sample((200, 300, 100)) > 0.5
>>> data.any(axis=-1).shape # show the result has the shape we want
(200, 300)
>>> data.any(axis=-1)
array([[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
...,
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True]], dtype=bool)
>>>
如果需要,您可以缩放值
>>> data.any(axis=-1) * 255
array([[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
...,
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255]])
>>>
当我有 3D 数据时,我倾向于将其视为 'cube' 具有行、列和切片 - 或面板的 2D 图像。每个切片或面板都是尺寸为 (rows, cols)
的二维图像。我通常是这样想的:
with (0,0,0)
在 front 切片的左上角。使用 numpy
索引,只需 select 您感兴趣的 3D 数组部分 就非常容易 而无需编写自己的循环 :
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> np.set_printoptions(precision=2)
# Generate a 3D 'cube' of data
>>> data3D = np.random.uniform(0,10, 2*3*5).reshape((2,3,5))
>>> data3D
array([[[ 7.44, 1.14, 2.5 , 3.3 , 6.05],
[ 1.53, 8.91, 1.63, 8.95, 2.46],
[ 3.57, 3.29, 6.43, 8.81, 6.43]],
[[ 4.67, 2.67, 5.29, 7.69, 7.59],
[ 0.26, 2.88, 7.58, 3.27, 4.55],
[ 5.84, 9.04, 7.16, 9.18, 5.68]]])
# Grab some "views" of the data
>>> front = data3D[:,:,0] # all rows and columns, first slice
>>> back = data3D[:,:,-1] # all rows and cols, last slice
>>> top = data3D[0,:,:] # first row, all cols, all slices
>>> bottom = data3D[-1,:,:] # last row, all cols, all slices
>>> r_side = data3D[:,-1,:] # all rows, last column, all slices
>>> l_side = data3D[:,0,:] # all rows, first column, all slices
看看前面的样子:
>>> plt.imshow(front, interpolation='none')
>>> plt.show()
前段时间我写了以下内容作为 3D 阵列的可视化辅助工具。也是一个很好的学习练习。
# Python 2.7.10
from __future__ import print_function
from numpy import *
def f_Print3dArray(a_Array):
v_Spacing = (len(str(amax(abs(a_Array)))) + 1) if amin(a_Array)\
< 0 else (len(str(amax(a_Array))) + 1)
for i in a_Array[:,:,::-1].transpose(0,2,1):
for index, j in enumerate(i):
print(" " * (len(i) - 1 - index) + "/ ", end="")
for k in j:
print(str(k).ljust( v_Spacing + 1), end="")
print("/")
print()
a_Array = arange(27).reshape(3, 3, 3)
print(a_Array)
print()
f_Print3dArray(a_Array)
转换为:
[[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]]
[[ 9 10 11]
[12 13 14]
[15 16 17]]
[[18 19 20]
[21 22 23]
[24 25 26]]]
为此:
/ 2 5 8 /
/ 1 4 7 /
/ 0 3 6 /
/ 11 14 17 /
/ 10 13 16 /
/ 9 12 15 /
/ 20 23 26 /
/ 19 22 25 /
/ 18 21 24 /
希望对大家有所帮助。
我有一个二进制数据的 3D 数组。我想将其投影到 3 个 2D 图像 - 侧面,正面,鸟瞰图。
我写了代码:
for x in range(data.shape[2]):
for y in range(data.shape[0]):
val = 0
for z in range(data.shape[1]):
if data[y][z][x] > 0:
val = 255
break
side[y][x] = val
但是对于 ~700x300x300 矩阵来说,这太慢了(75 秒!)。
完成此任务最快的方法是什么?
编辑:
为了保存图像,我使用了:
sideImage = Image.fromarray(side)
sideImage.convert('RGB').save("sideImage.png")
您可以按如下方式计算:
>>> data = np.random.random_sample((200, 300, 100)) > 0.5
>>> data.any(axis=-1).shape # show the result has the shape we want
(200, 300)
>>> data.any(axis=-1)
array([[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
...,
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True]], dtype=bool)
>>>
如果需要,您可以缩放值
>>> data.any(axis=-1) * 255
array([[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
...,
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255]])
>>>
当我有 3D 数据时,我倾向于将其视为 'cube' 具有行、列和切片 - 或面板的 2D 图像。每个切片或面板都是尺寸为 (rows, cols)
的二维图像。我通常是这样想的:
with (0,0,0)
在 front 切片的左上角。使用 numpy
索引,只需 select 您感兴趣的 3D 数组部分 就非常容易 而无需编写自己的循环 :
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> np.set_printoptions(precision=2)
# Generate a 3D 'cube' of data
>>> data3D = np.random.uniform(0,10, 2*3*5).reshape((2,3,5))
>>> data3D
array([[[ 7.44, 1.14, 2.5 , 3.3 , 6.05],
[ 1.53, 8.91, 1.63, 8.95, 2.46],
[ 3.57, 3.29, 6.43, 8.81, 6.43]],
[[ 4.67, 2.67, 5.29, 7.69, 7.59],
[ 0.26, 2.88, 7.58, 3.27, 4.55],
[ 5.84, 9.04, 7.16, 9.18, 5.68]]])
# Grab some "views" of the data
>>> front = data3D[:,:,0] # all rows and columns, first slice
>>> back = data3D[:,:,-1] # all rows and cols, last slice
>>> top = data3D[0,:,:] # first row, all cols, all slices
>>> bottom = data3D[-1,:,:] # last row, all cols, all slices
>>> r_side = data3D[:,-1,:] # all rows, last column, all slices
>>> l_side = data3D[:,0,:] # all rows, first column, all slices
看看前面的样子:
>>> plt.imshow(front, interpolation='none')
>>> plt.show()
前段时间我写了以下内容作为 3D 阵列的可视化辅助工具。也是一个很好的学习练习。
# Python 2.7.10
from __future__ import print_function
from numpy import *
def f_Print3dArray(a_Array):
v_Spacing = (len(str(amax(abs(a_Array)))) + 1) if amin(a_Array)\
< 0 else (len(str(amax(a_Array))) + 1)
for i in a_Array[:,:,::-1].transpose(0,2,1):
for index, j in enumerate(i):
print(" " * (len(i) - 1 - index) + "/ ", end="")
for k in j:
print(str(k).ljust( v_Spacing + 1), end="")
print("/")
print()
a_Array = arange(27).reshape(3, 3, 3)
print(a_Array)
print()
f_Print3dArray(a_Array)
转换为:
[[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]]
[[ 9 10 11]
[12 13 14]
[15 16 17]]
[[18 19 20]
[21 22 23]
[24 25 26]]]
为此:
/ 2 5 8 /
/ 1 4 7 /
/ 0 3 6 /
/ 11 14 17 /
/ 10 13 16 /
/ 9 12 15 /
/ 20 23 26 /
/ 19 22 25 /
/ 18 21 24 /
希望对大家有所帮助。