2010-08-29 13 views
2

J'essaie d'afficher des images en direct de mon appareil photo 1394. Actuellement, mon code est capable d'obtenir des images dans une boucle à partir de la caméra et je cherchais une interface graphique rapide qui se mettra à jour dynamiquement (comme un fil séparé). Je peux le faire dans PyQt peut-être en utilisant QThreads mais y a-t-il une recommandation ou une façon plus rapide de le faire? Voici mon codeToute interface graphique Python rapide pour afficher des images en direct de la caméra

#loop Capture d'images de la caméra

for frame in range(1,500): 

print 'frame:',frame 

TIME.sleep(1) #capture frame every second 

image_binary = pycam.cam.RetrieveBuffer() 

#convert to PIL Image 

pilimg = PIL.Image.frombuffer("L",(cimg.GetCols(),cimg.GetRows()),image_binary,'raw', "RGBA", 0, 1) 
    # At this point I want to send my image data to a GUI window and display it 

Remerciement.

Répondre

6

est ici le code wxPython qui le fera ...

import wx 
from PIL import Image 

SIZE = (640, 480) 

def get_image(): 
    # Put your code here to return a PIL image from the camera. 
    return Image.new('L', SIZE) 

def pil_to_wx(image): 
    width, height = image.size 
    buffer = image.convert('RGB').tostring() 
    bitmap = wx.BitmapFromBuffer(width, height, buffer) 
    return bitmap 

class Panel(wx.Panel): 
    def __init__(self, parent): 
     super(Panel, self).__init__(parent, -1) 
     self.SetSize(SIZE) 
     self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) 
     self.Bind(wx.EVT_PAINT, self.on_paint) 
     self.update() 
    def update(self): 
     self.Refresh() 
     self.Update() 
     wx.CallLater(15, self.update) 
    def create_bitmap(self): 
     image = get_image() 
     bitmap = pil_to_wx(image) 
     return bitmap 
    def on_paint(self, event): 
     bitmap = self.create_bitmap() 
     dc = wx.AutoBufferedPaintDC(self) 
     dc.DrawBitmap(bitmap, 0, 0) 

class Frame(wx.Frame): 
    def __init__(self): 
     style = wx.DEFAULT_FRAME_STYLE & ~wx.RESIZE_BORDER & ~wx.MAXIMIZE_BOX 
     super(Frame, self).__init__(None, -1, 'Camera Viewer', style=style) 
     panel = Panel(self) 
     self.Fit() 

def main(): 
    app = wx.PySimpleApp() 
    frame = Frame() 
    frame.Center() 
    frame.Show() 
    app.MainLoop() 

if __name__ == '__main__': 
    main() 
+0

Salut FogleBird, Je reçois l'erreur suivante: AttributeError: l'objet 'module' n'a pas d'attribut 'CallLater'. Donc j'ai utilisé wx.FutureCall, puis j'ai l'erreur AttributeError: l'objet 'module' n'a pas d'attribut 'BitmapFromBuffer' Des recommandations? – blueskin

+0

Quelle version de wxPython utilisez-vous? Quelle plateforme? – FogleBird

+0

Ubuntu 10.04; wxPython 2.8; Python 2.6 – blueskin

0

Essayez de jeter un coup d'œil à gstreamer. This est le premier résultat que google m'a donné à la recherche de "gstreamer 1394" et this one est le premier pour "gstreamer pyqt".

+0

Hey mg, GStreamer ressemble à un paquet entier qui fait tout. Eh bien, je bibliothèque sympa qui me procure des images personnalisées de mon appareil photo 1394 donc je ne veux pas utiliser de lib pour ça. Et je cherchais quelque chose de petit. J'ai modifié mon message et ajouté du code. Laissez-moi savoir si vous avez des suggestions. Best, – blueskin

+0

