glichtner / pystackreg

A python extension for the automatic alignment of a source image or a stack (movie) to a target image/reference frame.
Other
80 stars 17 forks source link

Parallel image registration #14

Open akatav opened 3 years ago

akatav commented 3 years ago

Hi I have almost 17000 frames to be aligned. I am wondering if pystackreg can registersuch images (using first frame as reference, let's say) in parallel ? Thanks

glichtner commented 3 years ago

Hi,

that's not part of pystackreg itself but it is possible using e.g. multiprocessing.Pool. See also this issue that contains some example code. But be aware that if you load the whole movie (your 17k frames) into a numpy array and then start a pool, the whole array is pickled and copied to the processes of the pool, which might not be very efficient and it might be better to use some more advanced methods like described here. However I'm not actually sure if this will give significant performance gains over just using a Pool without these techniques, so I'd recommend just trying Pool out and see how much it speeds the registration.

It's definitively an interesting feature and I will consider adding it to a future release of pystackreg.

Hope that helps, Gregor

orena1 commented 3 years ago

for the case where ref is first image or mean it can be added here, https://github.com/glichtner/pystackreg/blob/28d4c625e8542cddae8c3e8b9ad85dce0ef46147/pystackreg/pystackreg.py#L416

I'll create a pull request.

orena1 commented 3 years ago

see here: https://github.com/glichtner/pystackreg/pull/17

kevinjohncutler commented 1 year ago

@orena1's pull request is a great start, not sure why it has not been merged yet. As demonstrated, 'mean' and 'first' are straightforward. For 'previous' to be parallelized, it might be as simple as finding a bunch of relative transforms in parallel and then concatenating them.

ckolluru commented 1 year ago

In terms of parallelizing the registration process, has anyone attempted to do this with dask? I have a large 3D stack and need to register the slices to each other.

Any starter code or examples would be appreciated.

camilo1729 commented 11 months ago

Hello,

Would it be possible for the library to free the GIL?

My code does a heavy use of register_stack to compute the transformation matrices:

    sr = StackReg(StackReg.TRANSLATION)
    # Align each frame at the previous one
    tmats_float = sr.register_stack(image3D, reference='previous')    

I wan to use Threads to apply the rester_stack to different inputs in parallel but It run almost sequentially due to the GIL and a multiprocessing approach consumes a lot of extra memory.

So, I performed the following modification:

--- a/src/pymain.cpp
+++ b/src/pymain.cpp
@@ -184,9 +184,10 @@ PyObject *turbogreg_register(PyObject *self, PyObject *args) {
   double *img_ref = (double *)PyArray_DATA(ref_array);
   double *img_mov = (double *)PyArray_DATA(mov_array);

+  Py_BEGIN_ALLOW_THREADS
   registerImg(img_ref, img_mov, (Transformation)tf, Ny_ref, Nx_ref,
               rm); // width and height (Nx/Ny) have to be swapped!
-
+  Py_END_ALLOW_THREADS

And It worked, I can use multiple threads. I still don't know to which function this trick could be applied, I'm only using 'register_stak'.

Let me know what you think

glichtner commented 11 months ago

Hi @camilo1729,

thanks for your suggestion. I have opened a PR (#33) with your suggested change (and it looks good), but I have to add an appropriate test case to make sure registration is performed as expected.

Will keep you updated (but feel free to suggest a test case yourself).