Ask Your Question

Revision history [back]

This is part of a bigger project, so I had to peel the source code out of it - its dirty but it makes my point. The goal is an application which records a video and sends time stamps to various other machines and a PowerLab. WxPython is in the game because theres a lot of GUI and other processes. In the source code I left the video in its original size - because the effect comes earlier. (I know it would be a solution to make the video as small as possible but then the effect would simply occur later).

The capturing and writing out the frames is done by a wxpython timer. And theres no change if I remove the wxpython stuff. Thats the source code:

!/usr/bin/env python

import wx import time import cv, cv2 import sys from pylab import *

class MyFrame(wx.Frame): def __init__(self, args, *kwds):

      ############################################################################ initialize camera and capturing
      self.capture = cv2.VideoCapture(0) 
      ret, self.frame = self.capture.read()
      self.cwidth=int(self.capture.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
      self.cheight=int(self.capture.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))


      self.capSize=(self.cwidth,self.cheight)
      self.fps=12.5
      self.frames=0
      self.iterations=2000 ###################### number of frames to capture
      self.frame_rate_data=[]
      self.frame_data=[]

      print 'Camera loaded',self.cwidth,self.cheight,self.capSize

      ######################################################################## wxpython
      wx.Frame.__init__(self, *args, **kwds)
      mainSizer = wx.BoxSizer(wx.VERTICAL)

      videoWarper = wx.StaticBox(self, label="Video",size=(self.cwidth,self.cheight))
      videoBoxSizer = wx.StaticBoxSizer(videoWarper, wx.VERTICAL)
      self.videoPanel = wx.Panel(self, -1,size=(self.cwidth,self.cheight))
      videoBoxSizer.Add(self.videoPanel,0)
      mainSizer.Add(videoBoxSizer,0)
      self.Show()
      self.SetSizerAndFit(mainSizer)

      ######################################################################## convert frame to bmp for wx python
      self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
      self.bmp = wx.BitmapFromBuffer(self.cwidth, self.cheight, self.frame)

      ######################################################################## initialize videowriter
      self.fourcc = cv2.cv.CV_FOURCC('m', 'p', '4', 'v') 
      self.vout = cv2.VideoWriter() ################################################### open videowriter 
  self.outmovie='test'+'.mov'
      success = self.vout.open(self.outmovie,self.fourcc,self.fps,self.capSize,True)

      ####################################################################### initialize timer
      self.timer = wx.Timer(self.videoPanel)
      self.videoPanel.Bind(wx.EVT_PAINT, self.OnPaint)
      self.videoPanel.Bind(wx.EVT_TIMER, self.NextFrame)
      self.t0 =time.time()
      self.timer.Start(int(1000.0/self.fps))

 def OnPaint(self, event):           
                dc = wx.BufferedPaintDC(self.videoPanel)
                dc.DrawBitmap(self.bmp, 0, 0)

 def NextFrame(self, event):
                 ret, self.frame = self.capture.read()
                 if ret:  
                               self.xtime= time.time() - self.t0 
                               self.frames=self.frames+1
                               self.vout.write(self.frame) ######################### this is the offending line !!!   videowriter on - off             

                               xtime= time.time() - self.t0 
                               fpa= self.frames/xtime      
                               #print  self.frames, self.xtime, fpa
                               self.frame_rate_data.append (fpa)
                               self.frame_data.append (self.frames)

                               self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
                               self.bmp.CopyFromBuffer(self.frame)
                               self.Refresh()

                               if self.frames ==self.iterations: ################### plot and quit
                                    plot(self.frame_data,self.frame_rate_data)
                                    grid(True)
                                    savefig("test.png")
                                    show()
                                    self.Destroy()
                                    sys.exit()

if __name__ == "__main__":

    app=wx.App(False)
    frame_1 = MyFrame(None, wx.ID_ANY, "")
    app.SetTopWindow(frame_1)
    frame_1.Show()
    app.MainLoop()

Ok - thats the performance with commenting simply the line videowriter out: image description

Now lets write frames and the performance looks like this: image description

As you see the cumulative frames per second just drop away. The error can't be in the rest of the program, because its only by one line commented or uncommented.

Sorry for the dirty hack.