Reputation: 81
I am new to python. I am trying to write a motion detection app. Currently, I am trying to get the webcam video to display on the screen. Current code right now has no flicker at first, but after any resizing, the flicker will come back. Any clue? Also, why doesn't it work without self.Refresh() in the timer event, isn't paint event always happening unless the frame is minimized? Thanks in advance.
import wx
import cv
class LiveFrame(wx.Frame):
fps = 30
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, title="Live Camera Feed")
self.SetDoubleBuffered(True)
self.capture = None
self.bmp = None
#self.displayPanel = wx.Panel(self,-1)
#set up camaera init
self.capture = cv.CaptureFromCAM(0)
frame = cv.QueryFrame(self.capture)
if frame:
cv.CvtColor(frame,frame,cv.CV_BGR2RGB)
self.bmp = wx.BitmapFromBuffer(frame.width,frame.height,frame.tostring())
self.SetSize((frame.width,frame.height))
self.displayPanel = wx.Panel(self,-1)
self.fpstimer = wx.Timer(self)
self.fpstimer.Start(1000/self.fps)
self.Bind(wx.EVT_TIMER, self.onNextFrame, self.fpstimer)
self.Bind(wx.EVT_PAINT, self.onPaint)
self.Show(True)
def updateVideo(self):
frame = cv.QueryFrame(self.capture)
if frame:
cv.CvtColor(frame,frame,cv.CV_BGR2RGB)
self.bmp.CopyFromBuffer(frame.tostring())
self.Refresh()
def onNextFrame(self,evt):
self.updateVideo()
#self.Refresh()
evt.Skip()
def onPaint(self,evt):
#if self.bmp:
wx.BufferedPaintDC(self.displayPanel, self.bmp)
evt.Skip()
if __name__=="__main__":
app = wx.App()
app.RestoreStdio()
LiveFrame(None)
app.MainLoop()
Upvotes: 3
Views: 2664
Reputation: 81
I have found the solution to this problem. The flickering came from the panel clearing its background. I had to create a panel instance and have its EVT_ERASE_BACKGROUND bypass. Another thing is that I had to put the webcam routine inside that panel and have BufferPaintedDC drawing on the panel itself. For some reason, flicker still persist if wx.BufferedPaintedDC is drawing from the frame to self.displaypanel .
Upvotes: 5
Reputation: 33071
When you're drawing, you just have to call Refresh. It's a requirement. I don't remember why. To get rid of flicker, you'll probably want to read up on DoubleBuffering: http://wiki.wxpython.org/DoubleBufferedDrawing
Or maybe you could use the mplayer control. There's an example here: http://www.blog.pythonlibrary.org/2010/07/24/wxpython-creating-a-simple-media-player/
Upvotes: 1