【问题标题】:Efficiently re-shaping a numpy ndarray from 2-D to 3-D based on elements from 2-D基于 2-D 的元素有效地将 numpy ndarray 从 2-D 重塑为 3-D
【发布时间】:2011-06-24 20:49:30
【问题描述】:

我正在处理包含图像数据的DICOM 文件。我正在使用pydicom 从 .DCM 文件中读取元数据。现在,从 .DCM 文件中提取的像素数据以二维 numpy ndarray 的形式返回。
我正在使用的特定 DICOM 文件为每个像素保存一个强度值。在我对它们执行一些操作之后,我最终在二维 ndarray 中的每个像素上得到一个浮点值(介于 0.0 和 1.0 之间):

[

[ 0.98788927, 0.98788927 0.98788927, ..., 0.88062284 0.89532872 0.87629758],
[ 0.98788927, 0.98788927, 0.98788927, ..., 0.8884083, 0.89446367, 0.87889273],
[ 0.98788927, 0.98788927, 0.98788927, ..., 0.89100346, 0.89532872, 0.87629758],
,...,
[ 0.97491349, 0.97491349, 0.97491349, ..., 0.74480969, 0.72318339, 0.73269896],
[ 0.97491349, 0.97491349, 0.97491349, ..., 0.74913495, 0.74480969, 0.74740484],
[ 0.97491349, 0.97491349, 0.97491349, ..., 0.74913495 0.75865052, 0.75086505],

]

我想通过将每个元素替换为元素序列 [R, G, B] 其中 R=G=B=intensity 值,将其转换为带有 numpy 的 3-D ndarray。

ndarray.put() 函数使排除该方法的矩阵变平。

我也试过了:

for x in range( len(a[0]) ):
  for y in range( len(a) ):
    a[x][y] = [ a[x][y], a[x][y], a[x][y] ]

但得到一个

ValueError: setting an array element with a sequence.   

建议?由于其中一些图像很大,因此我试图尽可能轻松地进行数据操作,因此我想避免黑客/手动将所有数据复制到单独的变量中。

提前感谢您的帮助。

【问题讨论】:

  • 我想我错过了一些东西。为什么numpy.array([a,a,a]) 不起作用?
  • numpy.array([a,a,a]) 应该快得多,因为您没有明确地迭代您的数组。

标签: python numpy matrix pydicom


【解决方案1】:

所以你想要的当然是一个形状为 m x n x r 的数组,其中 r 是元组的大小。

在我看来最直接的一种方法是:(i) 显式创建一个 3D 网格数组,与原始 2D 数组相同,除了添加最后一个维度 r,已添加,然后; (ii) 将您的 rgb 元组映射到此 Grid 上。

>>> # first, generate some fake data:
>>> m, n = 5, 4            # rows & cols, represents dimensions of original image
>>> D = NP.random.randint(0, 10, m*n).reshape(m, n)
>>> D
    array([[8, 2, 2, 1],
           [7, 5, 0, 9],
           [2, 2, 9, 3],
           [5, 7, 3, 0],
           [5, 8, 1, 7]])

现在创建 Grid 数组:

>>> G = NP.zeros((m, n, r), dtype='uint')

将 G 视为一个 m x n 矩形网格——与 D 相同——但 20 个单元格中的每一个都存储的不是整数(如 D)而是一个 rgb 元组,所以:

>>> # placing the color pixel (209, 127, 87) at location 3,2:
>>> G[3,2] = (209, 124, 87)

要了解这种结构,您可以通过查看 G 的三个连续切片来查看网格 G 中的 rgb 元组:

>>> G[:,:,0]      # red
>>> array([[  0,   0,   0,   0,   0],
           [  0,   0,   0,   0,   0],
           [  0,   0,   0,   0,   0],
           [  0,   0, 209,   0,   0],
           [  0,   0,   0,   0,   0]], dtype=uint8)

>>> G[:,:,1]    # green
>>> array([[  0,   0,   0,   0,   0],
           [  0,   0,   0,   0,   0],
           [  0,   0,   0,   0,   0],
           [  0,   0, 124,   0,   0],
           [  0,   0,   0,   0,   0]], dtype=uint8)

>>> G[:,:,2]   # blue
>>> array([[ 0,  0,  0,  0,  0],
           [ 0,  0,  0,  0,  0],
           [ 0,  0,  0,  0,  0],
           [ 0,  0, 87,  0,  0],
           [ 0,  0,  0,  0,  0]], dtype=uint8)

现在要真正得到您想要的结果,我们只需要 (i) 创建一个网格 G,一个 3D NumPy 数组,其前两个维度取自您的 .DCM 文件中存储的数组,其第三个维度是三个,来自一个rgb元组的长度;然后 (ii) 将 rgb 元组映射到该网格 G。

>>> # create the Grid
>>> G = NP.zeros((m, n, r), dtype='uint')
>>> # now from the container that holds your rgb tuples, create *three* m x n arrays, 
>>> # one for each item in your rgb tuples

>>> # now just map the r values (1st itm in each rgb tuple) to the 3D grid
>>> G[:,:,0] = r_vals
>>> G[:,:,1] = g_vals
>>> G[:,:,2] = b_vals

>>> G.shape
    (5, 4, 3)

【讨论】:

  • 这个方法效果很好,我成功的得到了我想要的。但是,在此特定实例中,所有 R G 和 B 值都将相同,因此我只需设置 G[:,:,0] = 2-D Array G[:,:,1] = 2-D Array G[:,: ,2] = 2-D 数组,我得到了我想要的结果。附言np.zeroes 函数非常有用,我不知道我是如何在文档中错过的
猜你喜欢
  • 1970-01-01
  • 2018-07-18
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
相关资源
最近更新 更多