我正在使用 cython memoryviews 来引用一些灰度图像。我已经在我编写的一些图像处理代码中成功地使用了它。现在,我需要使用一些 OpenCV 函数。 不幸的是,我发现我无法将内存 View 作为图像参数传递给 OpenCV 函数。代码可以编译,但是当它运行时,它会在 OpenCV 函数调用处停止,并出现“TypeError: is not a numpy array”
我可以使用 np.asarray(my_memoryview) 将内存 View 转换回 numpy 数组。这可行,但它复制数据并且速度很慢。
在 memoryview 文档中,他们讨论了对 numpy 的强制转换 http://docs.cython.org/src/userguide/memoryviews.html#coercion-to-numpy 似乎我应该能够在不复制内存的情况下将 memoryview 强制转换为 numpy 数组。但是,如果我写:
im = np.asarray(<np.uint8_t[:, :]> my_memoryview)
它会导致编译错误:“Can only create cython.array from pointer or array”
任何有关如何将 memoryview 传递给 OpenCV 函数,或如何在不复制数据的情况下将 memoryview 强制转换为 numpy 数组的帮助,我们将不胜感激!
最佳答案
Numpy/OpenCV 不采用内存 View ,但它采用 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__
要求的那样。
如果这没有更快,我会推断您的解决方案已经没有复制数据。
关于opencv - 将 cython 内存 View 传递给 OpenCV 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12826946/