Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

mport java.util.*; import java.awt.*; import java.awt.event.*; import java.awt.i

ID: 3877705 • Letter: M

Question

mport java.util.*;

import java.awt.*;

import java.awt.event.*;

import java.awt.image.*;

import java.awt.geom.*;

import java.io.*;

import javax.imageio.*;

// Main class

public class ImageHistogram extends Frame implements ActionListener {

          BufferedImage input;

          int width, height;

          TextField texRad, texThres;

          ImageCanvas source, target;

          PlotCanvas plot;

          // Constructor

          public ImageHistogram(String name) {

                   super("Image Histogram");

                   // load image

                   try {

                             input =

ImageIO.read(newFile(name));

                   }

                   catch ( Exception ex ) {

                             ex.printStackTrace();

                   }

                   width = input.getWidth();

                   height = input.getHeight();

                   // prepare the panel for image canvas.

                   Panel main = new Panel();

                   source = new ImageCanvas(input);

                    plot = new PlotCanvas();

                   target = new ImageCanvas(input);

                   main.setLayout(new GridLayout(1, 3, 10, 10));

                   main.add(source);

                   main.add(plot);

                   main.add(target);

                   // prepare the panel for buttons.

                   Panel controls = new Panel();

                   Button button = new Button("Display Histogram");

                   button.addActionListener(this);

                   controls.add(button);

                   button = new Button("Histogram Stretch");

                   button.addActionListener(this);

                   controls.add(button);

                   controls.add(new Label("Cutoff fraction:"));

                   texThres = new TextField("10", 2);

                   controls.add(texThres);

                   button = new Button("Aggressive Stretch");

                   button.addActionListener(this);

                   controls.add(button);

                   button = new Button("Histogram Equalization");

                   button.addActionListener(this);

                   controls.add(button);

                   // add two panels

                   add("Center", main);

                   add("South", controls);

                   addWindowListener(new ExitListener());

                   setSize(width*2+400, height+100);

                   setVisible(true);

          }

          class ExitListener extends WindowAdapter {

                   public void windowClosing(WindowEvent e) {

                             System.exit(0);

                   }

          }

          // Action listener for button click events

          public void actionPerformed(ActionEvent e) {

                   //compute the average color for the image

                   if ( ((Button)e.getSource()).getLabel().equals("Display Histogram") ) {

                             float red=0, green=0, blue=0;

                             for ( int y=0, i=0 ; y<height ; y++ )

                                      for ( int x=0 ; x<width ; x++, i++ ) {

                                                Color clr = new Color(input.getRGB(x, y));

                                                red += clr.getRed();

                                                green += clr.getGreen();

                                         blue += clr.getBlue();

                                      }

                             red /= width * height;

                             green /= width * height;

                             blue /= width * height;

                             plot.setMeanColor(new Color((int)red,(int)green,(int)blue));

                   }

                  

          }

          public static void main(String[] args) {

                   new ImageHistogram(args.length==1 ? args[0] : "baboo.png");

          }

}

// Canvas for plotting histogram

class PlotCanvas extends Canvas {

          // lines for plotting axes and mean color locations

          LineSegment x_axis, y_axis;

          LineSegment red, green, blue;

          boolean showMean = false;

          public PlotCanvas() {

                   x_axis = new LineSegment(Color.BLACK, -10, 0, 256+10, 0);

                   y_axis = new LineSegment(Color.BLACK, 0, -10, 0, 200+10);

          }

          // set mean image color for plot

          public void setMeanColor(Color clr) {

                   red = new LineSegment(Color.RED, clr.getRed(), 0, clr.getRed(), 100);

                   green = new LineSegment(Color.GREEN, clr.getGreen(), 0, clr.getGreen(), 100);

                   blue = new LineSegment(Color.BLUE, clr.getBlue(), 0, clr.getBlue(), 100);

                   showMean = true;

                   repaint();

          }

          // redraw the canvas

          public void paint(Graphics g) {

                   // draw axis

                   int xoffset = (getWidth() - 256) / 2;

                   int yoffset = (getHeight() - 200) / 2;

                   x_axis.draw(g, xoffset, yoffset, getHeight());

                   y_axis.draw(g, xoffset, yoffset, getHeight());

                   if ( showMean ) {

                             red.draw(g, xoffset, yoffset, getHeight());

                             green.draw(g, xoffset, yoffset, getHeight());

                             blue.draw(g, xoffset, yoffset, getHeight());

                   }

          }

}

// LineSegment class defines line segments to be plotted

class LineSegment {

          // location and color of the line segment

          int x0, y0, x1, y1;

          Color color;

          // Constructor

          public LineSegment(Color clr, int x0, int y0, int x1, int y1) {

                   color = clr;

                   this.x0 = x0; this.x1 = x1;

                   this.y0 = y0; this.y1 = y1;

          }

          public void draw(Graphics g, int xoffset, int yoffset, int height) {

                   g.setColor(color);

                   g.drawLine(x0+xoffset, height-y0-yoffset, x1+xoffset, height-y1-yoffset);

          }

}

Also given the ImageCanvas.java:

import java.awt.*;

import java.awt.event.*;

import java.awt.image.*;

import java.io.*;

import javax.imageio.*;

// Canvas for image display

class ImageCanvas extends Canvas {

                BufferedImage image;

                // initialize the image and mouse control

                public ImageCanvas(BufferedImage input) {

                                image = input;

                                addMouseListener(new ClickListener());

                }

                // redraw the canvas

                public void paint(Graphics g) {

                                // draw boundary

                                g.setColor(Color.gray);

                                g.drawRect(0, 0, getWidth()-1, getHeight()-1);

                                // compute the offset of the image.

                                int xoffset = (getWidth() - image.getWidth()) / 2;

                                int yoffset = (getHeight() - image.getHeight()) / 2;

                                g.drawImage(image, xoffset, yoffset, this);

                }

