1

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 :(

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Yousra Marwan
  • 89
  • 1
  • 2
  • 11
  • 1
    1) For better help sooner, post an [SSCCE](http://sscce.org/). 2) One way to get image(s) for an example is to hot-link to the images seen in [this answer](http://stackoverflow.com/a/19209651/418556). – Andrew Thompson Oct 25 '13 at 07:56

2 Answers2

1

I didn't bother digging through you code. Better post pseudo representation of you algorithm.

Well to address the issue with negative parts of image, this happens when there is an number overflow; e.g. you are trying to make pixel with value 256 depending on used data structures and language, it might happen that the byte roll over 256 and instead the pixel gets value 0.

You need to check that all values you are assigning to image are in range <0-255> for 8-bit grayscale.

jnovacho
  • 2,825
  • 6
  • 27
  • 44
  • 1
    It took me a while reading that before it occurred to me it deserved +1 for the closing sentence. .. I mean as well as other things.. – Andrew Thompson Oct 25 '13 at 09:05
1

I figured out what was wrong. I made the filter a matrix and I multiplied the filter matrix by the image filter then I got the average of the resulting matrix. To correct this is to pass the filter over the whole image and multiply each pixel by the number that is inside the filter then add it all up.

Yousra Marwan
  • 89
  • 1
  • 2
  • 11