简体   繁体   English

交换numpy数组的子数组

[英]Swap subarrays of a numpy array

First a bit of context. 首先是一些背景。

I am trying to draw into a Gdk (actually pygtk) pixbuf with Cairo (actually pycairo). 我试图用开罗(实际上是pycairo)绘制一个Gdk(实际上是pygtk)pixbuf。 My original code looked like this: 我原来的代码看起来像这样:

import cairo as C
import gtk.gdk as GG

FMT = C.FORMAT_ARGB32
CSP = GG.COLORSPACE_RGB

st = C.ImageSurface.format_stride_for_width(FMT, zw)
surf = C.ImageSurface(FMT, zw, zh)
c = C.Context(surf)

# draw into c here ...

pixels = surf.get_data()
return GG.pixbuf_new_from_data(pixels, CSP, True, 8, zw, zh, st)

For a time, it looked like this would just work, until I tried to draw colors instead of just black text. 有一段时间,看起来这只会起作用,直到我试图绘制颜色而不仅仅是黑色文本。 It turns out the two libraries disagree on byte order, like so: 事实证明两个库在字节顺序上不一致,如下所示:

# !!! FIXME !!! cairo ARGB surfaces and gdk pixbufs disagree on bytesex:
# cairo: LSB --> B G R A <-- MSB
# gdk:   LSB --> R G B A <-- MSB
# !!! WTF !!!

The result is (after blitting from the pixbuf to screen) an image with red and blue channels swapped :-( 结果是(在从pixbuf到屏幕的blitting之后)交换了红色和蓝色通道的图像:-(

So, if I keep using pixbufs (as I want to) I need to postprocess the data, swapping every 1st byte with every 3rd. 所以,如果我继续使用pixbufs(我想要的话),我需要对数据进行后处理,每隔3个交换每个第1个字节。 I can do that in plain python: 我可以在普通的python中做到这一点:

def changesex(data):
    i0 = 0
    i2 = 2
    l = len(data)
    while i2 < l:
        temp = data[i0]
        data[i0] = data[i2]
        data[i2] = temp
        i0 += 4
        i2 += 4

but I thought using numpy might be faster if there is a built-in operator for this written in C. Something like this: 但我认为使用numpy可能会更快,如果有一个用C语言编写的内置运算符。这样的事情:

a = np.frombuffer(data, dtype=np.uint8)
a.shape = (len(data) / 4, 4)
temp = a[:,0]
a[:,0] = a[:,2]
a[:,2] = temp

Am I just dreaming? 我只是在做梦吗?

Noting a your initial (N,4) array of B,G,R,A , you could get a (N,4) representation as R,G,B,A rather simply using some advanced indexing: 注意到a初始(N,4)的阵列B,G,R,A ,可以得到一个(N,4)表示为R,G,B,A ,而简单地使用一些高级索引:

a = np.frombuffer(data, dtype=np.uint8)
a.shape = (-1, 4)
rearranged = a[:,[2,1,0,3]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM