Python Interface

OpenCV has a built in python interface that utilizes SWIG to automate a large portion of the C -> python conversion code. This page documents

  1. API Differences in Python
  2. Using the Interface in an Interactive Shell

IF ANYTHING ON THIS PAGE DOESN'T WORK AS YOU EXPECT, PLEASE REPORT A BUG.



API Differences in Python

In most cases, the API in python is exactly the same as in C, however, additional effort has been made to make interface more pythonic when appropriate. This is manifest in changes to both structures and functions.

Changes to OpenCV Functions

Changes to functions are minimal in order to maintain consistency between between C and Python. One important difference is the case of functions that return values in their arguments. Since basic types in python are immutable, such function have been modified to instead return multiple values.

Changes to OpenCV Structures

In most cases, OpenCV structures in python have the same functionality as in C, with some additional sugar. These additions and variations are described below for those structures that vary signifcantly from their C counterparts.

Arrays

No IplImage

The most important difference with regard to arrays is the elimination of IplImage. This change had to do with the way SWIG and python handle memory and the lack of reference counting in IplImage. The following accommodations have been made to ease the transition:

Iteration

CvMat been extended with special python methods like __iter__ and __getitem__ to simplify iteration and element access. For example:

Iterate through rows of array

   1 x = cvCreateMat(m, n, type)
   2 for row in x:
   3     # row is same as that returned by cvGetRow

Iterate through columns of array

   1 for col in x.colrange():
   2     # col is same as that returned by cvGetCol

Slice Access

Get a row

   1 row = x[i]

Get a column

   1 col = x[:, i]

Get a subrectangle

   1 slice = x[0:10, 0:10]

Get an element

   1 elem = x[i, j]
   2 # or
   3 elem = x[i][j]
   4 # or if x is a vector
   5 elem = x[i]

This works for setting values as well

   1 # x and y are CvMat's
   2 x[0:10, 0:5] = y[10:20, 1:6]
   3 x[i, j] = 1;
   4 x[:, :] = 1;
   5 x[:, :] = cvScalar(1);
   6 x[0:10, i] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

CvMatND

No work has gone into making this more pythonic. If you are interested in changing this, please contact RomanStanchak.


Histograms

You will notice when using the latest wrappers (at the time of writing, the rev. 1887 of the SVN) that you cannot use the function cvCalcHist. A bug file has been submitted, and before a correction is available, you can call the function cvCalcArrHist which will give you what you wanted.


Sequences

The biggest challenge with sequences is that in C, we must cast in order to access elements of the sequence. To make this transparent in Python, all CvSeq returned by OpenCV functions in python are now typed. This makes iteration and element access easier and more pythonic. For example, the function cvFindContours:

   1 num_contours, contours = cv.cvFindContours(...)
   2 # hrange iterates through h_next element
   3 for contour in contours.hrange():
   4     # contour is a CvSeq of points
   5     for pt in contour:
   6         print pt
   7     # alternately
   8     for pt in contour.vrange():
   9         print pt
  10     # alternately
  11     for i in range(contour.total):
  12         print contour[i]

Using an Interactive Shell

The python interface of course allows OpenCV functions to be used in an interactive shell. Here is a brief session from the python interpreter that loads and displays an image.

   1 from opencv.cv import *
   2 from opencv.highgui import *
   3 cvStartWindowThread()
   4 cvNamedWindow("win")
   5 im = cvLoadImage("pics/airplane.jpg")
   6 cvShowImage("win", im)

Note the use of cvStartWindowThread. This function is only available on Linux at the moment, but removes the need to refresh the image manually using cvWaitKey(), thus freeing the interactive interpreter for user input.

The Python interactive shell is somewhat lacking in features compared to the command line in most OSes and programs like Matlab. IPython is an enhanced python shell with built-in features such as tab completion, color, and debugging.

The bash script below will conveniently load IPython, the OpenCV modules, and starts the windowing thread.

   1 #!/bin/bash
   2 ipython -c "from opencv import *; \
   3             from opencv.highgui import *; \
   4             from opencv.matlab_syntax import *; \
   5             cvStartWindowThread(); \
   6             print \"OpenCV libraries loaded.\"" -i

Matlab Syntax

Users familiar with Matlab or SciPy may find the matlab_syntax module useful. This implements some basic functions for creating arrays that emulate Matlab and/or SciPy. Mostly, these are convenient because they are less verbose than the standard OpenCV functions. For example,

   1 from opencv.cv import *
   2 from opencv.highgui import *
   3 from opencv.matlab_syntax import *
   4 cvStartWindowThread()
   5 im = imread("pics/airplane.jpg")
   6 imshow(im)

Is equivalent to the example above of loading and displaying an image.

Building the wrappers

From scratch with Python 2.6, visual C++ 2008 Express edition

I know the wrappers are provided with the install since version 1.1 of OpenCV but if you're working with an older or newer version of python this little guide could come in handy! So here is what I had to do to (re)build the wrappers using python 2.6.1 and visual C++ Express 2008 from scratch (not using cmake):

Set these environment variables (system-wide):

Then add to the PATH your path to the bin folder of visual c++, in my system using the standard install it was: "C:\Program Files\Microsoft Visual Studio 9.0\VC\bin"

Ok now go to where the python wrappers are using a console and type:

vcvars32.bat
python setup-for-win.py bdist --format="wininst"

And it "should" work well (at least this did the trick for me...)

Using CMAKE

Well, instead of going through all the mess that I described before, you can use cmake to create a "partially" perfect makefile that will allows you to build the wrappers in a single click. I had only to tweak one file, the cmake_install.cmake located in the interfaces/swig/python directory because cmake adds .dll to the generated files while the python wrappers are .pyd, so just change the concerned lines:

"C:/OpenCV_SVN/lib/$(OutDir)/_cv.pyd"
"C:/OpenCV_SVN/lib/$(OutDir)/_ml.pyd"
"C:/OpenCV_SVN/lib/$(OutDir)/_highgui.pyd"

Ok now you can have fun! :-)

OpenCVWiki: SwigPythonInterface (last edited 2009-09-30 16:53:40 by JamesBowman)