Любой быстрый Python GUI для отображения живых изображений с камеры - PullRequest
3 голосов
/ 30 августа 2010

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

# Цикл захвата кадров с камеры

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

Спасибо.

Ответы [ 5 ]

6 голосов
/ 30 августа 2010

Вот код 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()
4 голосов
/ 31 августа 2010

Я решил попробовать пример 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_())
2 голосов
/ 30 августа 2010

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

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

Вот пример;У меня нет 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 голосов
/ 24 февраля 2019

Поскольку хорошие ответы довольно велики, я чувствую, что должен опубликовать библиотеку, созданную специально для этого:

from cvpubsubs.webcam_pub import VideoHandlerThread
import numpy as np

image_np = numpy.array(pilImage)

def update_function(frame, cam_id):
    frame[...] = image_np[...]

VideoHandlerThread(video_source=image_np, callbacks=update_function).display()

На самом деле, это то, что image_binary каждый раз является новым массивом numpy. Если он назначен тому же местоположению, то это должно сработать:

from cvpubsubs.webcam_pub import VideoHandlerThread

VideoHandlerThread(video_source=image_np).display()

Я знаю, что OpenCV едва ли считается графическим интерфейсом, но это быстрый код.

0 голосов
/ 30 августа 2010

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

...