Le [deuxième résultat par google] (http://pypi.python.org/pypi/Dc1394/0.1). Pour l'intégration de l'interface utilisateur, consultez les autres réponses ou consultez le [script de test] (http://www.rzuser.uni-heidelberg.de/~ge6/Programing/download/FastDisplay.py) à la page d'accueil [dc1394]. (http://www.rzuser.uni-heidelberg.de/~ge6/Programing/dc1394python.html). –

2

Je recommande d'utiliser Tkinter car il fait déjà partie de python. Je n'ai jamais utilisé PIL mais un rapide google montre qu'il est facile d'utiliser les images PIL dans les widgets Tk (via la méthode pil.ImageTk.PhotoImage()).

Si vous avez déjà un widget Tkinter configuré pour afficher des images (un widget Étiquette fonctionne correctement), tout ce que vous devez faire est d'organiser la mise à jour de l'image toutes les secondes. Vous pouvez le faire en utilisant la commande after de tkinter.

Voici un exemple; Je n'ai pas PIL il utilise une image statique mais il illustre comment utiliser la boucle d'événement pour aller chercher des images chaque seconde:

import Tkinter 

class App(Tkinter.Tk): 
    def __init__(self): 
     Tkinter.Tk.__init__(self) 
     self.label = Tkinter.Label(text="your image here", compound="top") 
     self.label.pack(side="top", padx=8, pady=8) 
     self.iteration=0 
     self.UpdateImage(1000) 

    def UpdateImage(self, delay, event=None): 
     # this is merely so the display changes even though the image doesn't 
     self.iteration += 1 

     self.image = self.get_image() 
     self.label.configure(image=self.image, text="Iteration %s" % self.iteration) 
     # reschedule to run again in 1 second 
     self.after(delay, self.UpdateImage, 1000) 

    def get_image(self): 
     # this is where you get your image and convert it to 
     # a Tk PhotoImage. For demonstration purposes I'll 
     # just return a static image 
     data = ''' 
      R0lGODlhIAAgALMAAAAAAAAAgHCAkC6LV76+vvXeswD/ANzc3DLNMubm+v/6zS9PT6Ai8P8A//// 
      /////yH5BAEAAAkALAAAAAAgACAAAAS00MlJq7046803AF3ofAYYfh8GIEvpoUZcmtOKAO5rLMva 
      0rYVKqX5IEq3XDAZo1GGiOhw5rtJc09cVGo7orYwYtYo3d4+DBxJWuSCAQ30+vNTGcxnOIARj3eT 
      YhJDQ3woDGl7foNiKBV7aYeEkHEignKFkk4ciYaImJqbkZ+PjZUjaJOElKanqJyRrJyZgSKkokOs 
      NYa2q7mcirC5I5FofsK6hcHHgsSgx4a9yzXK0rrV19gRADs= 
     ''' 
     image = Tkinter.PhotoImage(data=data) 
     return image 

if __name__ == "__main__": 
    app=App() 
    app.mainloop() 
+0

J'ai essayé d'utiliser Tkinter mais quand j'ai dû afficher la fenêtre de l'interface graphique, j'ai dû appeler mainloop() qui arrête tout à ce moment-là, c'est-à-dire une fonction de blocage. Je veux obtenir des images et mettre à jour la fenêtre de l'interface graphique de Tkinter. Y-a-t-il un moyen de faire ça? – blueskin

+0

@chenna: vous aurez ce problème, peu importe la boîte à outils que vous utilisez. Tous les toolkits GUI ont besoin d'une boucle d'événement. Ils ont tous aussi un moyen d'interposer des événements (faute d'une meilleure description).Dans le cas de Tkinter, vous pouvez appeler 'after' pour avoir quelque chose appelé par la boucle d'événement à un moment donné dans le futur. J'ai édité ma réponse pour vous donner un exemple de travail. –

+0

Merci Bryan. Je reçois l'erreur suivante, aucune idée de ce qui la provoque ?? File "LiveCam.py", à la ligne 28, dans __init__ self.UpdateImage (1000) File "LiveCam.py", ligne 36, à UpdateImage self.label.configure (image = self.image) fichier «/usr/lib/python2.6/lib-tk/Tkinter.py ", ligne 1205, dans configure return self._configure ('configure', cnf, kw) Fichier" /usr/lib/python2.6/lib- tk/Tkinter.py ", ligne 1196, dans _configure self.tk.call (_flatten ((self._w, cmd)) + self._options (cnf)) TypeError: __str__ renvoyé non-chaîne (instance de type) – blueskin

4

Je pensais que je vais essayer PyQt4 exemple imageviewer.py et cela a fonctionné pour moi . Merci pour votre aide les gars. Voici mon code modifié:

from PyQt4 import QtCore, QtGui 
class CameraViewer(QtGui.QMainWindow): 
    def __init__(self): 
    super(CameraViewer, self).__init__() 

    self.imageLabel = QtGui.QLabel() 
    self.imageLabel.setBackgroundRole(QtGui.QPalette.Base) 
    self.imageLabel.setScaledContents(True) 

    self.scrollArea = QtGui.QScrollArea() 
    self.scrollArea.setWidget(self.imageLabel) 
    self.setCentralWidget(self.scrollArea) 

    self.setWindowTitle("Image Viewer") 
    self.resize(640, 480) 

    timer = QtCore.QTimer(self) 
    timer.timeout.connect(self.open) 
    timer.start(33) #30 Hz 

    def open(self): 
    #get data and display 
    pilimg = getMyPILImageDatFromCamera() 
    image = PILQT.ImageQt.ImageQt(pilimg) 
    if image.isNull(): 
     QtGui.QMessageBox.information(self, "Image Viewer","Cannot load %s." % fileName) 
     return 

    self.imageLabel.setPixmap(QtGui.QPixmap.fromImage(image)) 
    self.imageLabel.adjustSize() 


if __name__ == '__main__': 

    import sys 

    app = QtGui.QApplication(sys.argv) 
    CameraViewer = CameraViewer() 
    CameraViewer.show() 
    sys.exit(app.exec_())