Передача представлений памяти Cython в функции OpenCV

Я использую представления памяти Cython для ссылки на некоторые изображения в градациях серого. Я успешно использовал это в некотором коде обработки изображений, который я написал. Теперь мне нужно использовать некоторые функции OpenCV. К сожалению, я вижу, что не могу передать просмотры памяти в качестве аргументов изображения функциям OpenCV. Код компилируется, но когда он выполняется, он останавливается на вызове функции OpenCV с "TypeError: не является пустым массивом"

Я могу преобразовать представление памяти обратно в массив с np.asarray(my_memoryview). Это работает, но копирует данные и работает медленно.

В документации по просмотру памяти они говорят о принуждении к numpy http://docs.cython.org/src/userguide/memoryviews.html, и мне кажется, что я должен быть в состоянии заставить представление памяти к numpy массив без копирования памяти. Однако, если я напишу:

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

это приводит к ошибке компиляции: "Может создавать только cython.array из указателя или массива"

Будем весьма благодарны за любую помощь в том, как передать представление памяти в функцию OpenCV или как принудительно преобразовать представление памяти в пустой массив без копирования данных!

1 ответ

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 имеет атрибуты, которые возвращают кортежи, подобные тем __array_interface__ требует.

Если это не так быстро, я бы сделал вывод, что ваше решение уже не копирует данные.

Другие вопросы по тегам