4

いくつかのグレースケール画像を参照するためにcythonmemoryviewsを使用しています。私が書いたいくつかの画像処理コードでこれをうまく使用しました。ここで、いくつかのOpenCV関数を使用する必要があります。残念ながら、メモリビューを画像引数としてOpenCV関数に渡すことができないようです。コードはコンパイルされますが、実行されると、OpenCV関数呼び出しで「TypeError:is notanumpyarray」で停止します。

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を作成できます」

メモリビューをOpenCV関数に渡す方法、またはデータをコピーせずにメモリビューをnumpy配列に強制変換する方法についてのヘルプをいただければ幸いです。

4

1 に答える 1

5

Numpy/OpenCV はメモリビューを使用しませんが、レガシーの前駆体を使用します。ラッパー クラスを作成できます。

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 に答える