I am working on an assignment that asking us to Develop a program that perform averaging filter on a grayscale image with different filter sizes 3x3, 5x5...11x11
First I developed a matrix class in Java:
final public class Matrix {
    private final int M;             // number of rows
    private final int N;             // number of columns
    private final double[][] data;   // M-by-N array
    // create M-by-N matrix of 0's
    public Matrix(int M, int N) {
        this.M = M;
        this.N = N;
        data = new double[M][N];
    }
    // create matrix based on 2d array
    public Matrix(double [][] data) {
        M = data.length;
        N = data[0].length;
        this.data = new double[M][N];
        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
                    this.data[i][j] = data[i][j];
    }
     public static Matrix filter(int M, int N) {
        Matrix A = new Matrix(M, N);
        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
                A.data[i][j] = (1.0/9.0);
        return A;
    }
    // copy constructor
    private Matrix(Matrix A) { this(A.data); }
    // return C = A + B
    public Matrix plus(Matrix B) {
        Matrix A = this;
        if (B.M != A.M || B.N != A.N) throw new RuntimeException("Illegal matrix dimensions.");
        Matrix C = new Matrix(M, N);
        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
                C.data[i][j] = A.data[i][j] + B.data[i][j];
        return C;
    }
// return C = A - B
    public Matrix minus(Matrix B) {
        Matrix A = this;
        if (B.M != A.M || B.N != A.N) throw new RuntimeException("Illegal matrix dimensions.");
        Matrix C = new Matrix(M, N);
        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
                C.data[i][j] = A.data[i][j] - B.data[i][j];
        return C;
    }
    public boolean eq(Matrix B) {
        Matrix A = this;
        if (B.M != A.M || B.N != A.N) throw new RuntimeException("Illegal matrix dimensions.");
        for (int i = 0; i < M; i++)
            for (int j = 0; j < N; j++)
                if (A.data[i][j] != B.data[i][j]) return false;
        return true;
    }
    // return C = A * B
    public Matrix multiply(Matrix B) {
        Matrix A = this;
        if (A.N != B.M) throw new RuntimeException("Illegal matrix dimensions.");
        Matrix C = new Matrix(A.M, B.N);
        for (int i = 0; i < C.M; i++)
            for (int j = 0; j < C.N; j++)
                for (int k = 0; k < A.N; k++)
                    C.data[i][j] +=  (A.data[i][k] * B.data[k][j]);
        return C;
    }
    public double average (){
        double sum=0.0;
        for (int i = 0; i < M; i++) {
                        for (int j = 0; j < N; j++) {
                                sum = sum + data[i][j];
                        }
        }
        return sum;
    }
    public void show() {
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < N; j++) 
                System.out.printf("%9.4f ", data[i][j]);
            System.out.println();
        }
    }
}
Then I developed my Image filtering application as follows:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
 *
 * @author Yousra
 */
public class ImgfilterApplication {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        System.out.println("Please Enter Your Image Path Here ...");
        Scanner myscanner = new Scanner(System.in);
        String path = myscanner.next();
        BufferedImage img = getImage(path);
       int filtersize = 3;
       BufferedImage outimg = TDfilter(img, filtersize);
       JFrame frame = new JFrame();
       JLabel image = new JLabel(new ImageIcon("imageName.png"));
       frame.getContentPane().setLayout(new FlowLayout());
       frame.getContentPane().add(new JLabel(new ImageIcon(img)));
       frame.getContentPane().add(new JLabel(new ImageIcon(outimg)));
       frame.pack();
       frame.setVisible(true);
    }
    public static BufferedImage TDfilter (BufferedImage img, int filtersize){
        int w = img.getWidth();
        int h = img.getHeight();
        WritableRaster cr=img.getRaster();
        WritableRaster wr=img.copyData(null);
        double[][] imgarray = Img2D(img);
        double[][] x = new double[filtersize][filtersize];
        Matrix filter = Matrix.filter(filtersize, filtersize);
        filter.show();
        Matrix imgm = new Matrix(w,h);;
        Matrix result;
        for (int ii = 0; ii < w; ii++)
                for (int jj = 0; jj < h; jj++) {
                    for (int i = ii; i < filtersize + ii; i++) {
                        for (int j = jj; j < filtersize + jj; j++) {
                                if (i - filtersize / 2 < 0 || i - filtersize / 2  >= w || j- filtersize / 2  < 0 || j- filtersize / 2  >= h) {
                                    x[i-ii][j-jj] = 0;
                                   // imgm = new Matrix(x);
                                } else {
                                    x[i-ii][j-jj] = imgarray[i - filtersize / 2][j - filtersize / 2];
                                };
                        }
                    }
                    imgm = new Matrix(x);
                    result = imgm.multiply(filter);
                    double value = result.average();
                    wr.setSample(ii, jj, 0, value);
                }
        BufferedImage img2= new BufferedImage(w, h, img.getType());
        img2.setData(wr);
        return img2;    
    }
    public static double [][] Img2D(BufferedImage img) {
        int w = img.getWidth();
        int h = img.getHeight();
        double[][] imgarray = new double[w][h] ;
        Raster raster = img.getData();
        for (int i = 0; i < w; i++) {
            for (int j = 0; j < h; j++) {
                imgarray[i][j] = raster.getSample(i, j, 0);
            }
        }
        return imgarray;
    }
     public static BufferedImage getImage(String imageName) {
        try {
            File input = new File(imageName);
            BufferedImage image = ImageIO.read(input);
            return image;
        } catch (IOException ie) {
            System.out.println("Error:" + ie.getMessage());
        }
        return null;
    }
}
This suppose to make the image more blurry, yet it makes it blurry in parts and negative in others in a random pattern. Can You please help :(