2014-04-10 142 views
10

在Python和Numpy中尝试创建3维数组。我的问题是,与Matlab相比,尺寸的顺序是关闭的。事实上,这个命令根本没有意义。numpy中的三维数组

创建矩阵:

x = np.zeros((2,3,4)) 

在我的世界这将导致2行,第3列和第4种深度尺寸并且应当表示为:

[0 0 0  [0 0 0  [0 0 0  [0 0 0 
0 0 0]  0 0 0]  0 0 0]  0 0 0] 

分隔条件上的每个深度尺寸。 相反,它是作为

[0 0 0 0  [0 0 0 0 
0 0 0 0  0 0 0 0 
0 0 0 0]  0 0 0 0] 

即,3行,4列和2种的深度尺寸。也就是说,第一个维度是“深度”。为了进一步增加这个问题,使用OpenCV导入图像的颜色维度是最后一个维度,也就是说,我将颜色信息看作深度维度。如果我只想在已知的较小三维阵列上尝试一些东西,这会使事情变得非常复杂。

我误解了一些东西吗?如果没有,为什么hecky使用这种不直观的方式处理3D维数组是非常困难的?

回答

7

你是对的,你正在创建一个2行,3列和4深度的矩阵。 NumPy的打印矩阵Matlab的不同:

numpy的:

>>> import numpy as np 
>>> np.zeros((2,3,2)) 
array([[[ 0., 0.], 
    [ 0., 0.], 
    [ 0., 0.]], 

    [[ 0., 0.], 
    [ 0., 0.], 
    [ 0., 0.]]]) 

Matlab的

>> zeros(2, 3, 2) 
ans(:,:,1) = 
    0  0  0 
    0  0  0 
ans(:,:,2) = 
    0  0  0 
    0  0  0 

但是你计算相同的矩阵。看看Numpy for Matlab users,它会引导你将Matlab代码转换成Numpy。


例如,如果你正在使用OpenCV的,你可以使用numpy的考虑到OpenCV的使用BGR表示构建一个图像:

import cv2 
import numpy as np 

a = np.zeros((100, 100,3)) 
a[:,:,0] = 255 

b = np.zeros((100, 100,3)) 
b[:,:,1] = 255 

c = np.zeros((100, 200,3)) 
c[:,:,2] = 255 

img = np.vstack((c, np.hstack((a, b)))) 

cv2.imshow('image', img) 
cv2.waitKey(0) 

enter image description here

如果你看一看,以矩阵c你会看到它是一个100x200x3的矩阵,它正是它在图像中显示的(红色,因为我们已经将R坐标设置为255,其他两个保持为0)。

+0

好的,所以如果一切正常计算,我可以指望一个算法对于较小的矩阵以及大图像都一样吗?将第三维视为“深度”。这是有道理的,因为数学处理所有维度都是一样的。但是有什么办法可以让Numpy呈现正确吗?恐怕链接在这方面没有多大帮助:( – Vejto

+0

Matlab和Numpy不以同样的方式处理图像,如果您使用的是OpenCV,那么它将图像表示为BGR而不是RGB,然后Matlab读取矩阵使用fortran所以你必须考虑所有这些事情时,将代码从matlab移植到numpy – jabaldonedo

+0

好了,我尝试了一些东西,当然,正如你所说的。我知道BGR的演示文稿(它让我感到困惑,但我只是希望有一种方法可以“正确地”呈现它,现在,我将分别查看每个暗点,因为(对于3D矩阵e)显示e [:,:,1]正确的时候e [:,:, - 1]显示不合逻辑谢谢! – Vejto

11

您已截断数组表示形式。让我们来看看完整的例子:

>>> a = np.zeros((2, 3, 4)) 
>>> a 
array([[[ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.]], 

     [[ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.]]]) 

阵列的NumPy的印刷作为单词array其次是结构,类似于嵌入式Python列表。让我们创建类似的列表:

>>> l = [[[ 0., 0., 0., 0.], 
      [ 0., 0., 0., 0.], 
      [ 0., 0., 0., 0.]], 

      [[ 0., 0., 0., 0.], 
      [ 0., 0., 0., 0.], 
      [ 0., 0., 0., 0.]]] 

>>> l 
[[[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]], 
[[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]]] 

这种化合物清单l的第一级正好有2个元素,就像阵列a(行#)的第一个维度。这些元素中的每一个本身都有3个元素的列表,这等于a(列数)的第二维。最后,大多数嵌套列表每个都有4个元素,与第三维a(深度/颜色数)相同。

所以,你已经有了完全相同的结构(在尺寸方面)与Matlab中一样,只是以其他方式打印。

一些注意事项。

  1. Matlab的存储数据逐列( “Fortran的顺序”),而NumPy的默认存储它们逐行( “C命令”)。这不会影响索引,但可能会影响性能。例如,在Matlab中,高效循环将在列上(例如for n = 1:10 a(:, n) end),而在NumPy中,优选遍历行(例如for n in range(10): a[n, :] - 注意n在第一位,而不是在最后)。

  2. 如果用彩色图像OpenCV的工作,请记住它:

    2.1。像大多数Python库一样,以BGR格式存储图像而不是RGB。

    2.2。大多数函数在图像坐标(x, y)上工作,这与矩阵坐标(i, j)相反。

+0

是的,我从jabaldonedo和一些测试中了解得很多,即使后端逻辑更容易理解,它的显示方式也不合逻辑。订单存储,很棒的提示! – Vejto

+2

不是实际上不合逻辑,它只是不同而已。在2D屏幕上没有真正的表示3D阵列的方法,因此不同的环境使用不同的方法。而且,Matlab和NumPy都具有打印数组的功能。 – ffriend

+0

阅读这个答案后,我认为在“行,列,堆栈”序列中的numpy数组是不合适的。最好想一想,“第一个容器容纳第二个容器,容纳第二个容器”。 –