-
Notifications
You must be signed in to change notification settings - Fork 369
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
Fix and add more options for non-optical flow register_ROIs; add feature to interpolate shifts based on patch locations in tile_and_correct #1444
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice work; do you mind cherry-picking the CI diffs from dev into this so tests can run?
caiman/motion_correction.py
Outdated
|
||
overlaps: tuple | ||
dimension of the patch | ||
overlap of patches (except possibly last one) in each dimension |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "except" part probably could use some explanation
Thanks! Can you be more specific - this should already be applied on top of dev. Are the CI changes in another branch? |
They should be in dev now; the problem is github's test infrastructure runs on your branch, not on what the dev branch would look like with your changes, so your branch being slightly out of date means the fixes are not effective. (rebasing would also work) |
Sorry would you mind telling me the specific commits you're talking about? As far as I can tell it's not behind flatironinstitute/dev. |
You're right. Looks like it broke upstream again. I'd like to merge this sooner and I'll have to look at the CI issue separately; I may need to reach out if it fails tests when they're working again. |
Are you ready for this to be merged now? |
I think it's up to you - I have been using it fine on my own branch. I wasn't able to get the demo tests working locally. I think it might be worth considering whether that interp_shifts_precisely option should be made into a real parameter - I would like to try using it to motion correct a movie at some point and see how it differs in terms of runtime and results. |
Let me see if the CI stuff is quick to fix. |
I just updated dev with a CI fix. |
…ype of input to cv.remap
67eb627
to
5c50e9f
Compare
Passes CI now, which is good; you still sound uncertain on whether you want this style of parameterisation or something else; make a call on that. We could merge this now, or if you want to rework some of the approach first that's also fine. |
OK, I tried motion correcting a long recording using interp_shifts_precisely. It made very little difference in the result, but it also didn't take much longer than normal, so I decided it's fine to add it as a new parameter (false by default, though). |
Actually, before merging, I just want to update apply_shifts_movie to use the new option as well. |
Not done yet, but when going through the code, I noticed a couple of things that seem to be bugs:
I'm going to assume these are actually bugs and fix them, but just a warning that if they're not I may be breaking something... |
cf05c4a
to
8a6d62f
Compare
OK, now I'm done with this. |
Should be all set now. |
Description
The problem
This addresses an issue I raised on the slack where the non-optical flow path of
register_ROIs
seems to have a mistake. It works by finding piecewise-rigid shifts between the two template images usingtile_and_correct
. Then, the matrix of shifts for each patch should be interpolated into a shift map of the same size as the image, to be used forcv2.remap
. However, these lines:CaImAn/caiman/base/rois.py
Lines 434 to 435 in bb55800
actually just repeat the entries of the matrix, in C-order, to fill in a new matrix of the requested shape, so the result will make no sense.
I used this test script: https://gist.github.com/ethanbb/12e6efa6ba31733f769c0b6c3f82ee98 to confirm that it gives weirdly warped results. Note that with the current code, setting
use_opt_flow
to False always gives an error, because thetile_and_correct
call setsshifts_opencv=True
, but this path does not return a value forxy_grid
, which is then used on the next line. So, for testing, I temporarily changedshifts_opencv
to False. Here are the results with the current code:In this case, it seems like we should just stick with optical flow. However, one thing I've observed and which motivated this inquiry is that optical flow struggles with larger shifts. Here is what happens when I increase the amount of non-rigid offset from 2 to 6:
Clearly, neither method is satisfactory.
Solving the general problem
Up-sampling shifts from patches does not only happen in
register_ROIs
. It occurs in multiple places in the motion correction code as well, but for this PR I just focused ontile_and_correct
andtile_and_correct_3d
. In these functions, resizing occurs for both the OpenCV (to full image size in order to usecv2.remap
) and non-OpenCV (to an Nx denser grid, depending onupsample_factor_grid
) methods. I realized when looking into this that it was not being done in the most rigorously correct way; it is implemented as a standard image resize, but the patch centers at the borders do not coincide with the borders of the new image, and these centers may not even be evenly spaced (at the lower and right edges).This imprecision may not usually be a big deal for large images, and may be necessary in order to correct whole movies efficiently. However, I thought that at least for the case of aligning just 2 images, I may as well add a way to up-sample more precisely by interpolating using the exact location of each patch. Thus, I added
get_patch_centers
andinterpolate_shifts
to interpolate shifts to/from specific pixel locations using scipy (I don't think OpenCV has an easy way of doing this). I also added the flaginterp_shifts_precisely
for the two tile_and_correct functions to enable this method. I haven't tested it on a full motion correction run yet, but it could potentially be promoted to a new parameter in the future.Finally, I used the same functions to do the interpolation correctly within
register_ROIs
. Using the newget_patch_centers
function, thexy_grid
output is unnecessary, so it works with either setting ofshifts_opencv
. I also setinterp_shifts_precisely
to True here, and it seems to be working fine.Results with
nr_offset = 2
:And with
nr_offset = 6
:Other changes to register_ROIs
align_options
to allow overriding default motion correction params (fortile_and_correct
method only). This is necessary, among other things, to increasemax_deviation_rigid
from 2 in order to deal with cases like the second example above.max_deviation_rigid = 0
)Type of change
Has your PR been tested?
Aside from the test script mentioned above,
caimanmanager test
passes. I'm trying to run demotest, having some issues with it but I'll update if I can get it working.