Fast Gaussian blur#961
Conversation
radius meaning match graphicmagick, pixelmator other software and standard deviation from classic gaussian blur algorithm
this improves performance and readabillity
linear speed against any radius
libImaging/BoxBlur.c
Outdated
There was a problem hiding this comment.
Why the difference in structure between this one for(i=1...) and the next one for(i=0...)?
There was a problem hiding this comment.
Because imIn can't be used as source and target simultaneously at the first pass, because it is source image. But we can reuse imOut (this loop) and temp (next loop).
There was a problem hiding this comment.
Ah, got it. Might make sense to note that imOut is being used as scratch space.
|
Looking at the results for a synthetic image, 20 pixels wide, one white pixel in the middle: Blur as a function of radius. Individual numbers are the pixel values, last number is the total of all the pixel values. With perfect precision, it should be 255, since the area under a gaussian curve is 1. Quantization being what it is, it's not exact, especially when running into the edge. This looks reasonable to me with a couple caveats, which require further checking.
Blur as a function of number of passes: I'd say 3 or 4 passes is closest here, any more than that and there's some significant numerical instability. I'm guessing that it's a matter of iterating over the operations and squashing down to an 8 bit value between each pass. I suspect that to actually converge, we'd have to be using much more precision in the intermediate steps. |
fix code style for `!` fix spelling
actualize comments
There was a problem hiding this comment.
Convert to ppm, since png can be not available.
There is no "middle" pixel in 20 px wide image :) That is why result is not symmetric for large radius.
In fact there is not a radius, this is σ, normal distribution. And result is correct with tolerance is 1.
Again, this is because your image is not symmetric. This is result for 21 width image: There is no shift at all. And this if you'll continue blur incrementing: The shift is gone away right at R=11. It appear because of passes and that fact what we assume pixels outside the image has same color as nearest. So after first pass with radius 10 we have something like this: At next pass we assume that all pixels on the left is 0, while all pixels at the right is 13.
Number of passes is even not a part of public api. N=3 already gives good gaussian approximation. Pixels value which we are seeing is rounded values. When we get 12.49, it'll be rounded to 12, while 12.51 will be rounded to 13. Of course on each pass error is collected. More passes = more error. But I want to notice what result is really good. There is only very small difference for N between 3 and 19. |
|
Ok, I don't know what I was seeing thinking that the distribution was fat-tailed. I think I may have been looking at a cdf or similar, rather than the pdf. I should have been more clear about the iterations -- I'm not seeing that as an issue, just confirmation that 3 iterations is pretty near optimal, and that the behavior gets worse after that. |
|
I finally got my mac mini back up and running and managed to run the bigendian tests. There's definitely endianess issues. I think what might work is to iterate through the |
|
This works on bigendian machines: wiredfool@712fc5b . It's not cleaned up, and I haven't checked to see if it runs on little endian ones yet. |
|
As assignment of dword is faster (at least at x86), I think we should make a macro with two implementations. |
|
Fair enough. |
|
Given this: #977 (comment), what do you want to do with the endianness bug here? |
|
Looking at the documentation portion of this, for now, notes on the ImageFilter calls should be enough. We should also document the ImageOps functions, and generally prefer them for any multichannel image. (since the filters split the images, run each of the channels through the filter, and then recombine. That's extra work/memory over just running it on all channels at once). I'd say that the filters for Gaussian and USM should probably be deprecated for new code in favor of the ImageOPS version once we get the return types worked out there. |
resolve sharp endianness issues
|
@wiredfool I've fixed endianness in both blur and unsharp. Please, actualize checklist. |
|
Ok, will check. |
|
Ok, works on PPC now. |
|
🍸 |
|
Yes. It's been a long process. Good to get it in. |

No description provided.