Had a lot of fun implementing the Huang histogram approach and the constant time approach by hand in a prior role.

Never saw the binary tree approach. And this article, being written in summer of 22, missed out on the 2D wavelet approach published later on that year.

Not the OP but have a look at the scikit-images and other scikit packages. Lots of different algorithms implemented. Also of course the OpenCV library.

I honestly recommend just writing them by hand in a simple language (C or Python), without relying on third party dependencies (just load an uncompressed grayscale image to use as your input).

OpenCV implementations of this stuff will be complex with lots of architecture specific optimizations. They will also have tons of branches for different image formats — you can keep things very simple by just using single channel uncompressed grayscale. The Huang histogram and Perrault/Hebert constant time papers are very approachable. They have pseudocode and visualizations. They’re not that tricky. You can sit down in a day and implement them without much headache.

Median filtering with large kernel can be pretty ugly as it gives pixels who are far away the same weight. I prefer weighting them (for example with a gaussian) and using a weighted histogram, use the weighted median value (interpolated between two values). It gives a result even more interesting (for some uses) than a simple gaussian blur and you can also configure the weights to make it edge preserving like a bilateral blur but better

There is also no way to split up the median computation

What does this mean here ? Seems like we could have a rolling window by adding and subtracting pixels on the way. I’ve coded this before, although it’s not O(1) like the algorithm described at the end

For example if you are using an "ordinary" kernel where there is some sliding window of nonzero weights contributing to the output value, you can compute the two dimensions in separate passes.

I've found sorting-network-based filters to be faster than these methods up to size 25x25 or so. It has worse computational complexity, but filters up to that size covers a lot of ground in practice. See Figure 10 in https://andrew.adams.pub/fast_median_filters.pdf

Had a lot of fun implementing the Huang histogram approach and the constant time approach by hand in a prior role.

Never saw the binary tree approach. And this article, being written in summer of 22, missed out on the 2D wavelet approach published later on that year.

https://cgenglab.github.io/en/publication/sigga22_wmatrix_me....

I'm interested to learn more about these algorithms. Are there any sources you'd recommend?

Not the OP but have a look at the scikit-images and other scikit packages. Lots of different algorithms implemented. Also of course the OpenCV library.

I honestly recommend just writing them by hand in a simple language (C or Python), without relying on third party dependencies (just load an uncompressed grayscale image to use as your input).

OpenCV implementations of this stuff will be complex with lots of architecture specific optimizations. They will also have tons of branches for different image formats — you can keep things very simple by just using single channel uncompressed grayscale. The Huang histogram and Perrault/Hebert constant time papers are very approachable. They have pseudocode and visualizations. They’re not that tricky. You can sit down in a day and implement them without much headache.

Median filtering with large kernel can be pretty ugly as it gives pixels who are far away the same weight. I prefer weighting them (for example with a gaussian) and using a weighted histogram, use the weighted median value (interpolated between two values). It gives a result even more interesting (for some uses) than a simple gaussian blur and you can also configure the weights to make it edge preserving like a bilateral blur but better

What does this mean here ? Seems like we could have a rolling window by adding and subtracting pixels on the way. I’ve coded this before, although it’s not O(1) like the algorithm described at the endFor example if you are using an "ordinary" kernel where there is some sliding window of nonzero weights contributing to the output value, you can compute the two dimensions in separate passes.

You could combine the benefits of a median with the benefits of an average.

Eg you could kick out the top and bottom quartile, and take the average of what's left.

I've found sorting-network-based filters to be faster than these methods up to size 25x25 or so. It has worse computational complexity, but filters up to that size covers a lot of ground in practice. See Figure 10 in https://andrew.adams.pub/fast_median_filters.pdf

I hacked together an SVG-filter based median filter once. It was horribly inefficient, but it worked: https://codepen.io/mullany/pen/ngJWvx

For a second, I thought median filtering was going to be about riding motorcycles down the median of a road to filter through traffic.....

Does anyone know of a pytorch differentiable filter that does the same thing?

Kornia has one

https://kornia.readthedocs.io/en/stable/filters.html#kornia....

I don't think you'll have much luck differentiating the median operator