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.
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()
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With