0

I have a C function which controls a camera, I am trying to send the image buffer to Python via Ctypes to be used in a GUI.

I can grab the buffer, but I am stuck on basically how to get this to work, I suppose I could look into numpy-c api but it looks very confusing.

Thus far I have tried the following:

Create a C array (I guess it is by pointer reference), something like:

   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;
    }   

I can try to get the return of the array in python:

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

where MyFunction() looks like the following:

def MyFunction():

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

Another option is to read line by line using pointers:

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

UPDATE:

It turns out I need to assign a pointer to my array, but it is a UINT16 in C. When I try to get the array into a numpy array, python crashes. I can get this as a return from the wrapper function:

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

Calling the function looks like this:

Data = Grab(1)
print Data

Which returns this:

<__main__.LP_c_ushort_Array_4409856 object at 0x000000000436FE48>
3
  • You freed the array before returning it? Wouldn't you get an invalid address at that point, then? Commented Sep 23, 2014 at 19:09
  • Indeed, that was a typing mistake on this post, good catch. But I do not have that problem in the actual code. Thanks! Commented Sep 23, 2014 at 19:13
  • What does not work? What is the error you get? What are you trying to do that you don't know how to do? The conversion to c_ubyte array looks correct to me. From the question here, it is unclear what is the problem that you have. Commented Sep 23, 2014 at 19:40

1 Answer 1

1

Lets say you have a c_ubyte array img_buffer and it has a width and a height, because it is an image. I'm going to assume that you have that already because it looks like you do in your code.

Your cast for the c_ubyte array should look something like this:

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

You can use numpy to convert it to an ndarray using:

import numpy as np

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

Once you have the ndarray you can use PIL or matplotlib or OpenCV to show it.

EDIT: Saw that your image is 16-bit so I changed the data type.

Sign up to request clarification or add additional context in comments.

2 Comments

I tried that, but I get : TypeError: buffer is too small for requested array.
Then your height, width, or data_type doesn't match your c_ubyte buffer size. Check your buffer size and compare it to what you expect for your image and ensure that they match.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.