[英]Is there possibilty in numpy to swap x,y of matrix without changing memory order and iterators?
I'm trying to switch to numpy from the world of fortran and c++ .我正在尝试从fortran和c++ 的世界切换到 numpy 。 Mainly I'm working with huge images, where coordinates directions are x: left to right, y: top down, and pixels are stored in rows, common for image format.
主要是我正在处理巨大的图像,其中坐标方向是x:从左到右,y:自上而下,像素存储在行中,常见于图像格式。
Numpy says that also stores matrices by rows. Numpy 说它还按行存储矩阵。 As far as good, it is the same as fortran/c++ saves images.
就好的而言,它与 fortran/c++ 保存图像相同。 But, see following example, grays from black to white in rows.
但是,请参阅以下示例,从黑色到白色的灰色行。 Lets create image 3x3 where first row is 123 etc
让我们创建图像 3x3,其中第一行是 123 等
Black to White image as expected, with matplotlib imshow(mat)黑白图像符合预期,带有 matplotlib imshow(mat)
mat = np.array([1,2,3,4,5,6,7,8,9], 'i1').reshape(3,3)
next I've used following code to get info about matrix.接下来我使用以下代码获取有关矩阵的信息。 Routine prints: value at position
x=1, y=0
, position in memory to see if array is copied, strides and iterators.例行打印: position
x=1, y=0
, position 中的值在 memory 中查看是否复制了数组、步幅和迭代器。
def pr(a):
x=1; y=0;
print(a[x,y])
print(a.ctypes.data, a.strides, a.ravel(order='K'), [x for x in a.flat], a.flatten(order='K'))
print(a.flags)
for matrix mat
in C-order I've got对于C 顺序的矩阵
mat
,我有
4
94598176807408 (3, 1) [1 2 3 4 5 6 7 8 9] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1 2 3 4 5 6 7 8 9]
C_CONTIGUOUS : True
F_CONTIGUOUS : False
So it is clear that x,y
are swapped, because for x=1
and y=0
pixel value is 2 and not 4, so I've changed to F order.所以很明显
x,y
被交换了,因为对于x=1
和y=0
像素值是 2 而不是 4,所以我已更改为 F 顺序。
# mat = mat.ravel(order='K').reshape(3,3, order='F')
mat.strides = (1,3)
# mat = np.swapaxes(mat, 0, 1)
Above are three possibilities to get F order with same results.以上是获得具有相同结果的F 阶的三种可能性。
2
94598176807408 (1, 3) [1 2 3 4 5 6 7 8 9] [1, 4, 7, 2, 5, 8, 3, 6, 9] [1 2 3 4 5 6 7 8 9]
C_CONTIGUOUS : False
F_CONTIGUOUS : True
Now image is swapped when using F order with same memory layout as before现在,当使用具有相同 memory 布局的 F 订单时,图像被交换
As you can see value 2 for x=1 y=2
is correct, using mat[x,y]
is correct, memory order is correct, but iterator is wrong 1 4 7...
.如您所见,
x=1 y=2
的值 2 是正确的,使用mat[x,y]
是正确的,memory 顺序是正确的,但迭代器是错误的1 4 7...
。 Consequences are that saving or showing image are bad, all are swapped.结果是保存或显示图像不好,全部被交换。 Iterator not in memory order has big performance penalties.
不在 memory 订单中的迭代器有很大的性能损失。
Question is: How to set numpy matrix with swapped x,y without copy of image and all other properties are as in C-order.问题是:如何在没有图像副本的情况下设置 numpy 矩阵,交换 x,y 并且所有其他属性都与 C 顺序相同。 I've tried to set C_CONTIGUOUS=True, but it is not possible.?
我尝试设置 C_CONTIGUOUS=True,但这是不可能的。?
One way is to use C-order but on all such matrices one must use reversed indexes [y,x], problem is that it is very confusing, all vectors are normal (x,y,z)
and some objects use swap index order.?一种方法是使用 C 顺序,但在所有此类矩阵上都必须使用反向索引 [y,x],问题是它非常混乱,所有向量都是正常的
(x,y,z)
并且一些对象使用交换索引顺序.? Correct naming order of axes helps in further spatial operation of images.轴的正确命名顺序有助于图像的进一步空间操作。
Maybe there is possibility to extend numpy , with other index method like mat.swap2[x,y]
that only returns mat[y,x]
or eg.也许有可能扩展numpy ,使用其他索引方法,如
mat.swap2[x,y]
只返回mat[y,x]
或例如。 mat[*reversed((x,y))]
. mat[*reversed((x,y))]
。 But is there better solution?但是有更好的解决方案吗?
Next are two examples in fortran and c++ with eg.接下来是fortran和c++中的两个示例,例如。 armadillo matrix library (as c/c++ doesn't seem to define own generic matrix object).
犰狳矩阵库(因为 c/c++ 似乎没有定义自己的通用矩阵对象)。 Both examples uses F order, indexing is correct
mat[x,y]
, memory layout is same as binary layout of input images, row by row, iterator are in memory layout.两个示例都使用 F 顺序,索引正确
mat[x,y]
,memory 布局与输入图像的二进制布局相同,逐行,迭代器在 memory 布局中。 It seems strange to me that numpy in F order does not support same behavior.在我看来,F 顺序中的 numpy 不支持相同的行为似乎很奇怪。 Or simply I don't understand the philosophy of numpy.
或者只是我不明白 numpy 的哲学。
Example in fortran , saving and iterating such matrix is in memory order (not shown here). fortran中的示例,保存和迭代此类矩阵按 memory 顺序(此处未显示)。
...
integer(1) :: mat(0:2,0:2) ! matrix 3x3 indexing 0,1,2
data mat /1,2,3,4,5,6,7,8,9/ ! memory order
print*, mat(1,0) ! value for x=1 y=0 is 2 ok
...
Example in C++ with armadillo, saving and iterating again is in memory order (not shown here). C++中的示例与犰狳,保存并再次迭代是按 memory 顺序(此处未显示)。
#define ARMA_U8_TYPE uint8_t
#define ARMA_S8_TYPE int8_t // define support for int8 instead of char
#include <armadillo>
...
using namespace arma;
int8_t amem[] = {1,2,3,4,5,6,7,8,9}; // memory order
Mat<int8_t> mat(amem, 3,3, false,true); // matrix 3x3
cout << (int)mat(1,0) << "\n"; // value for x=1 y=0 is 2 ok
...
First numpy has confusing terms for column major mode, F_CONTIGUOUS
is never contiguous in memory for 2D and more.首先 numpy 对列主模式有混淆的术语,
F_CONTIGUOUS
在 memory 中对于 2D 等从不连续。 It is just like view by design and memory layout is always C
.就像按设计查看一样, memory 布局始终为
C
。 For performance reasons and axis assignment as you specified it is more natural to use column major order as many do, but not easy in numpy.出于性能原因和您指定的轴分配,使用列主顺序更自然,但在 numpy 中并不容易。
Furthermore built-in/extension doesn't allow to use just setattr()
to extend directly numpy classes, but you can derive own.此外,内置/扩展不允许仅使用
setattr()
直接扩展 numpy 类,但您可以派生自己的。
To be simple in numpy always use default C
order (row major order) and swap axes as mat[z,y,x]
.为了简单起见, numpy 始终使用默认的
C
顺序(行主要顺序)并将轴交换为mat[z,y,x]
。 It seems to me to be the least confusing.在我看来,这似乎是最不容易混淆的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.