7 Replies - 2900 Views - Last Post: 22 February 2010 - 07:43 AM Rate Topic: -----

#1 AllboutJava  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 19-February 10

Processing Image "Averaging"

Posted 19 February 2010 - 02:03 PM

Hi guys,

Im trying to compute an average of two images say; image1.jpg & image2.jpg and obtaining result of "average of image1 and image2" -- g(x,y) = (f1(x,y) + f2(x,y)) / 2

Can anyone please advise me, which part it did wrong?

Would be appreciated thanks.

import java.io.*;             //these 6 sentences are for including packages to be used in the program
import java.awt.image.*;
import java.awt.color.ColorSpace;
import javax.swing.*;
import com.pearsoneduc.ip.io.*;
import com.pearsoneduc.ip.gui.*;

public class AverageXImage extends JFrame {

    private BufferedImage sourceImage;   // image to be average
    //private BufferedImage sourceImage2;
    private ImageView[] views;           // image display components
    

    public AverageXImage(String imageFile) throws IOException, ImageDecoderException {
        //call the constructor of the "super class" which in this case is JFrame
        //this can be seen at the beginning of the class after the keyword extends
        //the parameter passed to the constructor will be diplayed in the JFrame
        //window title bar
        super("xAverage: " + imageFile);
        readImage(imageFile);    //call readImage() method (see details later)

        views = new ImageView[2];      //instantiate 2  display windows, this is the place that you can
        //change, to suit your own need. eg, if need more windows
        views[0] = new ImageView(sourceImage);     //display the source image in the first window
   
		views[1] = new ImageView(average(sourceImage [0]); //display the output image after
    
        

        JTabbedPane tabbedPane = new JTabbedPane();      //instantiate a TabbedPane
        tabbedPane.add(new JScrollPane(views[0]), "input");   //put label that associate to the first display
        //window
        tabbedPane.add(new JScrollPane(views[1]), "xAverage");

        getContentPane().add(tabbedPane);
        addWindowListener(new WindowMonitor());
    }
  /*
   * Read an image from a named file, converting
   * to greyscale if necessary.
   */
    public void readImage(String filename)
    throws IOException, ImageDecoderException {
        ImageDecoder input = ImageFile.createImageDecoder(filename);   //read data from a file
        sourceImage = input.decodeAsBufferedImage();    //decode the data into BufferedImage
        //represenation
        if (sourceImage.getType() != BufferedImage.TYPE_BYTE_GRAY) {  //check image type
            System.err.println("Converting colour image to greyscale image...");
            ColorConvertOp op = new ColorConvertOp(     //convert colour image to grey level
                    ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
            BufferedImage greyImage = op.filter(sourceImage, null);
            sourceImage = greyImage;
        }
    }
  /*
   * Compute and return a averaged version of the source image
   */
    public BufferedImage average(BufferedImage[] imgArray) {
        //instantiate a new image object

        int n = imgArray.length;
        int w = n*imgArray[0].getWidth(); // assume that htey have
        int h = n*imgArray[0].getHeight(); // the same demensions

        BufferedImage AvgImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);

        //step through the original image pixel by pixel (from up to down
        //and set each pixel of the new AvgImage
        //to an exact copy of the original
        for (int y = 0; y < h; ++y)
            for (int x = 0; x < w; ++x){
                //here is to save the original image
                float sum = 0.0f;
                for (int i = 0; i < n; ++i)
                    sum += imgArray[i].getRaster().getSample(x, y, 0);
                AvgImage.getRaster().setSample(x, y, 0, Math.round(sum/2));
            }
        return AvgImage;
    }
    public static void main(String[] argv) {
        if (argv.length > 0) {

            try {
                JFrame frame = new AverageXImage(argv[0]);

                frame.pack();
                frame.setVisible(true);
            } catch (Exception e) {
                System.err.println(e);
                System.exit(0);
            }
        } else {
            System.err.println("usage: java enlarge <imagefile> ");
            System.exit(1);
        }
    }
}


Is This A Good Question/Topic? 0
  • +

Replies To: Processing Image "Averaging"

#2 Guest_javabie*


Reputation:

Re: Processing Image "Averaging"

Posted 19 February 2010 - 02:48 PM

I am not sure I understood your question properly....

Quote

Im trying to compute an average of two images say; image1.jpg & image2.jpg and obtaining result of "average of image1 and image2" -- g(x,y) = (f1(x,y) + f2(x,y)) / 2


so you have

f1 - an image
f2 - another image

also i am assuming dimensions of f1 and f2 are same...?...

so you want a new image g,

g(x,y) = (f1(x,y) + f2(x,y))/2

more specifically,

g(0,0) = (f1(0,0) + f2(0,0))/2
.
.
.
..until we reach the full length and width.

by looking at your code,
i don't see you reading in 2 different image.

