简体   繁体   English

Numpy最快的3D到2D投影

[英]Numpy fastest 3D to 2D projection

I have a 3D array of binary data. 我有一个二进制数据的3D数组。 I want to project this to 3 2D images - side on, head on, birds eye. 我想把它投射到3个2D图像 - 侧面,正面,鸟眼。

I have written the code: 我写了代码:

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

But this is horrifically slow (75s!) for a ~700x300x300 matrix. 但对于~700x300x300矩阵来说,这是非常缓慢的(75秒!)。

What is the fastest way of achieving this task? 实现此任务的最快方法是什么?

EDIT: 编辑:

To save the image, I have used: 为了保存图像,我使用了:

sideImage = Image.fromarray(side)
sideImage.convert('RGB').save("sideImage.png")

When I have 3D data, I tend to think of it as a 'cube' with rows, columns, and slices - or panels, of 2D images. 当我拥有3D数据时,我倾向于将其视为具有2D图像的行,列和切片(或面板)的“立方体”。 Each slice or panel is a 2D image that is of dimensions (rows, cols) . 每个切片或面板是2D图像是尺寸的(rows, cols) I usually think of it like this: 我通常会这样想:

3D数据立方体

with (0,0,0) being in the upper left corner of the front slice. (0,0,0)在所述片的左上角之中。 With numpy indexing it is super easy to select just the portions of the 3D array that you are interested in without writing your own loops : 随着numpy索引是超级容易选择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

See what the front looks like: 看看前面的样子:

>>> plt.imshow(front, interpolation='none')
>>> plt.show()

前面的数据立方体

You can compute it as follows: 您可以按如下方式计算它:

>>> 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)
>>>

You can scale values if you need 您可以根据需要缩放值

>>> 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]])
>>>

Some time back I wrote the below as a visualization aid for 3D arrays. 一段时间后,我将下面的内容写成3D阵列的可视化辅助工具。 Was also a good learning exercise. 也是一个很好的学习练习。

# 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)

Converts this: 转换这个:

[[[ 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]]]

To this: 对此:

  / 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  /

Hope it helps someone. 希望它可以帮助某人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM