4

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

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

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

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

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

任何有关如何将 memoryview 传递给 OpenCV 函数,或如何在不复制数据的情况下将 memoryview 强制转换为 numpy 数组的帮助将不胜感激!

4

1 回答 1

5

Numpy/OpenCV 不需要 memoryviews,但它需要一个legacy 前驱。您可以创建一个包装类:

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 对象具有返回__array_interface__所需元组的属性。

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

于 2012-10-22T21:47:11.123 回答