 for (int y = 0; y < h; ++y)
            for (int x = 0; x < w; ++x){
                //here is to save the original image
                float sum = 0.0f;
                for (int i = 0; i < n; ++i)
                    sum += imgArray[i].getRaster().getSample(x, y, 0);
                AvgImage.getRaster().setSample(x, y, 0, Math.round(sum/2));
            }
        return AvgImage;



hmm.. look at the code below...

             for (int i = 0; i < n; ++i)
                    sum += imgArray[i].getRaster().getSample(x, y, 0);

what you are doing is..

wen the loop finishes, it will add all the elements and if you really
need to find the average of that then u r supposed to divide by n.
but this is not wat u wanted...

          for (int i = 0; i < n; ++i)
          {
                   sum = imgArray[i].getRaster().getSample(x, y, 0) + imgArray[i].getRaster().getSample(x, y, 0); 
                  AvgImage.getRaster().setSample(x, y, 0, Math.round(sum/2));
          }  




i hope i didn't confuse you... and i hope i am not confused either.. lol.

goodluck
Was This Post Helpful? 0

#3 AllboutJava  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 19-February 10

Re: Processing Image "Averaging"

Posted 21 February 2010 - 11:21 AM

View Postjavabie, on 19 February 2010 - 01:48 PM, said:

I am not sure I understood your question properly....

Quote

Im trying to compute an average of two images say; image1.jpg & image2.jpg and obtaining result of "average of image1 and image2" -- g(x,y) = (f1(x,y) + f2(x,y)) / 2


so you have

f1 - an image
f2 - another image

also i am assuming dimensions of f1 and f2 are same...?...

so you want a new image g,

g(x,y) = (f1(x,y) + f2(x,y))/2

more specifically,

g(0,0) = (f1(0,0) + f2(0,0))/2
.
.
.
..until we reach the full length and width.

by looking at your code,
i don't see you reading in 2 different image.

 for (int y = 0; y < h; ++y)
            for (int x = 0; x < w; ++x){
                //here is to save the original image
                float sum = 0.0f;
                for (int i = 0; i < n; ++i)
                    sum += imgArray[i].getRaster().getSample(x, y, 0);
                AvgImage.getRaster().setSample(x, y, 0, Math.round(sum/2));
            }
        return AvgImage;



hmm.. look at the code below...

             for (int i = 0; i < n; ++i)
                    sum += imgArray[i].getRaster().getSample(x, y, 0);

what you are doing is..

wen the loop finishes, it will add all the elements and if you really
need to find the average of that then u r supposed to divide by n.
but this is not wat u wanted...

          for (int i = 0; i < n; ++i)
          {
                   sum = imgArray[i].getRaster().getSample(x, y, 0) + imgArray[i].getRaster().getSample(x, y, 0); 
                  AvgImage.getRaster().setSample(x, y, 0, Math.round(sum/2));
          }  




i hope i didn't confuse you... and i hope i am not confused either.. lol.

goodluck


Thanks for ur idea; well actually it supposed to be:

