CS 335 Graphics and Multimedia Image Manipulation
Image Manipulation Independent pixels: image subtraction image averaging grey level mapping thresholding Neighborhoods of pixels: filtering, convolution, etc. Geometric operations on pixels: rotation, scale, warp
Manipulating Images in Java Image class: provides simple file/network read difficult to access individual pixels easy to make into an icon BufferedImage class: simple file/network read easy access to pixels can get graphics context
Treating Pixels Independently Image Arithmetic: Change the values of pixels based on a rule which uses information from that pixel only Addition/averaging: average multiple images over time Subtraction: detect changes over time Negative: invert the color map
Image Addition
Image Subtraction
Image Subtraction
Pixel-wise Logical Operations AND XOR OR
Grey Level Mapping Remap the intensity distribution of pixels Enhances contrast between features and structures Target image grey levels Original image grey levels
Grey Level Mapping Mapping curve can be arbitrary Example: first interval is compressed, second interval is stretched Target image grey levels Original image grey levels
Grey Level Mapping Example: monotonically increasing curve (not line) Target image grey levels Original image grey levels
Grey Level Mapping Example: non-monotonically increasing curve Target image grey levels Original image grey levels
Thresholding Pixel modification based on a specified threshold criterion: newvalue = x if oldpixel < y otherwise threshold Goal: suppress values below threshold, enhance values above
Image Histograms Histogram: frequency distribution of grey levels or colors in that image Can be a strong indicator for enhancement schemes: contrast enhancement, thresholding Histograms are not unique: many images can produce the same histogram Histogram equalization: enhancement based on the histogram
Frequency Distribution Horizontal axis: grey level value Vertical axis: count 512x512 0 255
The Normalized Histogram Divide each bin by the total pixel count Bin total becomes normalized to 1
Modifying the Histogram Grey level modification will affect the histogram: 0 255 0 255
Using the Histogram for Thresholding Threshold value can be calculated from the shape of the histogram: 0 255
Localized Histograms Can compute histogram for a Region of Interest (ROI) Compute total number of pixels in ROI Compute pixel intensity distribution within ROI Can apply enhancements more locally
Histogram Equalization (Flattening) Evenly distribute intensity values across dynamic range Resulting histogram is flat Can be a complex grey level mapping: is usually easier to specify as a histogram operation
Original Image Histogram-equalized Image Intensity map to accomplish the flattening operation
Examples
Examples
Photo of the Year 2002
Take-home Exercises Ex 6.7: 1, 3, pp 132, Efford
/************************************************************ Sample: Program to load a JPEG image and display it in a JFRAME ************************************************************/ import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import javax.swing.*; import javax.swing.event.*; import com.sun.image.codec.jpeg.*; public class MyImageViewer extends JFrame { // Instance variables private BufferedImage image; // the image private MyImageObj view; // a component for display private JLabel infolabel; // a label for the GUI private int x, y; private boolean firstdrag=true;
// The Constructor for this extension of the JFrame class public MyImageViewer (String filename) throws IOException { super(filename); // Load an image from a file image = readimage(filename); // Create components to display image and pixel information view = new MyImageObj(image); infolabel = new JLabel(); infolabel.addmouselistener( new MouseAdapter() { public void mousepressed (MouseEvent event) { view.repaint(); );
// Listen for mouse events to show (x,y) coordinates on infolabel view.addmousemotionlistener( new MouseMotionAdapter() { public void mousemoved(mouseevent event) { infolabel.settext((event.getpoint()).tostring()); public void mousedragged(mouseevent event) { Graphics g = view.getimage().getgraphics(); g.setcolor (Color.white); if (firstdrag) { x = event.getx(); y = event.gety(); firstdrag = false; else { g.drawline (x, y, x=event.getx(),y=event.gety()); view.repaint(); ); view.addmouselistener( new MouseAdapter() { public void mousereleased(mouseevent event) { firstdrag = true; );
// Build the JPanel which holds (for now) the infolabel JPanel controlpane = new JPanel(); controlpane.add(infolabel); // Add the JPanel and the image data component to the JFrame getcontentpane().add(view, BorderLayout.CENTER); getcontentpane().add(controlpane, BorderLayout.SOUTH); public BufferedImage readimage (String file) throws IOException { try { FileInputStream fin = new FileInputStream(file); JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(fin); image = decoder.decodeasbufferedimage(); fin.close(); catch (IOException e) { return image;
public static void main(string[] argv) { // look for a command-line filename if (argv.length > 0) { try { JFrame frame = new MyImageViewer(argv[0]); frame.pack(); frame.setvisible(true); frame.addwindowlistener ( new WindowAdapter () { public void windowclosing ( WindowEvent e) { System.exit(0); ); catch (Exception e) { System.err.println(e); System.exit(1); // no command-line filename was provided else { System.err.println("usage: java MyImageViewer <imagefile>"); System.exit(1);
/***************************************************************** This is a helper object (could be described its own file) that extends JLabel so that it can hold a BufferedImage **************************************************************/ public class MyImageObj extends JLabel { // instance variable to hold the buffered image private BufferedImage image; public MyImageObj(BufferedImage img) { setimage(img); setpreferredsize(new Dimension(image.getWidth(), image.getheight())); public void setimage(bufferedimage img) { image = img; public BufferedImage getimage() { return image; public void paintcomponent(graphics g) { g.drawimage(image, 0, 0, this);