opencv - 将 cython 内存 View 传递给 OpenCV 函数

标签 opencv numpy cython memoryview

我正在使用 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/

相关文章:

android - 如何将位图图像转换为mat图像

Python TypeError : list indices must be integers or slices, 不是元组

python-2.7 - 对整个笔记本应用舍入设置

python - 安装 Cython/Statsmodels

python - 可以加快查找字符串邻域的代码吗?

c++ - OpenCV 中的圆圈和手部检测

java - opencv 3.1.0 absdiff 不起作用

python - 在三个数组中找到最近的三个 x,y 点

python - 字符串的快速串联

Python OpenCV : Returning cvBridge Image from ROS