Python Numpy:跨越多通道图像
我在numpy大步走的时候有点头晕。我正在写一些多通道图像插值的代码。我将图像定义为具有形状Python Numpy:跨越多通道图像,python,matlab,numpy,cython,Python,Matlab,Numpy,Cython,我在numpy大步走的时候有点头晕。我正在写一些多通道图像插值的代码。我将图像定义为具有形状[高度x宽度x通道]的np.ndarray类型的三维数组。我编写的C++必须在Matlab和Python中工作。对于单通道图像,我的代码运行良好,对于Matlab中的多通道图像,我的代码运行良好 为了插值图像,我正在编写一种方法,根据该方法,给定[M x N x p]数组,您可以提供一组x和Y亚像素坐标,以便在图像内插值。这与scipy的ndimage.map\u坐标的功能相同。不幸的是,我需要一种在Ma
[高度x宽度x通道]
的np.ndarray
类型的三维数组。我编写的C++必须在Matlab和Python中工作。对于单通道图像,我的代码运行良好,对于Matlab中的多通道图像,我的代码运行良好
为了插值图像,我正在编写一种方法,根据该方法,给定[M x N x p]
数组,您可以提供一组x
和Y
亚像素坐标,以便在图像内插值。这与scipy的ndimage.map\u坐标的功能相同。不幸的是,我需要一种在Matlab和Python中都能产生相同结果的插值方法,因此我正在编写自己的插值代码
我的问题是Matlab通过一个接一个地堆叠级联通道来安排它的三维内存。这意味着,对于[10,10,2]
图像,第一个100
元素将是第一个通道,元素[100200]
元素将是第二个通道。因此,要在Matlab连续内存中建立索引,我的索引如下:
// i is the element of the indices array
// j is the current channel
// F is the image we are indexing
// F_MAX is M * N (the number of pixels per channel)
// N_ELEMS is the total number of elements in the indices array
// f_index is the index in the contiguous array equivalent to the x and y coordinate in the 2D image
for (size_t j = 0; j < N_CHANNELS; j++)
{
out[i + j * N_ELEMS] = F[f_index + j * F_MAX];
}
到我可以索引到的东西,就像我对Matlab数组所做的那样?
我应该提到的是,我知道Matlab和numpy之间的列主/行主差异。如上所述,我的方法适用于单通道图像,但索引错误的通道超过1个。也许您可以使用函数
np.swapaxes
,如以下ipython示例所示:
In [1]: a = np.arange(2*2*2).reshape((2,2,2))
In [2]: a
Out[2]:
array([[[0, 1],
[2, 3]],
[[4, 5],
[6, 7]]])
In [3]: a.flatten()
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7])
In [4]: np.swapaxes(a,2,1).flatten()
Out[4]: array([0, 2, 1, 3, 4, 6, 5, 7])
编辑:
我认为只有在使用交换轴复制阵列后,内存布局才会发生变化,请参见:
In [6]: b = a.swapaxes(1,2)
In [7]: b.strides
Out[7]: (16, 4, 8)
In [8]: b = a.swapaxes(1,2).copy()
In [9]: b.strides
Out[9]: (16, 8, 4)
创建数组时,可以指定Fortran顺序:
>>> a = np.ones((10,10,2),dtype=np.float64)
>>> a.strides
(160, 16, 8)
>>> b = np.ones((10,10,2),dtype=np.float64,order='f')
>>> b.strides
(8, 80, 800)
如果已创建数组,则可以使用
np.asfortranarray
。这确实会复制数据,但捕捉效果很好,当然,更改轴确实会像您演示的那样起作用。不幸的是,我仍然不能完全纠正我的问题,因此求助于宏来改变每个平台上的索引模式。
>>> a = np.ones((10,10,2),dtype=np.float64)
>>> a.strides
(160, 16, 8)
>>> b = np.ones((10,10,2),dtype=np.float64,order='f')
>>> b.strides
(8, 80, 800)