【问题标题】:Pointer on ctypes to use OpenCV on Python 3.1在 Python 3.1 上使用 OpenCV 的 ctypes 指针
【发布时间】:2010-10-10 10:01:52
【问题描述】:

我尝试通过 ctypes 在 Python 3.1 上使用 OpenCV,但我不知道如何表示指针。例如,如果我想加载图像并打印她的第一个像素的内容,我将用 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
}

但在 Python 中,在 ctypes 上,我必须表示 IplImage、CvScalar 结构等,而且我必须使用“指针”来执行此操作,例如:IplImage *img;

但是怎么做呢?我试过了:

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),
                ("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)

但我没有 CvScalar 结构(我不知道如何表示它),并且我使用了错误的指针 ctypes,并且出现“段错误”错误。

【问题讨论】:

    标签: python opencv python-3.x ctypes


    【解决方案1】:

    在 OpenCV 2.3 中,CvScalar 结构是包装在结构中的double[4],问题中显示的其他结构定义有很大不同。此外,cvLoadImage 有一个 iscolor 参数,在 C++ 中具有默认值。使用 ctypes 调用时,必须将其设置为 CV_LOAD_IMAGE_* 常量之一。

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

    为了测试,我使用了 Debian repository 中的 2.3 OpenCV 库和以下 4 通道 PNG:

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

    输出:

    width = 85, height = 62
    
    y=30, x=30
    ('B', 128.0) ('G', 128.0) ('R', 64.0) ('A', 176.0)
    

    【讨论】:

      猜你喜欢
      • 2014-01-23
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      相关资源
      最近更新 更多