2011-08-09 38 views
1

我使用OpenCV 2.3的Python接口。我有一個用C語言編寫的庫,期望OpenCV對象,例如IplImage。像這樣:OpenCV Python接口和ctypes庫之間的互操作性

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' 

如何我要這樣做嗎?

回答

2

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中的imgid是它的基地址。使用ctypes,您可以直接訪問該對象的a字段,即您需要的IplImage *

>>> 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 
+0

在Ubuntu 14.04的cv2中,圖像不會作爲C風格的IplImage返回。它作爲numpy.ndarray()返回。通過使用my_array.data_as(c_void_p)將ndarray()值傳遞給C函數相對比較容易。 –