Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenCV Python接口与ctypes库之间的互操作性_Python_Opencv_Ctypes - Fatal编程技术网

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

OpenCV Python接口与ctypes库之间的互操作性,python,opencv,ctypes,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

我正在使用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

如何执行此操作?

cv.iplimage
是由定义的CPython对象。它包装了您需要的指针。有几种方法可以找到这个指针。我将使用CPython
id
返回对象基址这一事实

import cv, cv2
from ctypes import *
您可以使用
c\u void\u 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中,
img
id
是它的基址。使用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

cv.iplimage
是由定义的CPython对象。它包装了您需要的指针。有几种方法可以找到这个指针。我将使用CPython
id
返回对象基址这一事实

import cv, cv2
from ctypes import *
您可以使用
c\u void\u 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中,
img
id
是它的基址。使用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

在Ubuntu14.04的cv2中,图像不会以C风格的IplImage返回。它作为numpy.ndarray()返回。使用my_array.data_as(C_void_p)将ndarray()值传递给C函数相对容易。出现此错误
AttributeError:'numpy.ndarray'对象没有属性“data_as”
对于Python2.7.12,在Ubuntu14.04的cv2中,图像不会作为C风格的IplImage返回。它作为numpy.ndarray()返回。使用my_array.data_as(C_void_p)将ndarray()值传递给C函数相对容易。出现此错误
AttributeError:'numpy.ndarray'对象没有属性“data_as”
,适用于Python 2.7.12