diff options
| author | Jules Laplace <jules@okfoc.us> | 2015-04-22 05:21:11 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2015-04-22 05:21:11 -0400 |
| commit | bef106de9fa827d983fa319cecdf688c2822efb9 (patch) | |
| tree | d336ec726e97e5c19cb0dfee56d2bf4912d0db29 /smartblur.java | |
smartblur convolution experiment
Diffstat (limited to 'smartblur.java')
| -rw-r--r-- | smartblur.java | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/smartblur.java b/smartblur.java new file mode 100644 index 0000000..f62f2fa --- /dev/null +++ b/smartblur.java @@ -0,0 +1,162 @@ +import java.awt.image.Kernel; +import java.awt.image.BufferedImage; +import java.awt.image.ConvolveOp; +import java.awt.Graphics; + +// http://asserttrue.blogspot.ca/2010/08/implementing-smart-blur-in-java.html +public class SmartBlurFilter +{ + double SENSITIVITY = 10; + int REGION_SIZE = 5; + + float[] kernelArray = + { + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1 + }; + + Kernel kernel = new Kernel(9, 9, normalizeKernel(kernelArray)); + + float[] normalizeKernel(float[] ar) + { + int n = 0; + for (int i = 0; i < ar.length; i++) + n += ar[i]; + for (int i = 0; i < ar.length; i++) + ar[i] /= n; + + return ar; + } + + public double lerp(double a,double b, double amt) + { + return a + amt * (b - a); + } + + public double getLerpAmount(double a, double cutoff) + { + if (a > cutoff) + return 1.0; + + return a / cutoff; + } + + public double rmsError(int[] pixels) + { + double ave = 0; + + for (int i = 0; i < pixels.length; i++) + ave += (pixels[ i ] >> 8) & 255; + + ave /= pixels.length; + + double diff = 0; + double accumulator = 0; + + for (int i = 0; i < pixels.length; i++) + { + diff = ((pixels[ i ] >> 8) & 255) - ave; + diff *= diff; + accumulator += diff; + } + + double rms = accumulator / pixels.length; + + rms = Math.sqrt(rms); + + return rms; + } + + int[] getSample(BufferedImage image, int x, int y, int size) + { + int[] pixels = {}; + + try + { + BufferedImage subimage = image.getSubimage(x,y, size, size); + pixels = subimage.getRGB(0,0,size,size,null,0,size); + } + catch(Exception e) + { + // will arrive here if we requested + // pixels outside the image bounds + } + return pixels; + } + + int lerpPixel(int oldpixel, int newpixel, double amt) + { + int oldRed = (oldpixel >> 16) & 255; + int newRed = (newpixel >> 16) & 255; + int red = (int) lerp((double)oldRed, (double)newRed, amt) & 255; + + int oldGreen = (oldpixel >> 8) & 255; + int newGreen = (newpixel >> 8) & 255; + int green = (int) lerp((double)oldGreen, (double)newGreen, amt) & 255; + + int oldBlue = oldpixel & 255; + int newBlue = newpixel & 255; + int blue = (int) lerp((double)oldBlue, (double)newBlue, amt) & 255; + + return (red << 16) | (green << 8) | blue; + } + + int[] blurImage(BufferedImage image, int[] orig, int[] blur, double sensitivity) + { + int newPixel = 0; + double amt = 0; + int size = REGION_SIZE; + + for (int i = 0; i < orig.length; i++) + { + int w = image.getWidth(); + int[] pix = getSample(image, i % w, i / w, size); + if (pix.length == 0) + continue; + + amt = getLerpAmount (rmsError(pix), sensitivity); + newPixel = lerpPixel(blur[ i ], orig[ i ], amt); + orig[ i ] = newPixel; + } + + return orig; + } + + + public BufferedImage filter(BufferedImage image) + { + ConvolveOp convolver = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); + + // clone image into target + BufferedImage target = new BufferedImage(image.getWidth(), image.getHeight(), image.getType()); + Graphics g = target.createGraphics(); + g.drawImage(image, 0, 0, null); + g.dispose(); + + int w = target.getWidth(); + int h = target.getHeight(); + + // get source pixels + int[] pixels = image.getRGB(0, 0, w, h, null, 0, w); + + // blur the cloned image + target = convolver.filter(target, image); + + // get the blurred pixels + int[] blurryPixels = target.getRGB(0, 0, w, h, null, 0, w); + + // go thru the image and interpolate values + pixels = blurImage(image, pixels, blurryPixels, SENSITIVITY); + + // replace original pixels with new ones + image.setRGB(0, 0, w, h, pixels, 0, w); + return image; + } +}
\ No newline at end of file |
