pystackreg
pystackreg copied to clipboard
Parallel image registration
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
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
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.
see here: https://github.com/glichtner/pystackreg/pull/17
@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.
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.
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
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).