-
Notifications
You must be signed in to change notification settings - Fork 8
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
Improve median filter #150
Conversation
Hi @cgohlke! Thanks for implementing this improvements for median filtering. The modifications helped improving a little bit more the execution times, since now it seems to be around 20% faster than Scipy's (compared to 10-15% faster from what is now in main).
This is something we can discuss if it makes sense to apply the same logic as the
I think it would be a good idea to have the input of @lmalacrida on this. I remember he once said to me it's better practice to first filter and then threshold. I tried first thresholding and then filtering and the result phasor has wider spread and doesn't look as nice (even with the current implementation which is This is an example result of first thresholding and then filtering: And this is first filtering and then thresholding where you can see it is more compact and fewer pixels lie outside the semicircle:
This can be a good idea to add to the docstring as a warning that once performed the filter you can't go back to the signal. Also maybe add a note in the |
OK, I reverted the changes to the tutorial since they are disputed.
This would need to be documented and tested. And it should be implemented for all code paths, not just one. The filter would no longer be independent for real and imag. The logic should also apply to the intensity (at least optionally). That would probably be better implemented in a separate function (?) I think it is easier to implement and document if the median filter is applied independently (as it is now). |
@bruno-pannunzio I agree that Filtering should be performed on the entire image array, regardless of thresholding or before it. This is how i believe was performed at SimFCS. |
And the scientific reason is? |
That's what |
I skimmed through the SimFCS source code. At least in some places, a minimum intensity threshold is applied as part of calculating phasor coordinates, that is before applying median filter. Phasor coordinates for intensities below threshold are set to zero, which are then included in the median filter (I presume). Other code paths in SimFCS might or might not do things differently. For comparison: PhasorPy does not apply any intensity threshold by default when calculating phasor coordinates and sets phasor coordinates with no intensity to NaN. The |
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.
Christoph I think it makes sense what you propose here and keep the workflow as it is now.
Lets keep it like this with the modifications proposed here, where everything is very well documented.
Description
This PR improves upon #147, simplifying the implementation and boosting performance of median filtering:
_quickselect
twice in_median
function for even-sized kernels.The functions are now merged into one
_median
function._apply_2d_median_filter
function nogil section._median_filter_2d
and_median_filter_nd
into one_median_filter
function._apply_2d_median_filter
to_median_filter_2d
.nan_mask
for real and imag to match Cython implementation.Move median filter after thresholding in introductory tutorial. That should be better practice now that the median filter correctly handles NaN, no? Added a note that "filtered coordinates can no longer be used to reconstruct the original signal" (is there a better phrasing? Should that be added to the function docstring?)Checklist