4

O(1) で 2 つの配列を新しい配列に結合したいと考えています。次に、この新しい配列の値を変更して、古い配列の値を変更したいと考えています。

これは、RGBA (n*m*4) 配列を返す関数を持たない PyGame の surfarray モジュールのコンテキストにあります。RGB (n*m*3) 配列と A (n*m) 配列のみを個別に返します。理想的には、「RGB」配列と「A」配列を参照する新しい配列「RGBA」を O(1) に作成します。「RGBA」を変更すると、「RGB」と「A」の両方が変更されるため、サーフェスが変更されます。

Cでそれを行う方法が思いつかないので、これが可能かどうかはわかりません。ただし、いくつかのアイデアは思いつきます。たとえば、いくつかのサブ配列をカプセル化し、C レベルでインデックス付けを正しいものに内部的にリダイレクトする numpy 配列タイプが存在する可能性があります。これでいいでしょう。

4

2 に答える 2

1

以下の例に示すように、参照手順を管理する独自のクラスを作成できます。__getslice____add__、などのスライス機能を含めるには、これにさらに取り組む必要があり__mul__ます。

import numpy as np
a1 = np.arange(1,11)
a2 = np.arange(101,111)
class Combiner():
    def __init__(self, *args):
        self.arrays = [arg for arg in args]
        self.lens = [len(arg) for arg in args]
    def __getitem__(self,i):
        if i >=0:
            shift = 0
            acc = 0
            for j,l in enumerate(self.lens):
                acc += l
                if i<acc:
                    return self.arrays[j][i-shift]
                shift += l
        if i<0:
            shift = 0
            acc = 0
            for j in xrange(len(self.lens)-1,-1,-1):
                l = self.lens[j]
                acc -= l
                if i>=acc:
                    return self.arrays[j][i+shift]
                shift += l

    def __setitem__(self,i,v):
        if i >=0:
            shift = 0
            acc = 0.
            for j,l in enumerate(self.lens):
                acc += l
                if i<acc:
                    self.arrays[j][i-shift] = v
                    return
                shift += l
        if i<0:
            shift = 0
            acc = 0
            for j in xrange(len(self.lens)-1,-1,-1):
                l = self.lens[j]
                acc -= l
                if i>=acc:
                    self.arrays[j][i+shift] = v
                    return
                shift += l

a3 = Combiner(a1,a2)
print a3[-10]
# 101
a3[-2] = 22222
a3[ 4] = 11111
print a1
#[    1     2     3     4 11111     6     7     8     9    10]
print a2
#[  101   102   103   104   105   106   107   108 22222   110]
于 2013-05-09T15:22:41.840 に答える
0

質問を完全に理解したかどうかはわかりません。私の知る限り、次のようにpygameとサーフェスを初期化すると、pygameサーフェスはRGBA(正確にはBGRA)連続配列になります(各行の「32」に注意してください):

# display surface
DISP = pygame.display.set_mode((window_w, window_h), 0, 32)
# some surface
window = pygame.Surface((w, h), 0, 32) 

また、24ビットサーフェスは配列と相互運用するのが難しいため、可能な場合は24ビットではなく32ビットを使用することをお勧めします(numpy画像データの保存と操作に使用します)。
たとえば、私が間違っていなければ、24 ビットのサーフェスには 4 で割り切れるピクセルの量が必要です。

前述のように、あなたの最終的なタスクが何であるかはわかりませんが、これが私のやり方です。
たとえば、lib でイメージをロードし、openCVBGRA 配列に変換します。

# BGR 3d numpy array array (shape = h, w, 3) with image data
img = cv2.imread(filename)
# BGRA 3d numpy array (shape = h, w, 4) 
img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)

次に、この関数は配列データ全体をサーフェスにコピーします。ただし、それらが同じピクセル サイズであることを確認する必要があります。

# copy array data into a pygame surface
def copy_arr(surface, myarray):
    bv = surface.get_buffer()
    bv.write(myarray.tostring(), 0)

しかし、それはあなたが何か他のことをしたかったのかもしれません。

于 2016-04-10T21:42:05.027 に答える