Opencv integration with wxpython

发布于 2021-01-29 14:09:48

I just wanted to integrate the opencv video stream from my web cam into a more
complex gui than highgui can offer, nothing fancy just a couple of buttons and
something else, however it’s proven to be not that trivial. I can’t find any
base example from which I can start designing the gui. I tried converting this
code to
the new opencv interface with quite a poor result. I’m a new to opencv, numpy
and gui design. Some time does stream the video but most of the time it just
hangs there. I guess my one mistake might be in wx.BitmapFromBuffer(col, row,
img) since in the older version they used pil image format and now it’s using
numpy arrays so in the original code the used the pil function “imageData”,
instead of passing directly the numpy array as I’m doing. Any help it’s really
appreciated. color_channels_pic

This is my code conversion.

import wx
import cv2

class MyFrame(wx.Frame):
   def __init__(self, parent):
       wx.Frame.__init__(self, parent)
       self.displayPanel = wx.Panel(self)
       self.displayPanel.SetSize(wx.Size(800,640))

       self.cam = cv2.VideoCapture(1)
       self.cam.set(3, 640)
       self.cam.set(4, 480)
       ret, img = self.cam.read()

       cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
       row, col, x = img.shape
       self.SetSize((col,row))
       self.bmp = wx.BitmapFromBuffer(col, row, img)
       self.displayPanel.Bind(wx.EVT_PAINT, self.onPaint)

       self.playTimer = wx.Timer(self)
       self.Bind(wx.EVT_TIMER, self.onNextFrame)

       self.playTimer.Start(1000/15)

    def onPaint(self, evt):
        if self.bmp:
            dc = wx.BufferedPaintDC(self.displayPanel)
            self.PrepareDC(dc)
            dc.DrawBitmap(self.bmp, 0, 0, True)
        evt.Skip()

    def onNextFrame(self, evt):
        ret, img = self.cam.read()
        if ret == True:
            cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            self.bmp.CopyFromBuffer(img)
            self.displayPanel.Refresh()
        evt.Skip()

if __name__=="__main__":
    app = wx.App()
    MyFrame(None).Show()
    app.MainLoop()
关注者
0
被浏览
157
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    The following example code works fine for me under OS X, but I’ve had tiny
    surprises with wx across platforms. It is nearly the same code, the difference
    is that the result from cvtColor is reassigned, and a subclass of wx.Panel
    (which is the important part) was added.

    import wx
    import cv, cv2
    
    class ShowCapture(wx.Panel):
        def __init__(self, parent, capture, fps=15):
            wx.Panel.__init__(self, parent)
    
            self.capture = capture
            ret, frame = self.capture.read()
    
            height, width = frame.shape[:2]
            parent.SetSize((width, height))
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    
            self.bmp = wx.BitmapFromBuffer(width, height, frame)
    
            self.timer = wx.Timer(self)
            self.timer.Start(1000./fps)
    
            self.Bind(wx.EVT_PAINT, self.OnPaint)
            self.Bind(wx.EVT_TIMER, self.NextFrame)
    
    
        def OnPaint(self, evt):
            dc = wx.BufferedPaintDC(self)
            dc.DrawBitmap(self.bmp, 0, 0)
    
        def NextFrame(self, event):
            ret, frame = self.capture.read()
            if ret:
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                self.bmp.CopyFromBuffer(frame)
                self.Refresh()
    
    
    capture = cv2.VideoCapture(0)
    capture.set(cv.CV_CAP_PROP_FRAME_WIDTH, 320)
    capture.set(cv.CV_CAP_PROP_FRAME_HEIGHT, 240)
    
    app = wx.App()
    frame = wx.Frame(None)
    cap = ShowCapture(frame, capture)
    frame.Show()
    app.MainLoop()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看