2016-04-08 1 views
5

У нас есть библиотека ex-exisitng больших изображений, написанная на C/C++, с предварительно созданным типом изображения. Мы хотели бы связать его с Python. Мы знаем, как делать большинство вещей, используя SWIG, например, но мы хотели бы, чтобы наш интерфейс использовал NumPy вместо домашнего типа для хранения наших изображений.Лучший способ обернуть программу C для интерфейса Python с преобразованием между буфером данных в массиве C и NumPy?

Есть ли у кого-нибудь пример, как это сделать? В Интернете есть примеры, в которых интерфейс NumPy отображается в виде указателей. Как мы интерфейс NumPy к существующему типу C структуры, как этот:

typedef struct xvimage { 

    int nx, ny, nz, nt ; // dimensions 

    enum {PIX_UINT8, PIX_INT16, PIX_UINT16, PIX_INT32, PIX_FLOAT, PIX_DOUBLE} ; // type 

    void *data; 

} xvimage; 
+1

Добро пожаловать в StackOverflow! Я бы порекомендовал вам немного сузить вопрос, на что вы хотите получить ответ. –

ответ

0

Есть три основных способа:

  1. Копирование из вашего буфера изображения в массив NumPy и наоборот. При задании изображения C/C++ создайте массив NumPy и скопируйте данные, когда задан массив NumPy, создайте образ C/C++ и скопируйте данные.

  2. NumPy массив как обертка вокруг указателя данных C. Создайте массив NumPy, но с заданным указателем данных. Убедитесь, что изображение на C/C++, содержащее указатель данных, живет дольше, чем массив NumPy. Массив NumPy может жить короче, потому что в этом случае он не будет пытаться удалить данные.

  3. Буфер изображения C/C++ как обертка вокруг указателя массива NumPy. Создайте массив NumPy и извлеките указатель данных, а затем используйте его для manupilate массива NumPy на месте. Убедитесь, что массив NumPy живет достаточно долго, удерживая ссылку на Python.

Каждый из них может быть реализован в печатной карте SWIG.

В любом случае вам потребуется преобразование типа ваших типов в типы NumPy (NPY_UINT8, ..) и сохранение размеров изображения в npy_intp *.

Чтобы создать массив NumPy использовать PyArray_New или PyArray_SimpleNew или PyArray_SimpleNewFromData (Array API) и указать желаемые флаги, как Fortran стиле смежными или любой другой удобной для Вас. Вы можете указать свой собственный указатель данных PyArray_New и PyArray_SimpleNewFromData.

Возвращаемое значение является PyObject*, который смело может быть приведен к PyArrayObject* (или выполнить PyArray_Check раньше) и указатель данных извлекается PyArray_DATA (Array API), который возвращает void *, который вы можете бросить к нужному типу. Затем вы можете либо выполнить копию, либо сделать модификацию на месте по своему усмотрению.

Чтобы добавить ссылку на объект Python использовать Py_INCREF и Py_DECREF (doc) в случае, если вы хотите, чтобы избежать для массива NumPy преждевременно удаляется.

Если вы хотите получать уведомления о том, что объект Python собирается собирать мусор, используйте слабую ссылку через PyWeakref_NewRef (doc).