任何用于显示来自相机的实时图像的快速 Python GUI

发布于 2024-09-16 07:56:59 字数 540 浏览 2 评论 0原文

我正在尝试显示 1394 相机的实时图像。 目前,我的代码能够从相机循环获取图像,并且我正在寻找任何可以动态更新的快速 GUI(作为单独的线程)。我可以在 PyQt 中使用 QThreads 来做到这一点,但是有没有任何建议或更快的方法来做到这一点? 这是我的代码

#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

谢谢。

I am trying to display live images from my 1394 camera.
Currently my code is able to obtain images in a loop from the camera and I was looking for any quick GUI that will update dynamically (as a separate thread). I can do this in PyQt maybe using QThreads but is there any recommendation or faster way of doing this??
Here's my code

#Loop capturing frames from camera

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

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

带上头具痛哭 2024-09-23 07:56:59

这是 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()

Here's wxPython code that will do it...

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()
风渺 2024-09-23 07:56:59

我想我应该尝试 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_())

I thought I'd try PyQt4 imageviewer.py example and it worked for me.
Thanks for all your help guys.
Here's my modified code:

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_())
早乙女 2024-09-23 07:56:59

我建议使用 Tkinter,因为它已经是 python 的一部分。我从未使用过 PIL,但快速谷歌显示在 Tk 小部件中使用 PIL 图像很容易(通过 pil.ImageTk.PhotoImage() 方法)。

如果您已经设置了一个 Tkinter 小部件来显示图像(标签小部件工作正常),您所需要做的就是安排图像每秒左右更新一次。您可以使用 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()

I recommend using Tkinter since it's already part of python. I've never used PIL but a quick google shows it's easy to use PIL images in Tk widgets (via the pil.ImageTk.PhotoImage() method).

If you already have a Tkinter widget set up to display images (a Label widget works fine) all you need to do is arrange for the image to be updated every second or so. You can do this by using the after command of tkinter.

Here's an example; I don't have PIL so it uses a static image but it illustrates how to use the event loop to fetch images every second:

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()
尽揽少女心 2024-09-23 07:56:59

由于好的答案非常大,我觉得我应该发布一个专门为此构建的库:

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 几乎不能算作 GUI,但这是快速的代码明智的。

Since the good answers are pretty large, I feel like I should post a library I built specifically for this:

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

Actually, that's if image_binary is a new numpy array every time. If it's assigned to the same location, then just this should work:

from cvpubsubs.webcam_pub import VideoHandlerThread

VideoHandlerThread(video_source=image_np).display()

I know OpenCV barely counts as a GUI, but this is quick code wise.

我一向站在原地 2024-09-23 07:56:59

尝试看看 gstreamer。 这是 google 给我搜索“gstreamer 1394”和 这个是“gstreamer pyqt”的第一个。

Try to take a look at gstreamer. This is the first result google gave me searching for "gstreamer 1394" and this one is the first for "gstreamer pyqt".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文