2013-02-13 7 views
5

Ich versuche Build OpenGL Texturen in Python mit numpy verwenden, aber ich habe Probleme, weil ich nicht vorhersagen kann, wie numpy Arrays im Speicher organisiert werden. Das Beispielprogramm unten (die ausgeführt werden sollen, wie sie ist) veranschaulicht meine Verwirrung:Verstehen, wie numpy Arrays im Speicher ausgelegt sind

from pylab import * 

array_by_hand = array(
    [[[1, 2, 3, 4], [1, 2, 3, 4]], 
    [[1, 2, 3, 4], [1, 2, 3, 4]]], dtype='uint8') 

layers = 1 * ones((2, 2)), 2 * ones((2, 2)), 3 * ones((2, 2)), 4 * ones((2, 2)) 
array_from_layers = dstack(layers) 
array_from_layers = array_from_layers.astype('uint8') 

print array_by_hand; print 
print array_from_layers; print 

print ' '.join(x.encode('hex') for x in array_by_hand.data) 
print ' '.join(x.encode('hex') for x in array_from_layers.data) 
print 
print all(array_by_hand == array_from_layers)     # True 
print str(array_by_hand.data) == str(array_from_layers.data) # False 

Obwohl die beiden Arrays äquivalent sind, so weit wie Python betroffen ist, sind die unterschiedlich im Speicher angelegt und daher unterschiedlich von OpenGL angezeigt. Kann jemand erklären, warum das passiert und wie ich beide Arrays zum selben Format zwingen könnte?

Antwort

4

Wenn Sie die ToString-Methode stattdessen aufrufen, wandelt es sich um das Array zu C-zusammenhängenden Layout:

>>> array_by_hand.tostring() == array_from_layers.tostring() 
True 

Der Grund für die Zeichenfolge in Ihrem Fall anders ist, ist wegen der dstack Anruf. Es versucht, schlau zu sein, Arrays zusammen zu stapeln, indem einfach die zugrunde liegenden Daten der Quell-Arrays kombiniert werden und dann numpy's stride information geändert wird. Dies führt dazu, dass das Array nicht im C-zusammenhängenden Layout ist.

+0

Es war eine Überraschung für mich, dass beim Kopieren der Daten im Schritt '.astype ('uint8') die Kopie nicht in C-zusammenhängende Form umgeordnet wurde. – Jaime

+0

Ja, ich denke, .astype behält das zugrunde liegende Format gleich. – jterrace

+1

Sie könnten auch 'np.ascontiguousarray' verwenden, um das gewünschte Speicherlayout zu gewährleisten ... auch' .flatten() 'wird Ihr Array immer kopieren, auch wenn es nicht notwendig ist. Und '' .tostring() 'garantiert bereits' C' zusammenhängende Ausgabe. – seberg