将cython memoryviews传递给OpenCV函数

时间:2012-10-10 19:32:06

标签: opencv numpy cython memoryview

我正在使用cython memoryviews来引用一些灰度图像。我已经在我编写的一些图像处理代码中成功使用了它。现在,我需要使用一些OpenCV函数。 不幸的是,我发现我无法将内存视图作为图像参数传递给OpenCV函数。代码编译,但是当它运行时,它会在OpenCV函数调用时停止,并出现“TypeError:is a numpy array”

我可以使用np.asarray(my_memoryview)将memoryview转换回numpy数组。这有效,但它复制数据并且速度很慢。

在memoryview文档中,他们谈论强制到numpy http://docs.cython.org/src/userguide/memoryviews.html#coercion-to-numpy 似乎我应该能够将内存视图强制转换为numpy数组,而无需复制内存。但是,如果我写:

im = np.asarray(<np.uint8_t[:, :]> my_memoryview)

导致编译错误:“只能从指针或数组创建cython.array”

有关如何将内存视图传递给OpenCV函数的任何帮助,或者如何将内存视图强制转换为numpy数组而不复制数据将非常感激!

1 个答案:

答案 0 :(得分:5)

Numpy / OpenCV不会占用内存视图,但需要legacy precursor。您可以创建一个包装类:

from cython.view cimport memoryview

cdef extern from "Python.h":
    object PyLong_FromVoidPtr(void *p)

cdef class OpenCVMemoryView:
    cdef object arr
    cdef object underlying_object
    def __init__(OpenCVMemoryView self, np.uint8_t[:, :] my_memoryview):
        self.underlying_object = my_memoryview # prevents GC of my_memoryview
        cdef memoryview my_memoryview_c = my_memoryview
        self.arr = dict(version=3,
            typestr='<u1', #typestr=np.uint8,
            data=(PyLong_FromVoidPtr(<void*>my_memoryview_c.view.buf), False),
            strides=my_memoryview.strides,
            shape=my_memoryview.shape)
    def __array_interface__(self):
        return self.arr

Cython memoryview object具有返回元组的属性,如__array_interface__所需。

如果这不是更快,我会推断你的解决方案已经没有复制数据了。