diff --git a/build/classes/image2d/Closing.class b/build/classes/image2d/Closing.class new file mode 100644 index 0000000..6e7fe82 Binary files /dev/null and b/build/classes/image2d/Closing.class differ diff --git a/build/classes/image2d/Dilation.class b/build/classes/image2d/Dilation.class new file mode 100644 index 0000000..358c06f Binary files /dev/null and b/build/classes/image2d/Dilation.class differ diff --git a/build/classes/image2d/EdgeDetector.class b/build/classes/image2d/EdgeDetector.class index 0977c48..196d3b7 100644 Binary files a/build/classes/image2d/EdgeDetector.class and b/build/classes/image2d/EdgeDetector.class differ diff --git a/build/classes/image2d/EdgeOperator.class b/build/classes/image2d/EdgeOperator.class index 4d6f7b6..3ea8bc3 100644 Binary files a/build/classes/image2d/EdgeOperator.class and b/build/classes/image2d/EdgeOperator.class differ diff --git a/build/classes/image2d/Erosion.class b/build/classes/image2d/Erosion.class new file mode 100644 index 0000000..8d18ac4 Binary files /dev/null and b/build/classes/image2d/Erosion.class differ diff --git a/build/classes/image2d/Filter.class b/build/classes/image2d/Filter.class new file mode 100644 index 0000000..e0e0499 Binary files /dev/null and b/build/classes/image2d/Filter.class differ diff --git a/build/classes/image2d/FilterSequence.class b/build/classes/image2d/FilterSequence.class new file mode 100644 index 0000000..9a82ed7 Binary files /dev/null and b/build/classes/image2d/FilterSequence.class differ diff --git a/build/classes/image2d/Grayscale.class b/build/classes/image2d/Grayscale.class new file mode 100644 index 0000000..53e2824 Binary files /dev/null and b/build/classes/image2d/Grayscale.class differ diff --git a/build/classes/image2d/Guassian.class b/build/classes/image2d/Guassian.class new file mode 100644 index 0000000..ee8417f Binary files /dev/null and b/build/classes/image2d/Guassian.class differ diff --git a/build/classes/image2d/Image2D.class b/build/classes/image2d/Image2D.class index 38c5d90..85ea467 100644 Binary files a/build/classes/image2d/Image2D.class and b/build/classes/image2d/Image2D.class differ diff --git a/build/classes/image2d/ImageReader.class b/build/classes/image2d/ImageReader.class new file mode 100644 index 0000000..0910fb0 Binary files /dev/null and b/build/classes/image2d/ImageReader.class differ diff --git a/build/classes/image2d/Opening.class b/build/classes/image2d/Opening.class new file mode 100644 index 0000000..3c55121 Binary files /dev/null and b/build/classes/image2d/Opening.class differ diff --git a/build/classes/image2d/RGB.class b/build/classes/image2d/RGB.class index 3bf3b49..6a296ba 100644 Binary files a/build/classes/image2d/RGB.class and b/build/classes/image2d/RGB.class differ diff --git a/build/classes/image2d/ServiceProcess.class b/build/classes/image2d/ServiceProcess.class index 53d6ffd..4a7b5ab 100644 Binary files a/build/classes/image2d/ServiceProcess.class and b/build/classes/image2d/ServiceProcess.class differ diff --git a/build/classes/image2d/Threshold.class b/build/classes/image2d/Threshold.class new file mode 100644 index 0000000..87c4579 Binary files /dev/null and b/build/classes/image2d/Threshold.class differ diff --git a/build/classes/image2d/Unitys.class b/build/classes/image2d/Unitys.class index 2efe8e9..cb65103 100644 Binary files a/build/classes/image2d/Unitys.class and b/build/classes/image2d/Unitys.class differ diff --git a/src/image2d/Closing.java b/src/image2d/Closing.java new file mode 100644 index 0000000..ddb323a --- /dev/null +++ b/src/image2d/Closing.java @@ -0,0 +1,52 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.image.BufferedImage; +import java.util.ArrayList; + +/** + * + * @author pratchaya + */ +public final class Closing extends Filter { + + int radius; + ArrayList seq = new ArrayList(); + int index = 0; + + @Override + public BufferedImage apply(BufferedImage image) { + runningFlag = true; + + for (index = 0; index < seq.size() && cancelFlag == false; index++) { + image = seq.get(index).apply(image); + } + + cancelFlag = false; + runningFlag = false; + + return image; + } + + public void append(Filter filter) { + seq.add(filter); + } + + /** + * re-write for value correctness + */ + @Override + public int getProgress() { + return (100 * index + seq.get(index).getProgress()) / seq.size(); + } + + public Closing(int radius) { + this.radius = radius; + this.append(new Dilation(radius)); + this.append(new Erosion(radius)); + + } +} diff --git a/src/image2d/Dilation.java b/src/image2d/Dilation.java new file mode 100644 index 0000000..f4b3bbd --- /dev/null +++ b/src/image2d/Dilation.java @@ -0,0 +1,56 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.image.BufferedImage; + +/** + * + * @author pratchaya + */ +public class Dilation extends Filter { + + int radius; + + public Dilation(int radius) { + this.radius = radius; + } + + private int maxAround(BufferedImage image, int row, int col) { + int maxR = 0; + int maxG = 0; + int maxB = 0; + int radius2 = radius * radius; + for (int i = -radius; i <= radius; i++) { + for (int j = -radius; j <= radius; j++) { + if (i * i + j * j <= radius2) { + int c = new Unitys().getRGBExtended(image, col + i, row + j); + maxR = Math.max(maxR, (c >> 16) & 0xFF); + maxG = Math.max(maxG, (c >> 8) & 0xFF); + maxB = Math.max(maxB, c & 0xFF); + } + } + } + return (maxR << 16) | (maxG << 8) | maxB; + } + + @Override + public BufferedImage apply(BufferedImage image) { + + int width = image.getWidth(); + int height = image.getHeight(); + + BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); + + for (int i = 0; i < width && cancelFlag == false; i++) { + progress = 100 * i / width; + for (int j = 0; j < height && cancelFlag == false; j++) { + img.setRGB(i, j, maxAround(image, i, j)); + } + } + + return img; + } +} diff --git a/src/image2d/EdgeDetector.java b/src/image2d/EdgeDetector.java index 9f618d4..20de526 100644 --- a/src/image2d/EdgeDetector.java +++ b/src/image2d/EdgeDetector.java @@ -4,6 +4,7 @@ */ package image2d; +import java.awt.Color; import java.awt.image.BufferedImage; /** @@ -18,11 +19,10 @@ public static BufferedImage findEdgeSobel(BufferedImage _image) { // get kernel vertical double vertical[][] = new EdgeOperator().edgeVertical(); // copy image form original - BufferedImage imageOutput = new Unitys().copyImg(_image); + BufferedImage imageOutput = Unitys.copyImage(_image); // get result return new EdgeOperator().sobelOperation(_image, horizontal, vertical); } - - + } diff --git a/src/image2d/EdgeOperator.java b/src/image2d/EdgeOperator.java index b333104..784bdf1 100644 --- a/src/image2d/EdgeOperator.java +++ b/src/image2d/EdgeOperator.java @@ -36,25 +36,24 @@ public double[][] edgeVertical() { return sobel; } // ----------------------------- end sobel --------------------------------- - - - - public BufferedImage sobelOperation(BufferedImage _image, double horizon[][], double vertical[][]) { - BufferedImage imageOutput = new Unitys().copyImg(_image); // Set initial BufferedImage + + public BufferedImage sobelOperation(BufferedImage _image, double horizon[][], double vertical[][]) { + BufferedImage imageOutput = Unitys.copyImage(_image); // Set initial BufferedImage int pixel[][] = doPixels.getPixel(_image); //use to store pixels int kernelXY = horizon.length / 2; // calculate image for (int i = 0 + kernelXY; i < imageOutput.getWidth() - kernelXY - 1; i++) { for (int j = 0 + kernelXY; j < imageOutput.getHeight() - kernelXY - 1; j++) { - int a = 0, r = 0, g = 0, b = 0; // store RGB + int r = 0, g = 0, b = 0; // store RGB int horiz = 0, verti = 0; + // int p = RGB.getRGBExtended(_image, i, j); // horizontal for (int k = -(kernelXY); k < kernelXY + 1; k++) { for (int l = -(kernelXY); l < kernelXY + 1; l++) { // calculate a RGB by chip bit - a += RGB.alpha(pixel, i - k, j - l) * horizon[k + kernelXY][l + kernelXY]; + r += RGB.red(pixel, i - k, j - l) * horizon[k + kernelXY][l + kernelXY]; g += RGB.green(pixel, i - k, j - l) * horizon[k + kernelXY][l + kernelXY]; b += RGB.blue(pixel, i - k, j - l) * horizon[k + kernelXY][l + kernelXY]; @@ -70,7 +69,7 @@ public BufferedImage sobelOperation(BufferedImage _image, double horizon[][], do for (int l = -(kernelXY); l < kernelXY + 1; l++) { // calculate a RGB by chip bit - a += RGB.alpha(pixel, i - k, j - l) * vertical[k + kernelXY][l + kernelXY]; + r += RGB.red(pixel, i - k, j - l) * vertical[k + kernelXY][l + kernelXY]; g += RGB.green(pixel, i - k, j - l) * vertical[k + kernelXY][l + kernelXY]; b += RGB.blue(pixel, i - k, j - l) * vertical[k + kernelXY][l + kernelXY]; diff --git a/src/image2d/Erosion.java b/src/image2d/Erosion.java new file mode 100644 index 0000000..7e34238 --- /dev/null +++ b/src/image2d/Erosion.java @@ -0,0 +1,56 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.image.BufferedImage; + +/** + * + * @author pratchaya + */ +public class Erosion extends Filter { + + int radius; + + public Erosion(int radius) { + this.radius = radius; + } + + private int minAround(BufferedImage image, int row, int col) { + int minR = 255; + int minG = 255; + int minB = 255; + int radius2 = radius * radius; + for (int i = -radius; i <= radius; i++) { + for (int j = -radius; j <= radius; j++) { + if (i * i + j * j <= radius2) { + int c = new Unitys().getRGBExtended(image, col + i, row + j); + minR = Math.min(minR, (c >> 16) & 0xFF); + minG = Math.min(minG, (c >> 8) & 0xFF); + minB = Math.min(minB, c & 0xFF); + } + } + } + return (minR << 16) | (minG << 8) | minB; + } + + @Override + public BufferedImage apply(BufferedImage image) { + + int width = image.getWidth(); + int height = image.getHeight(); + + BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); + + for (int i = 0; i < width; i++) { + progress = 100 * i / width; + for (int j = 0; j < height && cancelFlag == false; j++) { + img.setRGB(i, j, minAround(image, i, j)); + } + } + + return img; + } +} diff --git a/src/image2d/Filter.java b/src/image2d/Filter.java new file mode 100644 index 0000000..2295de0 --- /dev/null +++ b/src/image2d/Filter.java @@ -0,0 +1,42 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.image.BufferedImage; + +/** + * + * @author pratchaya + */ +public abstract class Filter { + + /** + * Apply an filter to an image. The result image will be allocated. + * @param image Original image + * @return Processed image + */ + public abstract BufferedImage apply(BufferedImage image); + + protected boolean cancelFlag = false; + + protected boolean runningFlag = false; + + protected int progress = 0; + + public final void cancel() { + if (runningFlag == true) { + cancelFlag = true; + } + } + + public int getProgress() { + return progress; + } + + public final boolean isRunning() { + return runningFlag; + } + +} diff --git a/src/image2d/FilterSequence.java b/src/image2d/FilterSequence.java new file mode 100644 index 0000000..275893c --- /dev/null +++ b/src/image2d/FilterSequence.java @@ -0,0 +1,48 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.image.BufferedImage; +import java.util.ArrayList; + +/** + * + * @author pratchaya + */ +public class FilterSequence extends Filter { + + ArrayList seq = new ArrayList(); + int index = 0; + + public FilterSequence() { + // do nothing + } + + @Override + public BufferedImage apply(BufferedImage image) { + runningFlag = true; + + for (index = 0; index < seq.size() && cancelFlag == false; index++) { + image = seq.get(index).apply(image); + } + + cancelFlag = false; + runningFlag = false; + + return image; + } + + public void append(Filter filter) { + seq.add(filter); + } + + /** + * re-write for value correctness + */ + @Override + public int getProgress() { + return (100 * index + seq.get(index).getProgress()) / seq.size(); + } +} diff --git a/src/image2d/Grayscale.java b/src/image2d/Grayscale.java new file mode 100644 index 0000000..cb471c3 --- /dev/null +++ b/src/image2d/Grayscale.java @@ -0,0 +1,37 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.image.BufferedImage; + +/** + * + * @author pratchaya + */ +public class Grayscale extends Filter { + + @Override + public BufferedImage apply(BufferedImage _image) { + runningFlag = true; + BufferedImage imageOutput = Unitys.copyImage(_image); + int grayscale; + for (int i = 0; i < _image.getWidth(); i++) { + for (int j = 0; j < _image.getHeight(); j++) { + int rgb; + int p = RGB.getRGBExtended(_image, i, j); + + rgb = (int) ((((p >> 16) & 0xFF) * 0.2125) + (((p >> 8) & 0xFF) * 0.7154) + ((p & 0xFF) * 0.0721)); + rgb = (rgb << 16) | (rgb << 8) | (rgb); + + grayscale = rgb; //sum RGB + imageOutput.setRGB(i, j, grayscale); + } + } + cancelFlag = false; + runningFlag = false; + + return imageOutput; + } +} diff --git a/src/image2d/Guassian.java b/src/image2d/Guassian.java new file mode 100644 index 0000000..df88e64 --- /dev/null +++ b/src/image2d/Guassian.java @@ -0,0 +1,74 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.image.BufferedImage; + +/** + * + * @author pratchaya + */ +public class Guassian extends Filter { + double sigma = 0; + int size = 3; + public Guassian(double sigma, int size){ + this.sigma = sigma; + this.size = size; + } + + public static double[][] kernel(int _size , double sigma) { + int size = _size; + int _height = 5; + double gaussian[][] = new double[size][size]; + for (int j = 0; j < size; j++) { + for (int i = 0; i < size; i++) { + int xValue = i - (size / 2); + int yValue = j - (size / 2); + gaussian[i][j] = (1 / (2 * Math.PI * Math.pow(sigma, 2))) * (Math.pow(Math.E, -((Math.pow(xValue, 2) + Math.pow(yValue, 2)) / (2 * Math.pow(sigma, 2))))); + } + } + + return gaussian; + } + + @Override + public BufferedImage apply(BufferedImage _image) { + + BufferedImage imageOutput = Unitys.copyImage(_image); // Set initial BufferedImage + int c = 0; + + double gaussian[][] = kernel(size, this.sigma); + int wight = _image.getWidth(); // image wight + int heigth = _image.getHeight(); // image hight + int kernelSize = gaussian.length; // size kernel + int kernelXY = kernelSize / 2; // find a center of kernel + + // make a result with convolution method + // return image result + + for (int i = 0 + kernelXY; i < wight - kernelXY - 1; i++) { + for (int j = 0 + kernelXY; j < heigth - kernelXY - 1; j++) { + int r = 0, g = 0, b = 0; // store RGB + int p = RGB.getRGBExtended(_image, i, j); + for (int k = -(kernelXY); k < kernelXY + 1; k++) { + for (int l = -(kernelXY); l < kernelXY + 1; l++) { + + // calculate a RGB by chip bit + r += ((p >> 16) & 0xFF) * gaussian[k + kernelXY][l + kernelXY]; + g += ((p >> 8) & 0xFF) * gaussian[k + kernelXY][l + kernelXY]; + b += (p & 0xFF) * gaussian[k + kernelXY][l + kernelXY]; + + } //end k + }//end j + int rgb = ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); + //set RGB revert to image + imageOutput.setRGB(i, j, rgb); + }// end i + } //end j + + return imageOutput; + } + +} diff --git a/src/image2d/Image2D.java b/src/image2d/Image2D.java index 155c61f..5aed726 100644 --- a/src/image2d/Image2D.java +++ b/src/image2d/Image2D.java @@ -13,19 +13,39 @@ public class Image2D { + public Image2D(int x){ + Toolkit toolkit = Toolkit.getDefaultToolkit(); + Dimension dim = toolkit.getScreenSize(); + String url = "images/wl2.jpg"; // this program have 4 images : wr.png ,sh.jpg , ca.jpg , icon.jpg ,r1,r2,r3,r4.jpg + BufferedImage image = ImageReader.load_image(url); + image = new Guassian(0.7, 3).apply(image); + image = new Grayscale().apply(image); + image = new Threshold().apply(image); + // image = new Opening(3).apply(image); + image = new EdgeDetector().findEdgeSobel(image); + + JFrame frame = new JFrame("Display Image"); + ImagePanel iPanel = new ImagePanel(image); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().setLayout(new BorderLayout()); + frame.getContentPane().add("Center", iPanel); + //frame.setSize(65, 134); + frame.setSize(image.getWidth() + 8, image.getHeight() + 34); + frame.setLocation((int) image.getWidth() / dim.width + 455, (int) image.getHeight() / dim.height); + frame.setVisible(true); + + } public Image2D() { Toolkit toolkit = Toolkit.getDefaultToolkit(); Dimension dim = toolkit.getScreenSize(); String url = "images/wl2.jpg"; // this program have 4 images : wr.png ,sh.jpg , ca.jpg , icon.jpg ,r1,r2,r3,r4.jpg - BufferedImage image = ImageProcessor.load_image(url); - //image = ImageProcessor.gaussianFillter(image, 3, 3, 0.7); - //image = ImageProcessor.grayscaleFillter(image); - //image = ImageProcessor.balancingImg(image); - //image = ImageProcessor.threshold(image); - //image = ImageProcessor.balancingImg(image); - image = ServiceProcess.thresholdComplete(image); - image = EdgeDetector.findEdgeSobel(image); - + BufferedImage image = ImageReader.load_image(url); + image = new Guassian(0.7, 3).apply(image); + image = new Grayscale().apply(image); + image = new Threshold().apply(image); + image = new Opening(3).apply(image); + image = new EdgeDetector().findEdgeSobel(image); + JFrame frame = new JFrame("Display Image"); ImagePanel iPanel = new ImagePanel(image); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -43,5 +63,6 @@ public Image2D(String url) { public static void main(String[] args) { Image2D i = new Image2D(); + Image2D x = new Image2D(3); } } diff --git a/src/image2d/ImageProcessor.java b/src/image2d/ImageProcessor.java deleted file mode 100644 index a9341e1..0000000 --- a/src/image2d/ImageProcessor.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package image2d; - -import java.awt.Color; -import java.awt.image.BufferedImage; -import java.io.File; -import javax.imageio.ImageIO; -import javax.swing.JOptionPane; - -/** - * - * @author pratchaya - */ -public class ImageProcessor { - - // get image form url to BufferedImage - public static BufferedImage load_image(String url) { - // init BufferedImage null - BufferedImage image = null; - try { - // read file form BufferedImage - image = ImageIO.read(new File(url)); - if (!image.equals(null)) { - System.out.println("Load data at URL:" + url + " done."); - - } - - } catch (Exception e) { - - JOptionPane.showMessageDialog(null, e.getMessage() + " File does not exist because name or extension file is not correct." - + "\nPlease check your file again."); - } - // return result image when read url done! - return image; - } - //---------------------------------end-------------------------------------- - - // -----------------------------Convolution -------------------------------- - - public static BufferedImage convolution(BufferedImage _image, double kernel[][], int wigth, int height, int sizeKernel, int kernelXY) { - BufferedImage imageOutput = new Unitys().copyImg(_image); // Set initial BufferedImage - int pixel[][] = doPixels.getPixel(_image); //use to store pixels - - // calculate image - for (int i = 0 + kernelXY; i < wigth - kernelXY - 1; i++) { - for (int j = 0 + kernelXY; j < height - kernelXY - 1; j++) { - int a = 0, r = 0, g = 0, b = 0; // store RGB - - for (int k = -(kernelXY); k < kernelXY + 1; k++) { - for (int l = -(kernelXY); l < kernelXY + 1; l++) { - - // calculate a RGB by chip bit - a += RGB.alpha(pixel, i - k, j - l) * kernel[k + kernelXY][l + kernelXY]; - r += RGB.red(pixel, i - k, j - l) * kernel[k + kernelXY][l + kernelXY]; - g += RGB.green(pixel, i - k, j - l) * kernel[k + kernelXY][l + kernelXY]; - b += RGB.blue(pixel, i - k, j - l) * kernel[k + kernelXY][l + kernelXY]; - - } //end k - }//end j - //System.out.println(i + "," + j + ": " + "RED: " + r + " GREEN: " + g + " BLUE: " + b + "\n"); - int rgb = ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); - //set RGB revert to image - imageOutput.setRGB(i, j, rgb); - }// end i - } //end j - - return imageOutput; - } -//----------------------------------end----------------------------------------- -// -------------------------------Fillter -------------------------------------- - - public static BufferedImage gaussianFillter(BufferedImage _image, int _height, int _wight, double sigma) { - - // rander kernel gaussian - double gaussian[][] = new double[_wight][_height]; - for (int j = 0; j < _height; j++) { - for (int i = 0; i < _wight; i++) { - int xValue = i - (_wight / 2); - int yValue = j - (_height / 2); - gaussian[i][j] = (1 / (2 * Math.PI * Math.pow(sigma, 2))) * (Math.pow(Math.E, -((Math.pow(xValue, 2) + Math.pow(yValue, 2)) / (2 * Math.pow(sigma, 2))))); - } - } - - // get value _image and kernel - int wight = _image.getWidth(); // image wight - int heigth = _image.getHeight(); // image hight - int kernelSize = gaussian.length; // size kernel - int kernelXY = kernelSize / 2; // find a center of kernel - - // make a result with convolution method - // return image result - return convolution(_image, gaussian, wight, heigth, kernelSize, kernelXY); - - } - - public static BufferedImage grayscaleFillter(BufferedImage _image) { - BufferedImage imageOutput = new Unitys().copyImg(_image); - int grays; - int p[][] = doPixels.getPixel(_image); - for (int i = 0; i < _image.getWidth(); i++) { - for (int j = 0; j < _image.getHeight(); j++) { - int a, r, g, b; - a = RGB.alpha(p, i, j); - r = RGB.red(p, i, j); - g = RGB.green(p, i, j); - b = RGB.blue(p, i, j); - - grays = (int) (0.2125 * r + 0.7154 * g + 0.0721 * b); //formula - - a = (a << 24); - r = (grays << 16); - g = (grays << 8); - b = (grays); - - grays = a + r + g + b; //sum RGB - imageOutput.setRGB(i, j, grays); - } - } - return imageOutput; - } - - public static int[] histogtam(BufferedImage _image) { - int pixels[][] = doPixels.getPixel(_image); - int interval[] = new int[256]; - for (int i = 0; i < _image.getWidth(); i++) { - for (int j = 0; j < _image.getHeight(); j++) { - int r = (pixels[i][j] >> 16) & 0xff; - interval[r]++; - } - - } - - return interval; - - } - - public static int[] balancing(BufferedImage _image) { - int _histogram[] = histogtam(_image); - int _factor[] = new int[256]; - _factor = new Unitys().randArray(_factor, 0); - long sum = 0; - float scale = (float) (255.0 / (_image.getWidth() * _image.getHeight())); - - for (int i = 0; i < _factor.length; i++) { - sum += _histogram[i]; - int value = (int) (sum * scale); - if (value > 255) { - _factor[i] = 255; - } else { - _factor[i] = value; - } - } - return _factor; - - } - - public static BufferedImage balancingImg(BufferedImage _image) { - int new_Histogram[] = balancing(_image); - BufferedImage output = new Unitys().copyImg(_image); - int pixel[][] = doPixels.getPixel(output); - int r, g, b, p; - for (int i = 0; i < _image.getWidth(); i++) { - for (int j = 0; j < _image.getHeight(); j++) { - r = RGB.red(pixel, i, j); - g = RGB.green(pixel, i, j); - b = RGB.blue(pixel, i, j); - - r = new_Histogram[r]; - g = new_Histogram[g]; - b = new_Histogram[b]; - - r = (r << 16); - g = (g << 8); - b = (b); - - p = r + g + b; - - output.setRGB(i, j, p); - } - - } - - return output; - - } - - public static BufferedImage threshold(BufferedImage _image) { - int _r, p, r, g, b; - - double threshold = otsuTreshold(_image); - BufferedImage imageOutput = new Unitys().copyImg(_image); - for (int i = 0; i < _image.getWidth(); i++) { - for (int j = 0; j < _image.getHeight(); j++) { - - // Get pixels - r = new Color(_image.getRGB(i, j)).getRed(); - int alpha = new Color(_image.getRGB(i, j)).getAlpha(); - if (r > threshold) { - p = 255; - } else { - p = 0; - } - alpha = (alpha << 24); - r = (p << 16); - g = (p << 8); - b = (p); - - p = alpha + r + g + b; - imageOutput.setRGB(i, j, p); - - } - } - - return imageOutput; - - } - - // --------------------------------not ok!!! ------------------------------ - public static int otsuTreshold(BufferedImage _image) { - int _histogram[] = histogtam(_image); - - int total = _image.getWidth() * _image.getHeight(); - float sum = 0; - for (int i = 0; i < 256; i++) { - sum += i * _histogram[i]; - } - float sum_bg = 0; - int wight_bg = 0, wight_fg = 0; - - float varMax = 0; - int threshold = 0; - - for (int i = 0; i < 256; i++) { - wight_bg += _histogram[i]; - if (wight_bg == 0) { - continue; - } - wight_fg = total - wight_bg; - - if (wight_fg == 0) { - break; - } - - sum_bg += (float) (i * _histogram[i]); - float mean_bg = sum_bg / wight_bg; - float mean_fg = (sum - sum_bg) / wight_fg; - float varBetween = (float) wight_bg * (float) wight_fg * (mean_bg - mean_fg) * (mean_bg - mean_fg); - if (varBetween > varMax) { - varMax = varBetween; - threshold = i; - } - } - System.out.println(threshold); - return threshold; - } - //----------------------------------end Fillter------------------------------------- -} diff --git a/src/image2d/ImageReader.java b/src/image2d/ImageReader.java new file mode 100644 index 0000000..13733bc --- /dev/null +++ b/src/image2d/ImageReader.java @@ -0,0 +1,75 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.File; +import javax.imageio.ImageIO; +import javax.swing.JOptionPane; + +/** + * + * @author pratchaya + */ +public class ImageReader { + + // get image form url to BufferedImage + public static BufferedImage load_image(String url) { + // init BufferedImage null + BufferedImage image = null; + try { + // read file form BufferedImage + image = ImageIO.read(new File(url)); + if (!image.equals(null)) { + System.out.println("Load data at URL:" + url + " done."); + + } + + } catch (Exception e) { + + JOptionPane.showMessageDialog(null, e.getMessage() + " File does not exist because name or extension file is not correct." + + "\nPlease check your file again."); + } + // return result image when read url done! + return image; + } +} +//---------------------------------end-------------------------------------- +/* + * public static int[] balancing(BufferedImage _image) { int _histogram[] = + * histogtam(_image); int _factor[] = new int[256]; _factor = new + * Unitys().randArray(_factor, 0); long sum = 0; float scale = (float) (255.0 / + * (_image.getWidth() * _image.getHeight())); + * + * for (int i = 0; i < _factor.length; i++) { sum += _histogram[i]; int value = + * (int) (sum * scale); if (value > 255) { _factor[i] = 255; } else { _factor[i] + * = value; } } return _factor; + * + * } + * + * public static BufferedImage balancingImg(BufferedImage _image) { int + * new_Histogram[] = balancing(_image); BufferedImage output = + * Unitys.copyImage(_image); int r, g, b, rgb; for (int i = 0; i < + * _image.getWidth(); i++) { for (int j = 0; j < _image.getHeight(); j++) { int + * p = RGB.getRGBExtended(_image, i, j); r = (p >> 16) & 0xff; g = (p >> 8) & + * 0xff; b = (p & 0xff); + * + * r = new_Histogram[r]; g = new_Histogram[g]; b = new_Histogram[b]; + * + * r = (r << 16); g = (g << 8); b = (b); + * + * rgb = r + g + b; + * + * output.setRGB(i, j, rgb); } + * + * } + * + * return output; + * + * } + * + * + */ diff --git a/src/image2d/Morphological.java b/src/image2d/Morphological.java deleted file mode 100644 index a216ea0..0000000 --- a/src/image2d/Morphological.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package image2d; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.Toolkit; -import java.awt.image.BufferedImage; -import javax.swing.JFrame; - -/** - * - * @author pratchaya - */ -public class Morphological { - - public Morphological() { - Toolkit toolkit = Toolkit.getDefaultToolkit(); - Dimension dim = toolkit.getScreenSize(); - String url = "images/wl5.jpg"; // this program have 4 images : wr.png ,sh.jpg , ca.jpg , icon.jpg ,r1,r2,r3,r4.jpg - BufferedImage image = ImageProcessor.load_image(url); - image = ImageProcessor.gaussianFillter(image, 3, 3, 0.7); - image = ImageProcessor.grayscaleFillter(image); - //image = ImageProcessor.balancingImg(image); - image = ImageProcessor.threshold(image); - - - - JFrame frame = new JFrame("Display Image"); - ImagePanel iPanel = new ImagePanel(image); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.getContentPane().setLayout(new BorderLayout()); - frame.getContentPane().add("Center", iPanel); - //frame.setSize(65, 134); - frame.setSize(image.getWidth() + 8, image.getHeight() + 34); - frame.setLocation((int) image.getWidth() / dim.width + 455, (int) image.getHeight() / dim.height); - frame.setVisible(true); - - } - -// public static BufferedImage erode(int kernel, BufferedImage _image) { -// BufferedImage imageOutput = Unitys.copyImg(_image); // copy image -// int pixel[][] = doPixels.getPixel(imageOutput); // get pixel -// int kernelMask[][] = new int[kernel][kernel]; -// int kernelXY = Unitys.operation_Number("/", kernelMask.length, 2); -// int temp = 0; -// for (int i = 0; i < kernelMask.length; i++) { -// for (int j = 0; j < kernelMask.length; j++) { -// kernelMask[i][j] = 1; -// } -// } -// for (int i = 0 + kernelXY; i < _image.getWidth() - kernelXY - 1; i++) { -// for (int j = 0 + kernelXY; j < _image.getHeight() - kernelXY - 1; j++) { -// int c = 0; -// for (int k = -(kernelXY); k < kernelXY + 1; k++) { -// for (int l = -(kernelXY); l < kernelXY + 1; l++) { -// } -// } -// } -// } -// return imageOutput; -// } - - public static void main(String[] args) { - Morphological m = new Morphological(); - } -} \ No newline at end of file diff --git a/src/image2d/Opening.java b/src/image2d/Opening.java new file mode 100644 index 0000000..bfa3856 --- /dev/null +++ b/src/image2d/Opening.java @@ -0,0 +1,52 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.image.BufferedImage; +import java.util.ArrayList; + +/** + * + * @author pratchaya + */ +public final class Opening extends Filter { + + int radius; + ArrayList seq = new ArrayList(); + int index = 0; + + @Override + public BufferedImage apply(BufferedImage image) { + runningFlag = true; + + for (index = 0; index < seq.size() && cancelFlag == false; index++) { + image = seq.get(index).apply(image); + } + + cancelFlag = false; + runningFlag = false; + + return image; + } + + public void append(Filter filter) { + seq.add(filter); + } + + /** + * re-write for value correctness + */ + @Override + public int getProgress() { + return (100 * index + seq.get(index).getProgress()) / seq.size(); + } + + public Opening(int radius) { + this.radius = radius; + this.append(new Erosion(radius)); + this.append(new Dilation(radius)); + + } +} diff --git a/src/image2d/RGB.java b/src/image2d/RGB.java index 35a89f4..b646786 100644 --- a/src/image2d/RGB.java +++ b/src/image2d/RGB.java @@ -4,6 +4,7 @@ */ package image2d; +import java.awt.image.BufferedImage; public class RGB { @@ -35,4 +36,12 @@ public static int blue(int pixels[][], int x, int y) { return r; } // return bit RGB - } + + public static int getRGBExtended(BufferedImage image, int i, int j) { + int width = image.getWidth(); + int height = image.getHeight(); + i = Math.max(0, Math.min(width - 1, i)); + j = Math.max(0, Math.min(height - 1, j)); + return image.getRGB(i, j); + } +} diff --git a/src/image2d/ServiceProcess.java b/src/image2d/ServiceProcess.java index dccf7c2..1316ba0 100644 --- a/src/image2d/ServiceProcess.java +++ b/src/image2d/ServiceProcess.java @@ -11,14 +11,14 @@ * @author pratchaya */ public class ServiceProcess { - - public static BufferedImage thresholdComplete(BufferedImage _image) { - // blur ** 3x3 in sigma 0.7 - BufferedImage image = ImageProcessor.gaussianFillter(_image, 3, 3, 0.7); - // grayscale tone - image = ImageProcessor.grayscaleFillter(image); - //image = ImageProcessor.balancingImg(image); - image = ImageProcessor.threshold(image); - return image; - } +// +// public static BufferedImage thresholdComplete(BufferedImage _image) { +// // blur ** 3x3 in sigma 0.7 +// BufferedImage image = ImageProcessor.gaussianFillter(_image, 3, 3, 0.7); +// // grayscale tone +// image = Grayscale.fillter(image); +// //image = ImageProcessor.balancingImg(image); +// image = ImageProcessor.threshold(image); +// return image; +// } } diff --git a/src/image2d/Threshold.java b/src/image2d/Threshold.java new file mode 100644 index 0000000..1f5697c --- /dev/null +++ b/src/image2d/Threshold.java @@ -0,0 +1,100 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package image2d; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.util.ArrayList; + +/** + * + * @author pratchaya + */ +public class Threshold extends Filter { + + @Override + public BufferedImage apply(BufferedImage _image) { + int _r, p, r, g, b; + double threshold = otsuTreshold(_image); + BufferedImage imageOutput = Unitys.copyImage(_image); + for (int i = 0; i < _image.getWidth(); i++) { + for (int j = 0; j < _image.getHeight(); j++) { + + // Get pixels + r = RGB.getRGBExtended(_image, i, j); + r = ((r >> 16) & 0xff); + int alpha = new Color(_image.getRGB(i, j)).getAlpha(); + if (r > threshold) { + p = 255; + } else { + p = 0; + } + alpha = (alpha << 24); + r = (p << 16); + g = (p << 8); + b = (p); + + p = alpha + r + g + b; + imageOutput.setRGB(i, j, p); + + } + } + + return imageOutput; + } + + public static int otsuTreshold(BufferedImage _image) { + int _histogram[] = histogtam(_image); + + int total = _image.getWidth() * _image.getHeight(); + float sum = 0; + for (int i = 0; i < 256; i++) { + sum += i * _histogram[i]; + } + float sum_bg = 0; + int wight_bg = 0, wight_fg = 0; + + float varMax = 0; + int threshold = 0; + + for (int i = 0; i < 256; i++) { + wight_bg += _histogram[i]; + if (wight_bg == 0) { + continue; + } + wight_fg = total - wight_bg; + + if (wight_fg == 0) { + break; + } + + sum_bg += (float) (i * _histogram[i]); + float mean_bg = sum_bg / wight_bg; + float mean_fg = (sum - sum_bg) / wight_fg; + float varBetween = (float) wight_bg * (float) wight_fg * (mean_bg - mean_fg) * (mean_bg - mean_fg); + if (varBetween > varMax) { + varMax = varBetween; + threshold = i; + } + } + System.out.println(threshold); + return threshold; + } + + public static int[] histogtam(BufferedImage _image) { + int interval[] = new int[256]; + for (int i = 0; i < _image.getWidth(); i++) { + for (int j = 0; j < _image.getHeight(); j++) { + int p = RGB.getRGBExtended(_image, i, j); + int r = (p >> 16) & 0xff; + interval[r]++; + } + + } + + return interval; + + } +} diff --git a/src/image2d/Unitys.java b/src/image2d/Unitys.java index a414f09..cce8285 100644 --- a/src/image2d/Unitys.java +++ b/src/image2d/Unitys.java @@ -4,6 +4,8 @@ */ package image2d; +import java.awt.geom.AffineTransform; +import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.WritableRaster; @@ -14,9 +16,11 @@ */ public class Unitys { + private static int IMAGE_TYPE; + //----------------------------------- helper method--------------------------------- // use to copy image - public BufferedImage copyImg(BufferedImage _image) { + public static BufferedImage copyImage(BufferedImage _image) { ColorModel cm = _image.getColorModel(); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); WritableRaster raster = _image.copyData(null); @@ -56,4 +60,12 @@ public int[] randArray(int arr[], int val) { } return arr; } + + public int getRGBExtended(BufferedImage image, int row, int col) { + int width = image.getWidth(); + int height = image.getHeight(); + row = Math.max(0, Math.min(height - 1, row)); + col = Math.max(0, Math.min(width - 1, col)); + return image.getRGB(col, row); + } }