package imagetools; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.awt.Color; import javax.imageio.ImageIO; /** * Denoise Class: Removes noise in the image and hopefully brings out quality * * Used for breaking a capture. * * aevans 7/29/2013 */ public class Denoise implements Proximity{ private Image image=Image.getInstance(); /** * Empty Constructor */ public Denoise() { // TODO empty constructor } /** * Constructor with Buffered Image * @param img */ public Denoise(BufferedImage img) { // TODO constructor with only buffered image if (img != null) { image.setImage(img); } else { // without an image provided, throw a new exception try { throw new NoImgException(); } catch (NoImgException e) { e.printStackTrace(); } } } /** * Constructor with Buffered Image and file path * @param img * @param inpath */ public Denoise(BufferedImage img, String inpath) { // TODO constructor that takes in image and path --> performs the blur if (img != null) { image.setImage(img); image.setPath(inpath); perform_denoise(); } else { // if no image is provided throws an exception try { throw new NoImgException(); } catch (NoImgException e) { e.printStackTrace(); } } } /** * Constructor with file path * @param inpath */ public Denoise(String inpath) { // TODO constructor that takes in a path and loads an image --> performs // the blur Pattern p=Pattern.compile("(?mi)(\\.jpg|\\.jpeg|\\.gif|\\.bmp)"); Matcher m=p.matcher(inpath); if(m.find()){ image.setPath(inpath); try { image.setImage(ImageIO.read(new File(image.getPath()))); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else{ try{ throw new FileTypeException("Image must be a jpg, gif, bmp, or jpeg"); }catch(FileTypeException e){ e.printStackTrace(); } } } /** * Set an image from a file path * @param inpath */ @Override public void setImage(String inpath) { // TODO sets a patha and attempts to create an image Pattern p=Pattern.compile("(?mi)(\\.jpg|\\.jpeg|\\.gif|\\.bmp)"); Matcher m=p.matcher(inpath); if(m.find()){ image.setPath(inpath); try { image.setImage(ImageIO.read(new File(image.getPath()))); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else{ try{ throw new FileTypeException("Image must be a jpg, gif, bmp, or jpeg"); }catch(FileTypeException e){ e.printStackTrace(); } } } /** * Set an image from a buffered image */ @Override public void setImage(BufferedImage inimg) { // TODO set image via buffered image if (inimg != null) { image.setImage(inimg); } else { try { throw new NoImgException(); } catch (NoImgException e) { e.printStackTrace(); } } } /** * Set the image path */ @Override public void setPath(String inpath){ //TODO set the image path image.setPath(inpath); } /** * Get the Image path */ @Override public String getPath(){ return image.getPath(); } /** * Get a buffered Image * @return */ public BufferedImage getBufferedImage() { // TODO return the image return image.getImage(); } /** * Return the image object */ @Override public Image getImage(){ return image; } /** * Perform the box average denoise */ public void average_denoise() { // TODO call denoise using mean filter // set the filetype string and if found, render the image if (image.getPath().lastIndexOf(".") > -1) { // the file type string perform_denoise_average(); } else { try { throw new FileTypeException(); } catch (FileTypeException e) { // no file type specified e.printStackTrace(); } } } /** * Perform the laplace based denoise */ public void laplace_denoise() { // TODO call for denoising using laplacian filter // set the filetype string and if found, render the image if (image.getImage() != null) { // if the path points to an image perform denoise perform_denoise(); } else { try { throw new FileTypeException(); } catch (FileTypeException e) { // no file type specified e.printStackTrace(); } } } /** * Save an image * @param filetype */ public void save(String filetype) { image.save(); } /** * Perform an average denoise */ private void perform_denoise_average() { // TODO perform an average denoise may work for most images /* * the kernel applied is1/9|1/9|1/91/9|1/9|1/91/9|1/9|1/9 * * this is a blur and a denoise in one so calling it again only causes a * blurier image */ BufferedImage proxyimage=image.getImage(); // the new image to be stored as a denoised image BufferedImage image2 = new BufferedImage(proxyimage.getWidth(),proxyimage.getHeight(), BufferedImage.TYPE_INT_RGB); // the current position properties int x = 0; int y = 0; // a neighbor pixel to add to the map // the image width and height properties int width = proxyimage.getWidth(); int height = proxyimage.getHeight(); // loop through pixels getting neighbors and resetting colors for (x = 1; x < width - 1; x++) { for (y = 1; y < height - 1; y++) { // get the neighbor pixels for the transform Color c00 = new Color(proxyimage.getRGB(x - 1, y - 1)); Color c01 = new Color(proxyimage.getRGB(x - 1, y)); Color c02 = new Color(proxyimage.getRGB(x - 1, y + 1)); Color c10 = new Color(proxyimage.getRGB(x, y - 1)); Color c11 = new Color(proxyimage.getRGB(x, y)); Color c12 = new Color(proxyimage.getRGB(x, y + 1)); Color c20 = new Color(proxyimage.getRGB(x + 1, y - 1)); Color c21 = new Color(proxyimage.getRGB(x + 1, y)); Color c22 = new Color(proxyimage.getRGB(x + 1, y + 1)); // apply the kernel for r int r = c00.getRed() / 9 + c01.getRed() / 9 + c02.getRed() / 9 + c10.getRed() / 9 + c11.getRed() / 9 + c12.getRed() / 9 + c20.getRed() / 9 + c21.getRed() / 9 + c22.getRed() / 9; // apply the kernel for g int g = c00.getGreen() / 9 + c01.getGreen() / 9 + c02.getGreen() / 9 + c10.getGreen() / 9 + c11.getGreen() / 9 + c12.getGreen() / 9 + c20.getGreen() / 9 + c21.getGreen() / 9 + c22.getGreen() / 9; // apply the transformation for b int b = c00.getBlue() / 9 + c01.getBlue() / 9 + c02.getBlue() + c10.getBlue() / 9 + c11.getBlue() / 9 + c12.getBlue() / 9 + c20.getBlue() / 9 + c21.getBlue() / 9 + c22.getBlue() / 9; // set the new rgb values r = Math.min(255, Math.max(0, r)); g = Math.min(255, Math.max(0, g)); b = Math.min(255, Math.max(0, b)); Color c = new Color(r, g, b); image2.setRGB(x, y, c.getRGB()); } } // reset the image image.setImage(image2); } /** * Average out the noise from the denoise filter * Take the new buffered image and take averages where the white spots * are since these are where the noise is noise is denoted by a pixel whose * laplace position is white insead of black/grey * * @param img2 */ private void denoise_compare_from_fft(BufferedImage img2) { // TODO take the laplace bitmap and compare the FFT BufferedImage proxyimage=image.getImage(); int ri = 0; int gi = 0; int bi = 0; for (int x = 0; x < proxyimage.getWidth(); x++) { for (int y = 0; y < proxyimage.getHeight(); y++) { // the values from the laplace map ri = new Color(img2.getRGB(x, y)).getRed(); gi = new Color(img2.getRGB(x, y)).getGreen(); bi = new Color(img2.getRGB(x, y)).getBlue(); // if hte laplace map is white, this is noise and average are // taken if (ri == 255 & gi == 255 & bi == 255) { // get the neighbor pixels for the transform Color c00 = new Color(proxyimage.getRGB(x - 1, y - 1)); Color c01 = new Color(proxyimage.getRGB(x - 1, y)); Color c02 = new Color(proxyimage.getRGB(x - 1, y + 1)); Color c10 = new Color(proxyimage.getRGB(x, y - 1)); Color c11 = new Color(proxyimage.getRGB(x, y)); Color c12 = new Color(proxyimage.getRGB(x, y + 1)); Color c20 = new Color(proxyimage.getRGB(x + 1, y - 1)); Color c21 = new Color(proxyimage.getRGB(x + 1, y)); Color c22 = new Color(proxyimage.getRGB(x + 1, y + 1)); // apply the kernel for r int r = c00.getRed() / 9 + c01.getRed() / 9 + c02.getRed() / 9 + c10.getRed() / 9 + c11.getRed() / 9 + c12.getRed() / 9 + c20.getRed() / 9 + c21.getRed() / 9 + c22.getRed() / 9; // apply the kernel for g int g = c00.getGreen() / 9 + c01.getGreen() / 9 + c02.getGreen() / 9 + c10.getGreen() / 9 + c11.getGreen() / 9 + c12.getGreen() / 9 + c20.getGreen() / 9 + c21.getGreen() / 9 + c22.getGreen() / 9; // apply the transformation for b int b = c00.getBlue() / 9 + c01.getBlue() / 9 + c02.getBlue() + c10.getBlue() / 9 + c11.getBlue() / 9 + c12.getBlue() / 9 + c20.getBlue() / 9 + c21.getBlue() / 9 + c22.getBlue() / 9; // set the new rgb values r = Math.min(255, Math.max(0, r)); g = Math.min(255, Math.max(0, g)); b = Math.min(255, Math.max(0, b)); Color c = new Color(r, g, b); proxyimage.setRGB(x, y, c.getRGB()); } } } } /** * Perform a denoise */ private void perform_denoise() { // TODO performs the denoise in laplace *default BufferedImage proxyimage=image.getImage(); // the new buffered image for the denoising algorithm BufferedImage image2 = new BufferedImage(proxyimage.getWidth(),proxyimage.getHeight(), BufferedImage.TYPE_INT_RGB); // gives ultimate control can also use image libraries // the current position properties int x = 0; int y = 0; // the image width and height properties int width = proxyimage.getWidth(); int height = proxyimage.getHeight(); /* * Denoise Using Rewritten Code found at * http://introcs.cs.princeton.edu/ * java/31datatype/LaplaceFilter.java.html * * Using laplace is better than averaging the neighbors from each part * of an image as it does a better job of getting rid of gaussian noise * without overdoing it * * Applies a default filter: * * -1|-1|-1 -1|8|-1 -1|-1|-1 */ // perform the laplace for each number for (y = 1; y < height - 1; y++) { for (x = 1; x < width - 1; x++) { // get the neighbor pixels for the transform Color c00 = new Color(proxyimage.getRGB(x - 1, y - 1)); Color c01 = new Color(proxyimage.getRGB(x - 1, y)); Color c02 = new Color(proxyimage.getRGB(x - 1, y + 1)); Color c10 = new Color(proxyimage.getRGB(x, y - 1)); Color c11 = new Color(proxyimage.getRGB(x, y)); Color c12 = new Color(proxyimage.getRGB(x, y + 1)); Color c20 = new Color(proxyimage.getRGB(x + 1, y - 1)); Color c21 = new Color(proxyimage.getRGB(x + 1, y)); Color c22 = new Color(proxyimage.getRGB(x + 1, y + 1)); /* apply the matrix */ // to check, try using gauss jordan // apply the transformation for r int r = -c00.getRed() - c01.getRed() - c02.getRed() + -c10.getRed() + 8 * c11.getRed() - c12.getRed() + -c20.getRed() - c21.getRed() - c22.getRed(); // apply the transformation for g int g = -c00.getGreen() - c01.getGreen() - c02.getGreen() + -c10.getGreen() + 8 * c11.getGreen() - c12.getGreen() + -c20.getGreen() - c21.getGreen() - c22.getGreen(); // apply the transformation for b int b = -c00.getBlue() - c01.getBlue() - c02.getBlue() + -c10.getBlue() + 8 * c11.getBlue() - c12.getBlue() + -c20.getBlue() - c21.getBlue() - c22.getBlue(); // set the new rgb values r = Math.min(255, Math.max(0, r)); g = Math.min(255, Math.max(0, g)); b = Math.min(255, Math.max(0, b)); Color c = new Color(r, g, b); image2.setRGB(x, y, c.getRGB()); } } // compare the original image and the image where noise was found and // average where noise was found denoise_compare_from_fft(image2); } /** * Save the image */ @Override public void save() { // TODO save the image image.save(); } /** * Delete the image */ @Override public void delete(){ image.delete(); } }