I have a 2D image, which I want to lowpass filter, with these constraints / quality metrics:
- I can not "add" light to the image, so each pixel in the result should be <= the corresponding pixel in the input.
- The lowpass cutoff frequency should be a parameter, to experiment with
- Applying this filter repeatedly should not change the result in a significant way.
- The time it takes to run this algorithm (5 minutes for a 5MPix image seems reasonable)
- Minimizing the amount of light that is filtered away.
Below are some approaches I have tried, together with their shortcomings:
Gaussian filter like normal, then pull the result down to comply with constraint 1. This complies very well with the first 3 points, but reduces a lot more light than necessary.
Fitting "upwards" parabolas through the "low" points and "downwards" parabolas between them to smooth out. This works great in 1D, but applying it first horizontally, then vertically produces bad results in 2D. It takes a lot longer, but not too long for my application. However, repeatably applying this filter will drastically change the result. If the (1D) input is a perfect "downward" parabola (which should not be filtered at all), it will be replaced by 2 "upward" parabolas sitting at the start/end.
Using some other form of 2D "basic" functions and linear solving to find the optimal parameters. This is an idea only currently, not implemented / tested yet.
My domain of experience in signal processing is almost exclusively image processing, so I hope to find alternatives to this problem with the input of experts active in other areas of signal processing.
update 2011/08/18
Based on the current reactions, I decided to make things a bit more clear by adding graphs of a typical input and the results of the 3 approaches I described originally + the suggestions I received so far. For easy comparison, I used just 1D filtering in these examples.
Input data:
Gaussian filter + bring it down to comply with requirement (1).
You can see that bringing it down results in unnecessary light reductions on the right hand side.
Parabolas
As far as I am concerned, this is pretty much excellent, sadly it does not translate perfectly into 2D by applying first horizontal, then vertical. In this case, you also see I can evaluate the fitted parabolas in floating point resolution, which is a small benefit, but not absolutely required.
Grayscale erosion
Based on the suggestion from rwong, I tried grayscale erosion. I used a structuring element with the same parabolic shape as my "fitted" parabolas. The result is almost exactly the same, so this looks promising. However, there are still a few problems:
1. My structuring element was not "big enough" (although it was already 801 pixels wide)
1. I only have "upwards" parabolas, no "downward parabolas to smooth the transition from one parabola to the next.
Median filtering
Only included for completeness, it is not really what I want.
raw data
I pasted the raw input data + the various python commands onto pastebin, so you can experiment with the same data too.
http://pastebin.com/ASnJ9M0p