Java Gauss gaussianBlur(int[][] pixels, float sigma)

Here you can find the source of gaussianBlur(int[][] pixels, float sigma)

Description

gaussian Blur

License

Apache License

Declaration

public static void gaussianBlur(int[][] pixels, float sigma) 

Method Source Code

//package com.java2s;
/*/*from   w w w.  j ava2 s. co m*/
 * Copyright 2009-2012 Michael Tamm
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

public class Main {
    public static void gaussianBlur(int[][] pixels, float sigma) {
        int kernelSize = (int) Math.ceil(6 * sigma);
        if (kernelSize % 2 == 0) {
            ++kernelSize;
        }
        if (kernelSize < 3) {
            kernelSize = 3;
        }
        float[][] kernel = new float[kernelSize][kernelSize];
        int m = kernelSize / 2;
        double q = 2 * sigma * sigma;
        double f = 1 / (Math.PI * q);
        for (int x = 0; x < kernelSize; ++x) {
            int dx = x - m;
            for (int y = 0; y < kernelSize; ++y) {
                int dy = y - m;
                kernel[x][y] = (float) (f * Math.exp(-((dx * dx + dy * dy) / q)));
            }
        }
        applyConvolutionFilter(pixels, kernel);
    }

    public static void applyConvolutionFilter(int[][] pixels, float[][] kernel) {
        if (kernel == null) {
            throw new IllegalArgumentException("Method parameter kernel must not be null.");
        }
        int kernelSize = kernel.length;
        if (kernelSize % 2 == 0) {
            throw new IllegalArgumentException("Method parameter kernel must have odd size. (e.g. 3, 5, 7, ...)");
        }
        if (kernel[0].length != kernelSize) {
            throw new IllegalArgumentException(
                    "Method parameter kernel must have square dimensions. (e.g. 3x3, 5x5, 7x7, ...)");
        }
        if (pixels != null) {
            int w = pixels.length;
            if (w > 0) {
                int h = pixels[0].length;
                if (h > 0) {
                    int[][] r = new int[w][h];
                    int[][] g = new int[w][h];
                    int[][] b = new int[w][h];
                    int[][] a = splitIntoChannels(pixels, r, g, b);
                    if (a != null) {
                        applyConvolutionFilterToChannel(a, kernel);
                    }
                    applyConvolutionFilterToChannel(r, kernel);
                    applyConvolutionFilterToChannel(g, kernel);
                    applyConvolutionFilterToChannel(b, kernel);
                    if (a != null) {
                        combineChannels(a, r, g, b, pixels);
                    } else {
                        combineChannels(r, g, b, pixels);
                    }
                }
            }
        }
    }

    /**
     * If <code>pixels</code> has alpha channel, another <code>int[][]</code> array is allocated,
     * filled with the alpha values, and returned, otherwise <code>null</code> is returned.
     */
    public static int[][] splitIntoChannels(int[][] pixels, int[][] r, int[][] g, int[][] b) {
        int[][] a = null;
        int w = pixels.length;
        int h = pixels[0].length;
        for (int x = 0; x < w; ++x) {
            for (int y = 0; y < h; ++y) {
                int p = pixels[x][y];
                int alpha = p >>> 24;
                if (alpha > 0) {
                    if (a == null) {
                        a = new int[w][h];
                    }
                    a[x][y] = alpha;
                }
                r[x][y] = (p & 0xFF0000) >> 16;
                g[x][y] = (p & 0xFF00) >> 8;
                b[x][y] = (p & 0xFF);
            }
        }
        return a;
    }

    public static void applyConvolutionFilterToChannel(int[][] channel, float[][] kernel) {
        int w = channel.length;
        int h = channel[0].length;
        int kernelSize = kernel.length;
        int r = (kernelSize / 2);
        int xx, yy;
        float n, d;
        // for each column ...
        for (int x = 0; x < w; ++x) {
            // for each row ...
            for (int y = 0; y < h; ++y) {
                n = d = 0;
                // for each kernel column ...
                for (int i = 0; i < kernelSize; ++i) {
                    xx = x + (i - r);
                    if (0 <= xx && xx < w) {
                        // for each kernel row ...
                        for (int j = 0; j < kernelSize; ++j) {
                            yy = y + (j - r);
                            if (0 <= yy && yy < h) {
                                float k = kernel[i][j];
                                int oldValue = channel[xx][yy];
                                assert 0 <= oldValue && oldValue <= 255;
                                n += k * oldValue;
                                d += k;
                            }
                        }
                    }
                }
                int newValue = Math.round(n / d);
                assert 0 <= newValue && newValue <= 255;
                channel[x][y] = newValue;
            }
        }
    }

    public static void combineChannels(int[][] a, int[][] r, int[][] g, int[][] b, int[][] pixels) {
        int w = pixels.length;
        int h = pixels[0].length;
        for (int x = 0; x < w; ++x) {
            for (int y = 0; y < h; ++y) {
                pixels[x][y] = (a[x][y] << 24) | (r[x][y] << 16) | (g[x][y] << 8) | b[x][y];
            }
        }
    }

    public static void combineChannels(int[][] r, int[][] g, int[][] b, int[][] pixels) {
        int w = pixels.length;
        int h = pixels[0].length;
        for (int x = 0; x < w; ++x) {
            for (int y = 0; y < h; ++y) {
                pixels[x][y] = (r[x][y] << 16) | (g[x][y] << 8) | b[x][y];
            }
        }
    }
}

Related

  1. gaussian(double x, double sigma)
  2. gaussian(double[] d, double sigma, double mean)
  3. gaussian(double[][] A, double[] b)
  4. gaussian(float x, float mean, float sd)
  5. gaussian(int size, double sigma)
  6. gaussianDensity(double x, double mean, double standardDeviation)
  7. gaussianDerivative(double x)
  8. gaussianFilter(float[] weights, float sigma)
  9. gaussianIntegral(double x)