 for (int y = 0; y < h; ++y)
            for (int x = 0; x < w; ++x){
                //here is to save the original image
                float sum = 0.0f;
                for (int i = 0; i < n; ++i)
                    sum += imgArray[i].getRaster().getSample(x, y, 0);
                AvgImage.getRaster().setSample(x, y, 0, Math.round(sum/n));



Notice that, it divided by 'n' - I think I have to change some of the method in readImage as I am reading two images instead of one?

Any idea?

Thanks
Was This Post Helpful? 0
  • +
  • -

#4 javabie  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 117
  • Joined: 12-February 10

Re: Processing Image "Averaging"

Posted 21 February 2010 - 12:33 PM

I love to compile and run your program but i never purchased the book to get the packages you are using. So, I can't run your program.

since you need to read 2 different images... i would change your read image code to following...
	public BufferedImage readImage(String filename)
	throws IOException, ImageDecoderException 
	{
		ImageDecoder input = ImageFile.createImageDecoder(filename);   //read data from a file
		sourceImage = input.decodeAsBufferedImage();    //decode the data into BufferedImage
		//represenation
		if (sourceImage.getType() != BufferedImage.TYPE_BYTE_GRAY) 
		{  //check image type
			System.err.println("Converting colour image to greyscale image...");
			ColorConvertOp op = new ColorConvertOp(     //convert colour image to grey level
					ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
			return op.filter(sourceImage, null);
		}
		return sourceImage;
	}

notice that read image returns a BufferedImage.

you defined variables like so...
	private BufferedImage sourceImage;   // image to be average
	private BufferedImage sourceImage2; //notice this used to be a commment



so in your AverageXImage function.. you could do this...
public AverageXImage(String imageFile, String anotherImageFile) throws IOException, ImageDecoderException {
    
		super("xAverage: " + imageFile);
		
                sourceImage = readImage(imageFile);    //call readImage() method (see details later)
                sourceImage2 = readImage(anotherImageFile); //read the 2nd image....

		views = new ImageView[2];      //instantiate 2  display windows, this is the place that you can
 //rest of your code
}



but i have a feeling your both of the source images are same.. in that case you could keep your original AverageXImage method
but inside it...
        sourceImage = readImage(imageFile);
        sourceImage2 = sourceImage;


do the above if your source image are same. otherwise go with the other choice i mentioned earlier at the top.

now coming to your average method...
first time i read your code and posted some comments about dividing by n instead of 2... and all those,
i didn't try to understand what you were trying to do with your code, i said all those things with your
description of the problem and quick overlook of your code didn't do what you were tryin to do.
Now I looked each line of ur code and tried to understand what you were tryin to do with it.
You were correct by dividing by 2 because that n was supposed to be 2.
So here is the code below.. that i think how should your average method looks like.
		public BufferedImage average(BufferedImage img1, BufferedImage img2) {
		//instantiate a new image object

		int w = img1.getWidth(); // u dunt need to multiply by n
		int h = img1.getHeight(); //becuz, if u did.. you are doubling the width and height. also n is the array size
                 //since i am not using any array....

		BufferedImage AvgImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);

		for (int y = 0; y < h; ++y)
		{
			for (int x = 0; x < w; ++x)
			{
				float sum = img1.getRaster().getSampleFloat(x, y, 0) +
				            img2.getRaster().getSample(x, y, 0);
				AvgImage.getRaster().setSample(x, y, 0, sum/2); //why divide by 2? because 2 images are used. e.g  (X+Y)/2.
			}
		}
		return AvgImage;
	}



finally...

	views[1] = new ImageView(average(sourceImage)); //display the output image after


you might want to add 1 more view to show the 2nd source image.. cuz you got x+y = z ;
x - first image
y - second image
z - averaged image.


again, i can't compile and see if the program works or even run. If it works, great. If it doesn't.. I will try my best to help you with wat I know.

Also, before modifying your code with what ever I said above, make backup of your code so you could go back if I pointed you in the wrong direction.
Was This Post Helpful? 0
  • +
  • -

#5 AllboutJava  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 19-February 10

Re: Processing Image "Averaging"

Posted 21 February 2010 - 01:59 PM

View Postjavabie, on 21 February 2010 - 11:33 AM, said:

I love to compile and run your program but i never purchased the book to get the packages you are using. So, I can't run your program.

since you need to read 2 different images... i would change your read image code to following...
	public BufferedImage readImage(String filename)
	throws IOException, ImageDecoderException 
	{
		ImageDecoder input = ImageFile.createImageDecoder(filename);   //read data from a file
		sourceImage = input.decodeAsBufferedImage();    //decode the data into BufferedImage
		//represenation
		if (sourceImage.getType() != BufferedImage.TYPE_BYTE_GRAY) 
		{  //check image type
			System.err.println("Converting colour image to greyscale image...");
			ColorConvertOp op = new ColorConvertOp(     //convert colour image to grey level
					ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
			return op.filter(sourceImage, null);
		}
		return sourceImage;
	}

notice that read image returns a BufferedImage.

you defined variables like so...
	private BufferedImage sourceImage;   // image to be average
	private BufferedImage sourceImage2; //notice this used to be a commment



so in your AverageXImage function.. you could do this...
public AverageXImage(String imageFile, String anotherImageFile) throws IOException, ImageDecoderException {
    
		super("xAverage: " + imageFile);
		
                sourceImage = readImage(imageFile);    //call readImage() method (see details later)
                sourceImage2 = readImage(anotherImageFile); //read the 2nd image....

		views = new ImageView[2];      //instantiate 2  display windows, this is the place that you can
 //rest of your code
}



but i have a feeling your both of the source images are same.. in that case you could keep your original AverageXImage method
but inside it...
        sourceImage = readImage(imageFile);
        sourceImage2 = sourceImage;


do the above if your source image are same. otherwise go with the other choice i mentioned earlier at the top.

now coming to your average method...
first time i read your code and posted some comments about dividing by n instead of 2... and all those,
i didn't try to understand what you were trying to do with your code, i said all those things with your
description of the problem and quick overlook of your code didn't do what you were tryin to do.
Now I looked each line of ur code and tried to understand what you were tryin to do with it.
You were correct by dividing by 2 because that n was supposed to be 2.
So here is the code below.. that i think how should your average method looks like.
		public BufferedImage average(BufferedImage img1, BufferedImage img2) {
		//instantiate a new image object

		int w = img1.getWidth(); // u dunt need to multiply by n
		int h = img1.getHeight(); //becuz, if u did.. you are doubling the width and height. also n is the array size
                 //since i am not using any array....

		BufferedImage AvgImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);

		for (int y = 0; y < h; ++y)
		{
			for (int x = 0; x < w; ++x)
			{
				float sum = img1.getRaster().getSampleFloat(x, y, 0) +
				            img2.getRaster().getSample(x, y, 0);
				AvgImage.getRaster().setSample(x, y, 0, sum/2); //why divide by 2? because 2 images are used. e.g  (X+Y)/2.
			}
		}
		return AvgImage;
	}



finally...

	views[1] = new ImageView(average(sourceImage)); //display the output image after


you might want to add 1 more view to show the 2nd source image.. cuz you got x+y = z ;
x - first image
y - second image
z - averaged image.


again, i can't compile and see if the program works or even run. If it works, great. If it doesn't.. I will try my best to help you with wat I know.

Also, before modifying your code with what ever I said above, make backup of your code so you could go back if I pointed you in the wrong direction.


Thanks for ur reply - Well Im just eclipse to run the program. I think the it will run by the look of it - will try; by the way, you could try to run them if you like to see the output ^_^

Could you do the same method with substraction? Just wonder....
Cheers
Was This Post Helpful? 0
  • +
  • -

#6 javabie  Icon User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 117
  • Joined: 12-February 10

Re: Processing Image "Averaging"

Posted 21 February 2010 - 09:47 PM

I joined this D.I.C to help and get help so any time.

I also have eclipse but since you are using special packages such as..
import com.pearsoneduc.ip.io.*;
import com.pearsoneduc.ip.gui.*;

which is not standard that comes with java, it is from Pearson. I guess you bought a book and they gave you those packages in a cd.
Unless I have those, I can't run.

I am not sure what you mean by subtracting...
unless you mean sumthing like:
  for (int y = 0; y < h; ++y)
                {
                        for (int x = 0; x < w; ++x)
                        {
                                float subtractedValue = img1.getRaster().getSampleFloat(x, y, 0) -
                                            img2.getRaster().getSample(x, y, 0);
                                AvgImage.getRaster().setSample(x, y, 0, Math.abs(subtractedValue));
                        }
                }



That should work, I don't know what the output image would look like.
But, I think you might need to get the absolute value of the difference.. (you should know why..) or maybe you dunt need to take it (I could be wrong.)

Try your ideas with the program. It's easy, you change few lines and you could see the output right away.

Have fun.
I hope, what ever I said in earlier post works.
Was This Post Helpful? 0
  • +
  • -

#7 Guest_AllinJava*


Reputation:

Re: Processing Image "Averaging"

Posted 22 February 2010 - 07:42 AM

View Postjavabie, on 21 February 2010 - 08:47 PM, said:

I joined this D.I.C to help and get help so any time.

I also have eclipse but since you are using special packages such as..
import com.pearsoneduc.ip.io.*;
import com.pearsoneduc.ip.gui.*;

which is not standard that comes with java, it is from Pearson. I guess you bought a book and they gave you those packages in a cd.
Unless I have those, I can't run.

I am not sure what you mean by subtracting...
unless you mean sumthing like:
  for (int y = 0; y < h; ++y)
                {
                        for (int x = 0; x < w; ++x)
                        {
                                float subtractedValue = img1.getRaster().getSampleFloat(x, y, 0) -
                                            img2.getRaster().getSample(x, y, 0);
                                AvgImage.getRaster().setSample(x, y, 0, Math.abs(subtractedValue));
                        }
                }



That should work, I don't know what the output image would look like.
But, I think you might need to get the absolute value of the difference.. (you should know why..) or maybe you dunt need to take it (I could be wrong.)

Try your ideas with the program. It's easy, you change few lines and you could see the output right away.

Have fun.
I hope, what ever I said in earlier post works.

Was This Post Helpful? 0

#8 Guest_AllboutJava*


Reputation:

Re: Processing Image "Averaging"

Posted 22 February 2010 - 07:43 AM

View PostAllinJava, on 22 February 2010 - 06:42 AM, said:

View Postjavabie, on 21 February 2010 - 08:47 PM, said:

I joined this D.I.C to help and get help so any time.

I also have eclipse but since you are using special packages such as..
import com.pearsoneduc.ip.io.*;
import com.pearsoneduc.ip.gui.*;

which is not standard that comes with java, it is from Pearson. I guess you bought a book and they gave you those packages in a cd.
Unless I have those, I can't run.

I am not sure what you mean by subtracting...
unless you mean sumthing like:
  for (int y = 0; y < h; ++y)
                {
                        for (int x = 0; x < w; ++x)
                        {
                                float subtractedValue = img1.getRaster().getSampleFloat(x, y, 0) -
                                            img2.getRaster().getSample(x, y, 0);
                                AvgImage.getRaster().setSample(x, y, 0, Math.abs(subtractedValue));
                        }
                }



That should work, I don't know what the output image would look like.
But, I think you might need to get the absolute value of the difference.. (you should know why..) or maybe you dunt need to take it (I could be wrong.)

Try your ideas with the program. It's easy, you change few lines and you could see the output right away.

Have fun.
I hope, what ever I said in earlier post works.

Was This Post Helpful? 0

Page 1 of 1