                // change the image and redraw the canvas

                public void resetImage(Image input) {

                                image = new BufferedImage(input.getWidth(null), input.getHeight(null), BufferedImage.TYPE_INT_RGB);

                                Graphics2D g2D = image.createGraphics();

                                g2D.drawImage(input, 0, 0, null);

                                repaint();

                }

                // listen to mouse click

                class ClickListener extends MouseAdapter {

                                public void mouseClicked(MouseEvent e) {

                                                if ( e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON3 )

                                                                try {

                                                                                ImageIO.write(image, "png", new File("saved.png"));

                                                                } catch ( Exception ex ) {

                                                                                ex.printStackTrace();

                                                                }

                                }

                }

}

The output when ran is:

Create the code for each of the histogram stretch, aggressive stretch and histogram equalization buttons so when pressed the program applies each function to the image and displays the corresponding histogram. Can work for any image.

Image Histogram Display Histogram Histogram Stretch Cutoff fraction: 10 Aggressive Stretch Histogram Equalization

Explanation / Answer

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;

/**
* Image histogram equalization

*
*/

public class HistogramEQ {

private static BufferedImage original, equalized;

public static BufferedImage computeHistogramEQ(BufferedImage im){
return histogramEqualization(im);
}

private static void writeImage(String output) throws IOException {
File file = new File(output+".jpg");
ImageIO.write(equalized, "jpg", file);
}

private static BufferedImage histogramEqualization(BufferedImage original) {

int red;
int green;
int blue;
int alpha;
int newPixel = 0;

// Get the Lookup table for histogram equalization
ArrayList<int[]> histLUT = histogramEqualizationLUT(original);

BufferedImage histogramEQ = new BufferedImage(original.getWidth(), original.getHeight(), original.getType());

for(int i=0; i<original.getWidth(); i++) {
for(int j=0; j<original.getHeight(); j++) {

// Get pixels by R, G, B
alpha = new Color(original.getRGB (i, j)).getAlpha();
red = new Color(original.getRGB (i, j)).getRed();
green = new Color(original.getRGB (i, j)).getGreen();
blue = new Color(original.getRGB (i, j)).getBlue();

// Set new pixel values using the histogram lookup table
red = histLUT.get(0)[red];
green = histLUT.get(1)[green];
blue = histLUT.get(2)[blue];

// Return back to original format
newPixel = colorToRGB(alpha, red, green, blue);

// Write pixels into image
histogramEQ.setRGB(i, j, newPixel);

}
}

return histogramEQ;

}

// Get the histogram equalization lookup table for separate R, G, B channels
private static ArrayList<int[]> histogramEqualizationLUT(BufferedImage input) {

// Get an image histogram - calculated values by R, G, B channels
ArrayList<int[]> imageHist = imageHistogram(input);

// Create the lookup table
ArrayList<int[]> imageLUT = new ArrayList<int[]>();

// Fill the lookup table
int[] rhistogram = new int[256];
int[] ghistogram = new int[256];
int[] bhistogram = new int[256];

for(int i=0; i<rhistogram.length; i++) rhistogram[i] = 0;
for(int i=0; i<ghistogram.length; i++) ghistogram[i] = 0;
for(int i=0; i<bhistogram.length; i++) bhistogram[i] = 0;

long sumr = 0;
long sumg = 0;
long sumb = 0;

// Calculate the scale factor
float scale_factor = (float) (255.0 / (input.getWidth() * input.getHeight()));

for(int i=0; i<rhistogram.length; i++) {
sumr += imageHist.get(0)[i];
int valr = (int) (sumr * scale_factor);
if(valr > 255) {
rhistogram[i] = 255;
}
else rhistogram[i] = valr;

sumg += imageHist.get(1)[i];
int valg = (int) (sumg * scale_factor);
if(valg > 255) {
ghistogram[i] = 255;
}
else ghistogram[i] = valg;

sumb += imageHist.get(2)[i];
int valb = (int) (sumb * scale_factor);
if(valb > 255) {
bhistogram[i] = 255;
}
else bhistogram[i] = valb;
}

imageLUT.add(rhistogram);
imageLUT.add(ghistogram);
imageLUT.add(bhistogram);

return imageLUT;

}

// Return an ArrayList containing histogram values for separate R, G, B channels
public static ArrayList<int[]> imageHistogram(BufferedImage input) {

int[] rhistogram = new int[256];
int[] ghistogram = new int[256];
int[] bhistogram = new int[256];

for(int i=0; i<rhistogram.length; i++) rhistogram[i] = 0;
for(int i=0; i<ghistogram.length; i++) ghistogram[i] = 0;
for(int i=0; i<bhistogram.length; i++) bhistogram[i] = 0;

for(int i=0; i<input.getWidth(); i++) {
for(int j=0; j<input.getHeight(); j++) {

int red = new Color(input.getRGB (i, j)).getRed();
int green = new Color(input.getRGB (i, j)).getGreen();
int blue = new Color(input.getRGB (i, j)).getBlue();

// Increase the values of colors
rhistogram[red]++; ghistogram[green]++; bhistogram[blue]++;

}
}

ArrayList<int[]> hist = new ArrayList<int[]>();
hist.add(rhistogram);
hist.add(ghistogram);
hist.add(bhistogram);

return hist;

}

// Convert R, G, B, Alpha to standard 8 bit
private static int colorToRGB(int alpha, int red, int green, int blue) {

int newPixel = 0;
newPixel += alpha; newPixel = newPixel << 8;
newPixel += red; newPixel = newPixel << 8;
newPixel += green; newPixel = newPixel << 8;
newPixel += blue;

return newPixel;

}

}