Interoperability between OpenCV Python interface and a ctypes library
I'm using the Python interface from OpenCV 2.3. I have a library written in C that expects, as arguments, OpenCV objects such as IplImage
. Like this:
void MyFunction(IplImage* image);
I wish, from my Python code, to call this function. I've tried:
library.MyFunction(image)
But i开发者_如何学JAVAt gives me an error:
ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1
I've also tried to use byref
but it still doesn't works:
TypeError: byref() argument must be a ctypes instance, not 'cv.iplimage'
How do I do this?
cv.iplimage
is a CPython object defined by iplimage_t
. It wraps the IplImage
pointer that you need. There are a few ways to get at this pointer. I'll use the fact that CPython id
returns the object base address.
import cv, cv2
from ctypes import *
You could use c_void_p
instead of defining IplImage
. I define it below in order to demonstrate that the pointer is correct.
class IplROI(Structure):
pass
class IplTileInfo(Structure):
pass
class IplImage(Structure):
pass
IplImage._fields_ = [
('nSize', c_int),
('ID', c_int),
('nChannels', c_int),
('alphaChannel', c_int),
('depth', c_int),
('colorModel', c_char * 4),
('channelSeq', c_char * 4),
('dataOrder', c_int),
('origin', c_int),
('align', c_int),
('width', c_int),
('height', c_int),
('roi', POINTER(IplROI)),
('maskROI', POINTER(IplImage)),
('imageId', c_void_p),
('tileInfo', POINTER(IplTileInfo)),
('imageSize', c_int),
('imageData', c_char_p),
('widthStep', c_int),
('BorderMode', c_int * 4),
('BorderConst', c_int * 4),
('imageDataOrigin', c_char_p)]
The CPython object:
class iplimage_t(Structure):
_fields_ = [('ob_refcnt', c_ssize_t),
('ob_type', py_object),
('a', POINTER(IplImage)),
('data', py_object),
('offset', c_size_t)]
Load an example as an iplimage
:
data = cv2.imread('lena.jpg') # 512 x 512
step = data.dtype.itemsize * 3 * data.shape[1]
size = data.shape[1], data.shape[0]
img = cv.CreateImageHeader(size, cv.IPL_DEPTH_8U, 3)
cv.SetData(img, data, step)
In CPython the id
of img
is its base address. Using ctypes you have direct access to the a
field of this object, i.e. the IplImage *
that you need.
>>> ipl = iplimage_t.from_address(id(img))
>>> a = ipl.a.contents
>>> a.nChannels
3
>>> a.depth
8
>>> a.colorModel
'RGB'
>>> a.width
512
>>> a.height
512
>>> a.imageSize
786432
精彩评论