OpenCV Python接口和ctypes库之间的互操作性

时间:2011-08-09 19:29:40

标签: python opencv ctypes

我正在使用OpenCV 2.3的Python界面。我有一个用C语言编写的库,它希望作为参数使用OpenCV对象,例如IplImage。像这样:

void MyFunction(IplImage* image);

我希望从我的Python代码中调用此函数。我试过了:

library.MyFunction(image)

但它给了我一个错误:

ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1

我也试过使用byref,但它仍然不起作用:

TypeError: byref() argument must be a ctypes instance, not 'cv.iplimage'

我该怎么做?

1 个答案:

答案 0 :(得分:3)

cv.iplimage是由iplimage_t定义的CPython对象。它包装了您需要的IplImage指针。有几种方法可以获得此指针。我将使用CPython id返回对象基址的事实。

import cv, cv2
from ctypes import *

您可以使用c_void_p代替IplImage。我在下面定义它以证明指针是正确的。

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)]

CPython对象:

class iplimage_t(Structure):
    _fields_ = [('ob_refcnt', c_ssize_t),
                ('ob_type',  py_object),
                ('a', POINTER(IplImage)),
                ('data', py_object),
                ('offset', c_size_t)]

将示例加载为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)

在CPython中,id的{​​{1}}是其基地址。使用ctypes,您可以直接访问此对象的img字段,即您需要的a

IplImage *