我是python的新手。我正在尝试编写一个运动检测应用程序。目前,我正在尝试将网络摄像头视频显示在屏幕上。当前的代码现在没有闪烁,但在任何调整大小后,闪烁将会回来。任何线索?另外,为什么没有self.Refresh()在timer事件中它不工作,除非框架被最小化,否则不会发生paint事件?提前致谢。
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()
答案 0 :(得分:4)
我找到了解决这个问题的方法。闪烁来自面板清除其背景。我必须创建一个面板实例并使其EVT_ERASE_BACKGROUND绕过。另一件事是我必须将网络摄像头例程放在该面板中,并在面板上绘制BufferPaintedDC图。出于某种原因,如果wx.BufferedPaintedDC从帧中绘制到self.displaypanel,则闪烁仍然存在。
答案 1 :(得分:1)
当你画画时,你只需要调用刷新。这是一个要求。我不记得为什么。为了摆脱闪烁,你可能想要阅读DoubleBuffering:http://wiki.wxpython.org/DoubleBufferedDrawing
或许你可以使用mplayer控件。这里有一个例子:http://www.blog.pythonlibrary.org/2010/07/24/wxpython-creating-a-simple-media-player/