-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add version of Image::getArray (and Mesh::getField) that only wraps data in numpy.ndarray rather than copying it #903
Comments
I just want to reiterate: this is probably not difficult and there could be very significant performance benefits. |
One use case is in the ShapeCohortGenPackage. In the generate_images() function in CohortGenUtils.py we take a segmentation, add a foreground and background with noise and blur the boundary to create a synthetic image. As a very simple test:
The output image should look the same as the input image but brighter. |
Keep in mind that if the numpy image is reallocated, say by changing the image size, it will no longer point to this memory (though the memory can be passed without passing ownership thereof, so it wouldn't introduce a crash potential). |
|
It's inefficient to copy an image's data in order to modify it with numpy and then reconstruct the image from the copied data (which probably copies it again). Instead, we can use this version with a capsule, except our capsule will not free the data when the numpy array goes out of scope since it's actually owned by the itk image.
This will make operations like the ones @jadie1 is performing much more efficient.
The seeming danger is the image being free'd and the numpy array trying to be used afterwards. So add a note to the function's documentation (to be defined as a lambda in ShapeworksPython.cpp).
From https://stackoverflow.com/questions/44659924/returning-numpy-arrays-via-pybind11
Note: This topic seems to confirm that itkImage::GetBufferPointer() does not copy the data: http://itk-insight-users.2283740.n2.nabble.com/ITK-users-ITK-Image-data-pointer-and-GPU-algorithms-td7589655.html
(Our current Image.toArray function does copy the data because that's the default behavior of the py::array constructor.)
Lots of info here useful to ensure data is deallocated when no longer needed: pybind/pybind11#1042
For example, it may be possible to use a simpler version, or to ensure data is not deleted until it goes out of scope in both C++ and Python. But since it's the itkImage's data, I'm not sure we'd have that control, so the simplest method might be to just not delete it, recognizing the potential risk on the Python side, and gaining the (significant) advantage of not copying back and forth.
This is probably not difficult, but I want to make sure we have a use case, so @jadie1 when you have time please add one to this issue. I'll implement it and throw it back over the fence for you to test. Thanks!
The text was updated successfully, but these errors were encountered: