2014-09-23 3 views
0

У меня есть функция C, которая управляет камерой, я пытаюсь отправить буфер изображения на Python через Ctypes, который будет использоваться в графическом интерфейсе.Pass C массив на python через ctypes

Я могу захватить буфер, но я застрял в основном, как заставить это работать, я полагаю, я мог бы смотреть в numpy-c api, но это выглядит очень запутанным.

До сих пор я попытался следующее:

Создайте массив С (я предполагаю, что это является ссылкой указатель), что-то вроде:

UINT16 * MyFunction() 
    { 

     ...grab image... and return Buffer 

     size = 2088 * 2080 * sizeof(UINT16); 
     array = (BYTE*) malloc(size); 
     API_Write_to_buffer(Buffer, 0, array, size); 

     API_Free_Buffer(Buffer); 


     return array; 
    } 

Я могу попытаться получить возврат массива в Python:

Data = MyFunction() 
array = (c_ubyte * size).from_address(addressof(Data.contents)) 

где MyFunction() выглядит следующим образом:

def MyFunction(): 

    MyFunction= lib.MyFunction 
    MyFunction.restype = POINTER(c_ubyte) 
    img_arr = MyFunction() 
    return img_arr 

Другой вариант заключается в строку читать строки с использованием указателей:

for(i=0;i<Width;i++) 
{ 
    Ptr = (UINT16*)(bufferPointer + i*bufferWidth); 
    for(j=0;j<Height;j++) 
    { 
    ... 
    } 
} 

UPDATE:

Оказывается, мне нужно присвоить указатель на мой массив, но это UInt16 в C. Когда Я пытаюсь получить массив в массив numpy, сбой python. я могу получить это как возврат из функции-оболочки:

def Grab(nframes): 

    Grab= 2112 * 2088 * 8 (size of frame width * height * pixelDepth) 
    Grab= lib.MyFunction 
    Grab.argtypes = [c_uint32] 
    Grab.restype = POINTER(c_uint16 * array_length) 
    r = Grab(nframes) 
    return r 

Вызова функции выглядит следующим образом:

Data = Grab(1) 
print Data 

Который возвращает это:

<__main__.LP_c_ushort_Array_4409856 object at 0x000000000436FE48> 
+0

Вы освободили массив, прежде чем возвращать его? Не могли бы вы получить недействительный адрес в этот момент? – Santa

+0

Действительно, это была типичная ошибка на этом посту, хороший улов. Но у меня нет этой проблемы в фактическом коде. Благодаря! – user2221667

+0

Что не работает? Какая ошибка вы получаете? Что вы пытаетесь сделать, что не знаете, как это сделать? Преобразование в массив c_ubyte выглядит корректно для меня. Из вопроса здесь неясно, в чем проблема, которая у вас есть. –

ответ

1

Допустит, у вас есть c_ubyte array img_buffer, и он имеет width и height, потому что это изображение. Я собираюсь предположить, что у вас это есть, потому что это похоже на ваш код.

гипсом для массива c_ubyte должен выглядеть примерно так:

img_buffer = (c_ubyte * (height * bytes_per_pixel) * 
     (width * bytes_per_pixel)).from_address(addressof(data.contents)) 

Вы можете использовать NumPy, чтобы преобразовать его в ndarray с помощью:

import numpy as np 

img = np.ndarray(buffer=img_buffer, dtype=np.uint16, shape=(width, height, 1)) 

После того как вы ndarray вы можете использовать PIL или matplotlib или OpenCV, чтобы показать его.

EDIT: пила, что ваше изображение 16-бит, поэтому я изменил тип данных.

+0

Я пробовал это, но получаю: TypeError: буфер слишком мал для запрошенного массива. – user2221667

+0

Тогда ваш рост, ширина или тип данных не соответствуют размеру буфера c_ubyte.Проверьте размер буфера и сравните его с тем, что вы ожидаете от своего изображения, и убедитесь, что они совпадают. – ballsatballsdotballs

Смежные вопросы