2010-08-29 4 views
2

Я пытаюсь отображать живые изображения с моей камеры 1394. В настоящее время мой код способен получать изображения в цикле с камеры, и я искал любой быстрый графический интерфейс, который будет динамически обновляться (как отдельный поток). Я могу сделать это в PyQt, возможно, используя QThreads, но есть ли какие-либо рекомендации или более быстрый способ сделать это? Вот мой кодЛюбой быстрый графический интерфейс Python для отображения прямых изображений с камеры

#loop захвата кадров из камеры

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 

Спасибо.

ответ

6

Вот wxPython код, который будет делать это ...

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

Hi FogleBird, Я получаю следующую ошибку: AttributeError: объект 'module' не имеет атрибута 'CallLater'. Поэтому я использовал wx.FutureCall, затем получаю ошибку AttributeError: объект 'module' не имеет атрибута 'BitmapFromBuffer' Любые рекомендации? – blueskin

+0

Какую версию wxPython вы используете? Какая платформа? – FogleBird

+0

Ubuntu 10.04; wxPython 2.8; Python 2.6 – blueskin

0

Попробуйте взглянуть на gstreamer. This - это первый результат, который Google дал мне поиск «gstreamer 1394» и this one является первым для «gstreamer pyqt».

+0

Hey мг, GStreamer выглядит как весь пакет, который делает все. Ну, я хорошая библиотека, которая получает мне пользовательские изображения с моей камеры 1394, поэтому я не хочу использовать какую-либо библиотеку для этого. И я искал что-то маленькое. Я редактировал свой пост и добавил код. Дайте мне знать, если у вас есть предложения. Best, – blueskin

+0

[второй результат google] (http://pypi.python.org/pypi/Dc1394/0.1). Для интеграции с пользовательским интерфейсом посмотрите другие ответы или посмотрите [тестовый сценарий] (http://www.rzuser.uni-heidelberg.de/~ge6/Programing/download/FastDisplay.py) на домашней странице [dc1394] (http://www.rzuser.uni-heidelberg.de/~ge6/Programing/dc1394python.html). –

2

Я рекомендую использовать Tkinter, так как это уже часть питона. Я никогда не использовал PIL, но быстрый Google показывает, что легко использовать изображения PIL в виджетах Tk (с помощью метода pil.ImageTk.PhotoImage()).

Если у вас уже есть виджет Tkinter, настроенный для отображения изображений (виджет Label отлично работает), все, что вам нужно сделать, это организовать обновление изображения каждую секунду или около того. Вы можете сделать это, используя команду tkinter after.

Вот пример; У меня нет PIL поэтому он использует статическое изображение, но оно показывает, как использовать цикл событий для извлечения изображений каждый второй:

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

Я пробовал использовать Tkinter, но когда inorder отображал окно GUI, мне приходилось вызывать mainloop(), который останавливает все в этой точке, то есть это блокирующая функция. Я хочу получить изображения и обновить окно TKinter GUI. Есть ли способ сделать это? – blueskin

+0

@chenna: у вас будет эта проблема независимо от того, какой инструментарий вы используете. Все инструментальные средства GUI нуждаются в цикле событий. Все они также имеют возможность вмешиваться в события (из-за отсутствия лучшего описания).В случае Tkinter вы можете вызвать 'after', чтобы что-то вызывать в цикле событий в какой-то момент в будущем. Я отредактировал свой ответ, чтобы дать вам рабочий пример. –

+0

Спасибо, Брайан. Я получаю следующую ошибку, любые идеи, что вызывает ее? Файл "LiveCam.py", строка 28, в __init__ self.UpdateImage (1000) Файл "LiveCam.py", строка 36, в UpdateImage self.label.configure (изображение = self.image) Файл «/ usr/lib/python2.6/lib-tk/Tkinter.py ", строка 1205, в конфигурации return self._configure ('configure', cnf, kw) Файл« /usr/lib/python2.6/lib- tk/Tkinter.py ", строка 1196, в _configure self.tk.call (_flatten ((self._w, cmd)) + self._options (cnf)) ТипError: __str__ возвращен нестроковый (экземпляр типа) – blueskin

4

Я думал, что я хотел бы попробовать PyQt4 imageviewer.py пример, и она работала для меня , Спасибо за помощь. Вот мой модифицированный код:

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_())