2014-11-26 22 views
6

Prima di tutto, sono totalmente nuovo per Kivy, quindi sto faticando un po '.Visualizza un array numpy in Kivy

Sto provando a visualizzare una matrice numpy in una finestra kivy. Finora ho capito che questo dovrebbe funzionare usando la classe Texture (http://kivy.org/docs/api-kivy.graphics.texture.html).

Come il mio array numpy cambia di volta in volta, sto cercando di adattare il seguente codice alla mia applicazione.

# create a 64x64 texture, defaults to rgb/ubyte 
texture = Texture.create(size=(64, 64)) 

# create 64x64 rgb tab, and fill with values from 0 to 255 
# we'll have a gradient from black to white 
size = 64 * 64 * 3 
buf = [int(x * 255/size) for x in range(size)] 

# then, convert the array to a ubyte string 
buf = b''.join(map(chr, buf)) 

# then blit the buffer 
texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte') 

# that's all ! you can use it in your graphics now :) 
# if self is a widget, you can do this 
with self.canvas: 
    Rectangle(texture=texture, pos=self.pos, size=(64, 64)) 

Sembra che creare la consistenza e la modifica funziona come dovrebbe, ma io non arrivare, come visualizzare la texture.

Qualcuno può spiegare a me, come utilizzare il

with self.canvas: 
    Rectangle(texture=texture, pos=self.pos, size=(64, 64)) 

in un modo, che riesco a vedere la mia foto/array NumPy.

Grazie mille in anticipo! Holzroller

Modifica: Ho capito che usare Kivy 1.8.0 e la classe Texture è un po 'caotico. Così ho fatto l'upgrade a Kivy 1.9.0 tramite github (l'installazione di Kivy tramite apt-get in Ubuntu 14.04 LTS ti offre la versione 1.8.0) e riesco a vedere la Texture usando il seguente codice. Spero che aiuti le persone che hanno lo stesso problema di me.

from kivy.graphics.texture import Texture 
from kivy.graphics import Rectangle 
from kivy.uix.widget import Widget 
from kivy.base import runTouchApp 
from array import array 
from kivy.core.window import Window 


# create a 64x64 texture, defaults to rgb/ubyte 
texture = Texture.create(size=(1280, 1024), colorfmt='rgb') 

# create 64x64 rgb tab, and fill with values from 0 to 255 
# we'll have a gradient from black to white 
size = 1280 * 1024 * 3 
buf = [int(x * 255/size) for x in range(size)] 

# then, convert the array to a ubyte string 
arr = array('B', buf) 
# buf = b''.join(map(chr, buf)) 

# then blit the buffer 
texture.blit_buffer(arr, colorfmt='rgb', bufferfmt='ubyte') 

# that's all ! you can use it in your graphics now :) 
# if self is a widget, you can do this 
root = Widget() 
with root.canvas: 
    Rectangle(texture=texture, pos=(0, 0), size=(1280*3, 1024*3)) 

runTouchApp(root) 

Edit2: Fondamentalmente sono tornato al problema originale: Ho un allineamento NumPy (tipo 'numpy.ndarray'; DTYPE 'uint8') e sto cercando di convertirlo in un formato, in modo che la texture mi mostrerà l'immagine. Ho provato a scomporlo allo stesso modo in cui è fatto nel codice di esempio che ho postato sopra. Ma purtroppo non funziona. Non so davvero cosa sto sbagliando qui. (il mio allineamento NumPy è chiamato IM2 nel codice folling)

list1 = numpy.array(im2).reshape(-1,).tolist() 

arr = array('B', list1) 

texture.blit_buffer(arr, colorfmt='rgb', bufferfmt='ubyte') 

risposta

5

Numpy hanno un attributo tostring(), che è possibile utilizzare direttamente, se la matrice di origine è di tipo uint8. Non c'è nemmeno bisogno di rimodellare:

texture = Texture.create(size=(16, 16), colorfmt="rgb")) 
arr = numpy.ndarray(shape=[16, 16, 3], dtype=numpy.uint8) 
# fill your numpy array here 
data = arr.tostring() 
texture.blit_buffer(data, bufferfmt="ubyte", colorfmt="rgb" 

Circa il problema che stai parlando nel commento, vedo 2 punti:

  1. garantire la richiamata dal ROS è chiamato nel mainthread. Forse l'aggiornamento è semplicemente ignorato.
  2. Quando si modifica manualmente la trama, l'oggetto associato che lo utilizza non viene informato, è necessario farlo. Aggiungi un self.canvas.ask_update() per garantire la visualizzazione della tela al fotogramma successivo.
+0

anks, ho provato quella smussatura. Forse è colpa mia se aggiorno quella matrice. Quindi proverò a spiegare la mia intera domanda. Sto ottenendo un'immagine tramite un nodo ROS. Sto riportando l'immagine a un formato rgb im2 = CvBridge(). Imgmsg_to_cv2 (data, "rgb8") quindi sono sostanzialmente tornato a un array numpy. L'abbonato ROS ha una funzione di callback in cui la trama viene cambiata. Ma non vedo questo cambiamento. Forse diventa più chiaro quando date un'occhiata a: (https://gist.github.com/Holzroller/1ec092ce798afd9c8b34) – Holzroller

+0

a 1.Non penso che l'aggiornamento sia ignorato, per questo motivo ho aggiunto alcune funzioni di stampa per vedere se il callback è stato eseguito. Inoltre sono stato in grado di esportare l'immagine che ho ottenuto tramite ROS in un JPEG usando OpenCV. a 2. I aggiunto self.canvas.ask_update() in ogni funzione, ma purtroppo non ottengo di vedere l'immagine :( In ogni modo, grazie mille per il vostro sostegno https:.! // Gist .github.com/Holzroller/2f7f95b0958d6e406667 – Holzroller

+1

Non ignorato nel python, ignorato in GL poiché non si è nel thread opengl/main, ma normalmente se non lo si è, si blocca. Non riesco ancora a capire come opencv/ros chiama il callback senza essere nel mainthread – tito