Making OpenCV more Pythonic?

asked 2013-03-21 08:59:38 -0600

AGMark gravatar image

Hi,

I'm new to OpenCV, and in a short time I've found it very powerful and exceedingly useful. However, my language of choice is Python and the API for OpenCV is decidedly non-pythonic, and I find it rather jarring. For instance having to call vid.set(cv2.cv.CV_CAP_PROP_FOURCC, cv2.cv.CV_FOURCC('M', 'J', 'P', 'G')) just to set the codec of a video is rather opaque. Better would be vid.set_fourcc('MJPG'). Just as importantly the library is missing out on many of the opportunities that Python offers like iterators, error handling, and docstrings.

As an example of what's possible I've written a thin wrapper over the VideoCapture and VideoWriter classes in an attempt to make them more Pythonic. The code can be found at https://github.com/hohlraum/cvx/blob/master/video.py. Using this, interacting with OpenCV is a breeze, and it particularly simplifies working in the interpreter. I've attached an example below. It shows the use of iterators, setter and getters, context handlers and exception handling.

Is there any interest in extending this?


In [1]: import cvx

In [2]: vid=cvx.VideoCapture('test.avi')

In [3]: print 'Number of frames:',len(vid)
Number of frames: 258

In [4]: print 'Video encoding: ', vid.get_fourcc()
Video encoding:  MJPG

In [5]: img=vid.read()

In [6]: img10=vid[10] #read the 10th frame

In [7]: #iterate over the first 20 frames of the video

In [8]: for i, frame in enumerate(vid):
   ...:         print 'Frame #',i,' mean:', frame.mean()
   ...:         if i>20: break   
   ...:     
Frame # 0  mean: 0.0
Frame # 1  mean: 0.0
Frame # 2  mean: 0.0
Frame # 3  mean: 0.0
Frame # 4  mean: 0.0
...
Frame # 17  mean: 0.0
Frame # 18  mean: 0.0
Frame # 19  mean: 0.0
Frame # 20  mean: 0.225670583019
Frame # 21  mean: 72.8216034416

In [9]: vid.release()

In [10]: vid.read() #errors raise exceptions
---------------------------------------------------------------------------
EOFError                                  Traceback (most recent call last)
<ipython-input-10-d62fedc632fb> in <module>()
----> 1 vid.read() #errors raise exceptions

/Users/Documents/software/cvx/video.pyc in read(self)
     37 
     38         if flag is False:
---> 39             raise EOFError('Reached the end of video')
     40         return img
     41 

EOFError: Reached the end of video

In [12]: #copy a video frame by frame 
   ....: with cvx.VideoCapture('test.avi') as vin:
   ....:         fourcc=vin.get_fourcc()
   ....:         fps=vin.get_fps()
   ....:         shape=(vin.get_width(), vin.get_height())    
   ....:         with cvx.VideoWriter('output.avi', fourcc, fps, shape) as vout:                
   ....:                 for frames in vin:
   ....:                         vout.write(frames)
   ....:                 

In [13]: vin=cvx.VideoCapture('output.avi')

In [14]: len(vin)
Out[14]: 258

edit retag flag offensive close merge delete