Using opencv with wxpython
This page aims to be a quick reference guide to the combined usage of opencv, python and wxpython. All the examples should also work with wxwidget using the c++ syntax, I haven't tested them though.
At the time of writing this page I use wxpython 2.8, python 2.6 and the wrappers compiled using the svn from the 19th of may 2009 (rev.1765). Having wxpython 2.8 is very important since previous versions might not include the function wx.BitmapFromBuffer, which we use to convert the openCV images into a format which wxpython can handle. If you have more than one version of wxpython installed in your system, you can use the 'wxversion' module to select the version you want to use (see the examples).
Feel free to add any example that you find useful! If you are looking for more information about the python interface go to this page: PythonInterface
Display an Image in a panel
We begin by the most basic thing, displaying an image in a panel.
'''How to integrate openCV and wxpython.
This program loads an image file using openCV, converts it to a format
which wxpython can handle and displays the resulting image in a
wx.Frame.'''
# Select the version of wxpython to use.
import wxversion
wxversion.select('2.8')
import wx
import opencv.cv as cv
import opencv.highgui as gui
class CvDisplayPanel(wx.Panel):
def __init__(self, parent, img):
wx.Panel.__init__(self, parent, -1)
# Convert the raw image data to something wxpython can handle.
cv.cvCvtColor(img, img, cv.CV_BGR2RGB)
self.bmp = wx.BitmapFromBuffer(img.width, img.height,\
img.imageData)
# Display the resulting image
sbmp = wx.StaticBitmap(self, -1, bitmap=self.bmp)
if __name__=="__main__":
imageToDisplay = gui.cvLoadImage("lena.jpg")
app = wx.App()
app.RestoreStdio()
frame = wx.Frame(None, -1, size=(imageToDisplay.width, imageToDisplay.height))
CvDisplayPanel(frame, imageToDisplay)
frame.Show(True)
app.MainLoop()
Playing a movie
Still in the basics, let's play a movie using a frame this time. We will be using a webcam as an input.
import wx
import opencv.cv as cv
import opencv.highgui as gui
class CvMovieFrame(wx.Frame):
TIMER_PLAY_ID = 101
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1)
self.capture = gui.cvCreateCameraCapture(-1)
frame = gui.cvQueryFrame(self.capture)
self.SetSize((frame.width, frame.height))
self.displayPanel = wx.Panel(self, -1)
cv.cvCvtColor(frame, frame, cv.CV_BGR2RGB)
self.bmp = wx.BitmapFromBuffer(frame.width, frame.height, frame.imageData)
self.Bind(wx.EVT_PAINT, self.onPaint)
self.playTimer = wx.Timer(self, self.TIMER_PLAY_ID)
wx.EVT_TIMER(self, self.TIMER_PLAY_ID, self.onNextFrame)
fps = gui.cvGetCaptureProperty(self.capture, gui.CV_CAP_PROP_FPS)
self.Show(True)
if fps!=0: self.playTimer.Start(1000/fps)#every X ms
else: self.playTimer.Start(1000/15)#assuming 15 fps
def onPaint(self, evt):
if self.bmp:
dc=wx.BufferedPaintDC(self.displayPanel, self.bmp)
evt.Skip()
def onNextFrame(self, evt):
frame = gui.cvQueryFrame(self.capture)
if frame:
cv.cvCvtColor(frame, frame, cv.CV_BGR2RGB)
self.bmp.CopyFromBuffer(frame.imageData)
self.Refresh()
evt.Skip()
if __name__=="__main__":
app = wx.App()
app.RestoreStdio()
CvMovieFrame(None)
app.MainLoop()