开发者

Pointer on ctypes to use OpenCV on Python 3.1

I try to use OpenCV on Python 3.1 through ctypes, but I do not know how represent pointers. Example, if I want to load an image and print the content of her first pixel, I will write in C++:

#include <opencv/cv.h>
#include <opencv/highgui.h>

using namespace std;

int main() {
    IplImage *img;
    img = cvLoadImage("/home/foo/foo.png");
    CvScalar pixel = cvGet2D(img, 20, 30);
    printf(pixel)
    return 0
}

But in Python, on ctypes, I must represent IplImage, CvScalar structures and more, and I must use "pointers", to do this, for example: IplImage *img;.

But how? I tried:

from ctypes import *

cv = cdll.LoadLibrary("libcv.so")
highgui = cdll.LoadLibrary("libhighgui.so")

class IplRoi(Structure):
    _fields_ = [("coi", c_int),
                ("height", c_int),
                ("ptr", c_char_p),
                ("width", c_int),
               开发者_如何学JAVA ("xOffset", c_int),
                ("yOffset", c_int)]

class IplImage(Structure):
    _fields_ = [("nChannels", c_int),
                ("depth", c_int),
                ("width", c_int),
                ("height", c_int),
                ("imageData", c_char_p),
                ("dataOrder", c_int),
                ("origin", c_int),
                ("widthStep", c_int),
                ("imageSize", c_int),
                (IplRoi(), c_char_p),
                ("imageDataOrigin", c_char_p),
                ("align", c_int)]

image = IplImage(highgui.cvLoadImage("/home/michael/connerie.jpg"))
image = byref(image)
cv.cvGet2D(image, 1, 1)

But I do not have the CvScalar structure (I do not kown how represent it), and I'm using bad pointers ctypes, and I have a "segfault" error.


In OpenCV 2.3, the CvScalar structure is a double[4] wrapped in a struct, and the other structure definitions shown in the question are are significantly different. Also, cvLoadImage has an iscolor argument with a default value in C++. This has to be set to one of the CV_LOAD_IMAGE_* constants when called with ctypes.

from ctypes import *

CV_LOAD_IMAGE_UNCHANGED = -1
CV_LOAD_IMAGE_GRAYSCALE = 0
CV_LOAD_IMAGE_COLOR = 1
CV_LOAD_IMAGE_ANYDEPTH = 2
CV_LOAD_IMAGE_ANYCOLOR = 4

CvArr = None

class CvScalar(Structure):
    _fields_ = [('val', c_double * 4)]  # e.g BGRA, see channelSeq

class IplRoi(Structure):
    _fields_ = [
      ('coi', c_int),
      ('xOffset', c_int),
      ('yOffset', c_int),
      ('width', c_int),
      ('height', c_int),
    ]

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', c_void_p),
      ('imageSize', c_int),
      ('imageData', POINTER(c_char)),
      ('widthStep', c_int),
      ('BorderMode', c_int * 4),
      ('BorderConst', c_int * 4),
      ('imageDataOrigin', POINTER(c_char)),
    ]

For testing I used the 2.3 OpenCV libs in the Debian repository and the following 4-channel PNG:

Pointer on ctypes to use OpenCV on Python 3.1

cv = CDLL('libopencv_core.so.2.3')
highgui = CDLL('libopencv_highgui.so.2.3')

highgui.cvLoadImage.restype = POINTER(IplImage)
highgui.cvLoadImage.argtypes = [c_char_p, c_int]

cv.cvGet2D.restype = CvScalar
cv.cvGet2D.argtypes = [POINTER(CvArr), c_int, c_int]

pimg = highgui.cvLoadImage(
    b'data/rgba8_trans.png', CV_LOAD_IMAGE_UNCHANGED)
pixsc = cv.cvGet2D(pimg, 30, 30)

img = pimg[0]
pix = tuple(pixsc.val)
print('width = %d, height = %d\n' % (img.width, img.height))
print('y=30, x=30')
print(*zip(img.channelSeq.decode(), pix))

Output:

width = 85, height = 62

y=30, x=30
('B', 128.0) ('G', 128.0) ('R', 64.0) ('A', 176.0)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