gpt4 book ai didi

python - 改变 numpy 数组的步幅(改变数据)

转载 作者:行者123 更新时间:2023-11-28 21:53:42 24 4
gpt4 key购买 nike

我有一个 numpy 数组,我想更改它的 strides,同时修改它的数据,以便新数组描述相同的数字逻辑对齐方式。有什么办法吗?

背景:我用 cv2.imdecode() 读取了一个图像文件,它生成了一个 BGR 图像,其最低阶步幅设置为 3(因此之间没有间隙不同像素的 channel )。我想用 cairo 包修改这个图像,它想要使用步幅 4(即,两个连续像素之间的一个字节的间隙)。哪种方法最好? (我也想尽可能优化,因为我必须多次这样做)。

最佳答案

假设输入数组是(n,m,3),那么它可以通过简单地连接一个扩展为(n,m,4) (n,m,1) 数组。

X = np.ones((n,m,3), dtype='byte')
F = np.zeros((n,m,1), dtype='byte')
X1 = np.concatenate([X,F], axis=2)

这些步幅为 (3*m,3,1)(m,1,1)(4*m,4,1 )

可以放入相同的数据

In [72]: dt0 = np.dtype([('R','u1'), ('G','u1'), ('B','u1')])
In [73]: X=np.ones((n,m),dtype=dt0)
In [74]: X.strides
Out[74]: (150, 3)
In [75]: X.shape
Out[75]: (30, 50)

目标 dt = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A ','u1')]) http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html

将 RGB 字段映射到 RGBA

但是为了与这些 dtype 进行连接,我们会进行某种转换为 (n,m,3) 形状。看起来重新分配 data 属性就可以了。

n, m = 2, 4
dt1 = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])
dt0 = np.dtype([('R','u1'), ('G','u1'), ('B','u1')])
X = np.arange(n*m*3,dtype='u1').reshape(n,m,3)
print repr(X)
X0 = np.zeros((n,m), dtype=dt0)
X0.data = X.data
print repr(X0)
X0.strides # (12, 3)

X1 = np.zeros((n,m), dtype=dt1)
F = np.zeros((n,m,1), dtype='u1')
X01 = np.concatenate([X, F], axis=2)
X1.data = X01.data
print repr(X1)
X1.strides # (12, 4)

制作:

array([[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)],
[(12, 13, 14), (15, 16, 17), (18, 19, 20), (21, 22, 23)]],
dtype=[('R', 'u1'), ('G', 'u1'), ('B', 'u1')])
array([[(0, 1, 2, 0), (3, 4, 5, 0), (6, 7, 8, 0), (9, 10, 11, 0)],
[(12, 13, 14, 0), (15, 16, 17, 0), (18, 19, 20, 0), (21, 22, 23, 0)]],
dtype=[('R', 'u1'), ('G', 'u1'), ('B', 'u1'), ('A', 'u1')])

使用重叠数据类型

这是一种使用重叠数据类型而不是串联的方法:

dt0 = np.dtype([('R','u1'), ('G','u1'), ('B','u1')])
dt1 = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])
dtb = np.dtype({'names':['rgb','rgba'],
'offsets':[0,0],
'formats':[dt0, dt1]})
X0 = np.zeros((n,m), dtype=dt0)
X0.data = X.data
X1 = np.zeros((n,m), dtype=dtb)
X1['rgb'][:] = X0
print repr(X1['rgba'])

或者没有单独的命名字节字段,它甚至更简单:

dt0 = np.dtype(('u1',(3,)))
dt1 = np.dtype(('u1',(4,)))
dtb = np.dtype({'names':['rgb','rgba'],
'offsets':[0,0],
'formats':[dt0, dt1]})
X = np.arange(n*m*3,dtype='u1').reshape(n,m,3)
X1 = np.zeros((n,m), dtype=dtb)
X1['rgb'][:] = X

X1['rgba'](n,m,4),步幅为 (m*4, 4, 1) .

X1['rgb'](n,m,3),但步幅相同 (m*4, 4, 1).

使用as_strided

形状不同,但步幅相似,建议使用 as_strided。创建空目标数组,并使用 as_strided 选择元素子集以从 X 接收值:

X1 = np.zeros((n,m,4),dtype='u1')
np.lib.stride_tricks.as_strided(X1, shape=X.shape, strides=X1.strides)[:] = X
print X1

关于python - 改变 numpy 数组的步幅(改变数据),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25704797/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com