Effectively convert System.Single [,] to numpy array

Using Python 3.6 and Python for dotNET / pythonnet I was able to capture an array of images. It is of type System.Single [,]

I would like to convert this to a numpy array so that I can do something with it in Python. I configured a function to go through this array and converted it in different ways - but is there something smarter (and faster) I could use?

def MeasurementArrayToNumpy(TwoDArray):
    hBound = TwoDArray.GetUpperBound(0)
    vBound = TwoDArray.GetUpperBound(1)

    resultArray = np.zeros([hBound, vBound])

    for c in range(TwoDArray.GetUpperBound(0)):            
            for r in range(TwoDArray.GetUpperBound(1)):
                resultArray[c,r] = TwoDArray[c,r]
    return resultArray

      

+3


source to share


1 answer


@denfromufa is a very helpful link.

You are supposed to make a direct copy of the memory using Marshal.Copy or np.frombuffer. I was unable to get Marshal.Copy to work - some shenanigans have to use a 2D array with a marshal, and changed the contents of the array somehow, but the np.frombuffer version seems to work for me and reduces the time to complete to ~ 16000 for the array 3296 * 2471 (~ 25s → ~ 1.50ms). It's good enough for my purposes



This requires a few more imports, so I included them in the code snippet below

import ctypes
from System.Runtime.InteropServices import GCHandle, GCHandleType

def SingleToNumpyFromBuffer(TwoDArray):
    src_hndl = GCHandle.Alloc(TwoDArray, GCHandleType.Pinned)

    try:
        src_ptr = src_hndl.AddrOfPinnedObject().ToInt32()
        bufType = ctypes.c_float*len(TwoDArray)
        cbuf = bufType.from_address(src_ptr)
        resultArray = np.frombuffer(cbuf, dtype=cbuf._type_)
    finally:
        if src_hndl.IsAllocated: src_hndl.Free()
    return resultArray

      

+3


source







All Articles