2012-10-10 3 views
4

일부 회색 음영 이미지를 참조하기 위해 cython memoryviews를 사용하고 있습니다. 필자가 작성한 일부 이미지 처리 코드에서이를 성공적으로 사용했습니다. 이제 OpenCV 기능을 사용해야합니다. 불행히도 OpenCV 함수에 memoryviews를 이미지 인수로 전달할 수 없음을 알았습니다. 코드가 컴파일되지만 실행하면 OpenCV 함수 호출에서 "TypeError : numpy 배열이 아닙니다"와 함께 중지됩니다.OpenCV 함수에 cython memoryviews 전달

np.asarray (my_memoryview)를 사용하여 memoryview를 numpy 배열로 다시 변환 할 수 있습니다. 이 작동하지만 데이터를 복사하고 느립니다.

memoryview 설명서에서 numpy에 강요에 대해 이야기합니다. http://docs.cython.org/src/userguide/memoryviews.html#coercion-to-numpy 마치 메모리를 복사하지 않고 numview 배열에 메모리 뷰를 강제 변환 할 수있는 것처럼 보입니다. 그러나, 나는 쓰기 :

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

은 컴파일 오류가 발생합니다

OpenCV의 기능에 memoryview를 전달하는 방법에 어떤 도움, 또는 "단지 포인터 나 배열에서 cython.array을 만들 수" 어떻게 데이터를 복사하지 않고 numpy 배열에 memoryview를 강요하는 것은 매우 감사하겠습니다!

+0

어디서 원래 메모리 뷰를 얻었습니까? – r3m0t

+0

다음과 같이 numpy 배열 (openCV 이미지)에서 원래 메모리 뷰를 얻습니다. cdef np.uint8_t [:, :: 1] im2 = im 그러면 im2를 조작하고 기본적으로 서브 윈도우 (메모리 뷰)를 추출합니다. 그렇다면 cv2.matchTemplate에 전달합니다. 메모리 뷰를 직접 전달할 수 없기 때문에 현재 np.asarray (서브 윈도우)를 사용하고 있습니다. 내가 nump 문서 예제에 강요를 missinterpreted했을 수 있습니다, 그 예제에서 그들은 memoryview에 대한 포인터를 캐스팅하고 내가하고있는 동일한 np.asarray와 numpy 배열로 변환합니다. 그러나 강제 또는 복사 중인지 확실하지 않습니다. – martinako

답변

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__이 요구하는 것과 같은 튜플을 반환 특성을가집니다.

이것이 더 빠르지 않다면, 나는 당신의 솔루션이 이미 데이터를 복사하고 있지 않다는 것을 추측 할 것입니다.

+0

답변 해 주셔서 감사합니다. 난 당신이 제안 무엇을 시도하고 싶습니다하지만 난 당신의 코드를 컴파일 할 때 나는 통과 할 수 얻을 오류, 오류가'데이터에 = PyLong_FromVoidPtr ( my_memoryview.view.buf)' 내가 를 얻을'memoryview_opencv .pyx : 13 : 51 : 임시 파이썬 객체를 비 - 숫자가 아닌 비 파이썬 유형으로 변환하기' 이것을 해결하는 방법을 알고 있습니까? – martinako

+0

martinako 님, 중간 변수 my_memoryview_c (다른 Cython 유형이 있음)가 작동합니다. 내 대답을 조금 편집했는데 작동하기 전에 컴퓨터가 망가졌습니다. '읽을 수있는 버퍼 인터페이스'가 있다면, 주석 처리 된'typestr'를 사용해야 할 수도 있습니다. – r3m0t

+0

안녕하세요, 지금은 빌드하지만, OpenCVMemoryView를 cv2.matchTemplate에 전달할 때 런타임 오류가 발생합니다.'TypeError : 은 numpy 배열이 아닙니다. '주석이 달린 typestr를 시도했지만 아무런 차이가 없습니다. – martinako