├── .gitignore ├── LICENSE.txt ├── README.md └── src └── image2d ├── AutoBalance.java ├── Dilation.java ├── EdgeDetector.java ├── EdgeOperator.java ├── Erosion.java ├── Gaussian.java ├── Grayscale.java ├── Histogram.java ├── Image2D.java ├── ImagePanel.java ├── ImageReader.java ├── RGB.java ├── Threshold.java └── Unitys.java /.gitignore: -------------------------------------------------------------------------------- 1 | /dist/ -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 Avatar 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Image Processing with java 2 | ## About this project 3 | The code I was developing on 3-4 years ago, While I studied on Third years in University. My purpose is to use the code in Senior project. Now I don't work in image processing field anymore. I decided to open code for everyone who is interesting in image processing. I want people to lean from my code. 4 | 5 | This project develop by using java, image processing concept and basic mathematical formula 6 | 7 | 8 | # What's inside the project. 9 | ### Image2D.java 10 | Main class, show example to use function 11 | 12 | ### Gaussian.java 13 | The algorithm for bluring image, I use Gaussian distribution method 14 | ##### Link 15 | * https://en.wikipedia.org/wiki/Gaussian_blur 16 | * http://www.pixelstech.net/article/1353768112-Gaussian-Blur-Algorithm 17 | * http://blog.ivank.net/fastest-gaussian-blur.html 18 | 19 | ### Grayscale.java 20 | The algorithm for convert image to gray color, In this file I use Luminosity method, However I can read other method and example at below link 21 | ##### Link 22 | * https://en.wikipedia.org/wiki/Grayscale 23 | * http://developer.bostjan-cigan.com/java-color-image-to-grayscale-conversion-algorithm/ 24 | * http://www.tannerhelland.com/3643/grayscale-image-algorithm-vb6/ 25 | * http://www.johndcook.com/blog/2009/08/24/algorithms-convert-color-grayscale/ 26 | 27 | ### Histogram.java 28 | ##### understand about histogram 29 | * http://www.tutorialspoint.com/dip/histograms_introduction.htm 30 | * http://www.tutorialspoint.com/dip/histogram_equalization.htm 31 | 32 | ##### Math formula 33 | * https://en.wikipedia.org/wiki/Histogram 34 | 35 | ### Threshold.java 36 | The algorithm to convert image to binary color (Separates pixels in an image into a foreground and background) , In this file I use Otsu's method, 37 | However you must have understand about histogram first cause by threshold algorithm base on histogram 38 | ##### understand about Threshold 39 | * https://en.wikipedia.org/wiki/Thresholding_(image_processing) 40 | 41 | ##### Math formula for Otsu's method 42 | * http://www.ancient-asia-journal.com/articles/10.5334/aa.06113/ 43 | * https://en.wikipedia.org/wiki/Otsu%27s_method 44 | 45 | ### EdgeOperator.java 46 | The algorithm to find edge of image , I use Canny Edge algorithm 47 | ##### Understand about Canny Edge algorithm 48 | * https://en.wikipedia.org/wiki/Canny_edge_detector 49 | 50 | ##### Definetion and example 51 | I follow by this link to implement canny edge and use convolution method to apply value to image 52 | * http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/can_tut.html 53 | 54 | #### Definetion on OpenCv website 55 | * http://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html 56 | 57 | ### AutoBalance.java 58 | ##### link 59 | * https://en.wikipedia.org/wiki/Color_balance 60 | 61 | ## Remove or Add image area (Morphological) 62 | ##### Concept 63 | * https://www.cs.auckland.ac.nz/courses/compsci773s1c/lectures/ImageProcessing-html/topic4.htm 64 | 65 | ### Erosion.java 66 | ##### link 67 | * http://homepages.inf.ed.ac.uk/rbf/HIPR2/erode.htm 68 | 69 | ### Dilation.java 70 | ##### link 71 | * http://homepages.inf.ed.ac.uk/rbf/HIPR2/dilate.htm 72 | 73 | ### See also Morphological 74 | ##### Closing 75 | * https://en.wikipedia.org/wiki/Closing_(morphology) 76 | 77 | ##### Opening 78 | * https://en.wikipedia.org/wiki/Opening_(morphology) 79 | 80 | ## Read pixel color value 81 | ### RGB.java 82 | If you get value of pixle from RGB.java to access RGB value on Dicimal digit, You must use bitwise operators to shitf bit. R >> 16 , G >> 8 and B, Then add mask by (& 0xFF), See example in below link or file this project 83 | ##### link 84 | * http://stackoverflow.com/questions/22391353/get-color-of-each-pixel-of-an-image-using-bufferedimages 85 | * http://stackoverflow.com/questions/6524196/java-get-pixel-array-from-image 86 | 87 | # Convoluion 88 | ## To apply vaule to image, You must have understand Convoluion method 89 | * https://en.wikipedia.org/wiki/Convolution 90 | * http://mathworld.wolfram.com/Convolution.html 91 | * http://www.songho.ca/dsp/convolution/convolution.html 92 | 93 | ## License 94 | 95 | This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info. 96 | -------------------------------------------------------------------------------- /src/image2d/AutoBalance.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.image.BufferedImage; 8 | 9 | /** 10 | * 11 | * @author pratchaya 12 | */ 13 | public class AutoBalance { 14 | 15 | public static int[] balancing(BufferedImage _image) { 16 | int _histogram[] =Histogram.histogtam(_image); 17 | int _factor[] = new int[256]; 18 | _factor = new Unitys().randArray(_factor, 0); 19 | int sum = 0; 20 | float scale = (float) (255.0 / (_image.getWidth() * _image.getHeight())); 21 | 22 | for (int i = 0; i < _factor.length; i++) { 23 | sum += _histogram[i]; 24 | int value = 25 | (int) (sum * scale); 26 | if (value > 255) { 27 | _factor[i] = 255; 28 | } else { 29 | _factor[i] = value; 30 | } 31 | } 32 | return _factor; 33 | 34 | } 35 | 36 | public static BufferedImage apply(BufferedImage _image) { 37 | int new_Histogram[] = balancing(_image); 38 | BufferedImage output = new BufferedImage(_image.getWidth(), _image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); 39 | int r, g, b, rgb; 40 | for (int i = 0; i < _image.getWidth(); i++) { 41 | for (int j = 0; j < _image.getHeight(); j++) { 42 | int p = RGB.getRGBW(_image, i, j); 43 | r = (p >> 16) & 0xff; 44 | g = (p >> 8) & 0xff; 45 | b = (p & 0xff); 46 | 47 | r = new_Histogram[r]; 48 | g = new_Histogram[g]; 49 | b = new_Histogram[b]; 50 | 51 | output.setRGB(i, j, (r << 16) | (g << 8) | (b)); 52 | } 53 | 54 | } 55 | 56 | return output; 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/image2d/Dilation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.image.BufferedImage; 8 | 9 | /** 10 | * 11 | * @author pratchaya 12 | */ 13 | public class Dilation { 14 | 15 | private static int maxPixel(BufferedImage _image, int _w, int _h, int r) { 16 | int maxR = 0; 17 | int maxG = 0; 18 | int maxB = 0; 19 | int radiusPow = r * r; 20 | int _r = r/2; 21 | for (int i = -_r; i < _r; i++) { 22 | for (int j = -_r; j < _r; j++) { 23 | if (i * i + j * j < radiusPow) { 24 | int c = RGB.getRGBW(_image, _w + i, _h + j); 25 | maxR = Math.max(maxR, (c >> 16) & 0xFF); 26 | maxG = Math.max(maxG, (c >> 8) & 0xFF); 27 | maxB = Math.max(maxB, c & 0xFF); 28 | } // end if 29 | } // end j 30 | } // end i 31 | return (maxR << 16) | (maxG << 8) | maxB; 32 | } 33 | 34 | public static BufferedImage apply(BufferedImage _image, int _radius) { 35 | 36 | int width = _image.getWidth(); 37 | int height = _image.getHeight(); 38 | int radius = _radius; 39 | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); 40 | 41 | for (int i = 0; i < width; i++) { 42 | for (int j = 0; j < height; j++) { 43 | image.setRGB(i, j, maxPixel(_image, i, j, radius)); 44 | } 45 | } 46 | 47 | return image; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/image2d/EdgeDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.Color; 8 | import java.awt.image.BufferedImage; 9 | 10 | /** 11 | * 12 | * @author pratchaya 13 | */ 14 | public class EdgeDetector { 15 | 16 | public static BufferedImage EdgeSobel(BufferedImage _image) { 17 | // get kernel horizontal 18 | int horizontal[][] = EdgeOperator.edgeHorizontal(); 19 | // get kernel vertical 20 | int vertical[][] = EdgeOperator.edgeVertical(); 21 | // get result 22 | return EdgeOperator.apply(_image, horizontal, vertical); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/image2d/EdgeOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.Color; 8 | import java.awt.image.BufferedImage; 9 | 10 | /** 11 | * 12 | * @author pratchaya 13 | */ 14 | public class EdgeOperator { 15 | 16 | // ---------------------------- sobel -------------------------------------- 17 | // ** this template for sobel ** 18 | public static int[][] edgeHorizontal() { 19 | 20 | int sobel[][] = { 21 | {-1, -2, -1}, 22 | {0, 0, 0}, 23 | {1, 2, 1} 24 | }; 25 | 26 | return sobel; 27 | } 28 | 29 | public static int[][] edgeVertical() { 30 | int sobel[][] = { 31 | {-1, 0, 1}, 32 | {-2, 0, 2}, 33 | {-1, 0, 1} 34 | }; 35 | 36 | return sobel; 37 | } 38 | // ----------------------------- end sobel --------------------------------- 39 | 40 | public static BufferedImage apply(BufferedImage _image, int horizon[][], int vertical[][]) { 41 | BufferedImage imageOutput = new BufferedImage(_image.getWidth(), _image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); // Set initial BufferedImage 42 | 43 | int kernelXY = horizon.length / 2; 44 | // calculate image 45 | for (int i = 0; i < imageOutput.getWidth(); i++) { 46 | for (int j = 0; j < imageOutput.getHeight(); j++) { 47 | int r = 0, g = 0, b = 0 , _r = 0 , _g = 0 , _b = 0; // store RGB 48 | int horiz = 0, verti = 0; 49 | // int p = RGB.getRGBExtended(_image, i, j); 50 | 51 | for (int k = -(kernelXY); k < kernelXY + 1; k++) { 52 | for (int l = -(kernelXY); l < kernelXY + 1; l++) { 53 | int p = RGB.getRGBW(_image, i + k, j + l); 54 | // calculate a RGB by ship bit 55 | // horizontal 56 | r += ((p >> 16) & 0xff) * vertical[k + kernelXY][l + kernelXY]; 57 | g += ((p >> 8) & 0xff) * vertical[k + kernelXY][l + kernelXY]; 58 | b += (p & 0xff) * vertical[k + kernelXY][l + kernelXY]; 59 | 60 | // verticel 61 | _r += ((p >> 16) & 0xff) * horizon[k + kernelXY][l + kernelXY]; 62 | _g += ((p >> 8) & 0xff) * horizon[k + kernelXY][l + kernelXY]; 63 | _b += (p & 0xff) * horizon[k + kernelXY][l + kernelXY]; 64 | 65 | } //end k 66 | }//end j 67 | horiz += ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); 68 | verti += ((_r & 0xff) << 16) | ((_g & 0xff) << 8) | (_b & 0xff); 69 | 70 | 71 | 72 | 73 | // add x-coordinate,y-coordinate form (diff) wiht sqrt(x.diff^2)+sqrt(y.diff^2)+ 74 | double rgb = Math.sqrt(Math.pow(horiz, 2.0)) + Math.sqrt(Math.pow(verti, 2.0)); 75 | // set color 0-255 76 | if (rgb > 255) { 77 | rgb = 255; 78 | } 79 | if (rgb < 0) { 80 | rgb = 0; 81 | } 82 | Color c = new Color((int) rgb, (int) rgb, (int) rgb); 83 | 84 | //set RGB revert to image 85 | imageOutput.setRGB(i, j, (int) c.getRGB()); 86 | }// end i 87 | } //end j 88 | 89 | return imageOutput; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/image2d/Erosion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.image.BufferedImage; 8 | 9 | /** 10 | * 11 | * @author pratchaya 12 | */ 13 | public class Erosion { 14 | 15 | private static int minPixel(BufferedImage _image, int _w, int _h, int r) { 16 | int minR = 255; 17 | int minG = 255; 18 | int minB = 255; 19 | int radiusPow = r * r; 20 | int _r = r/2; 21 | for (int i = -_r; i < _r; i++) { 22 | for (int j = -_r; j < _r; j++) { 23 | if (i * i + j * j < radiusPow) { 24 | int c = RGB.getRGBW(_image, _w + i, _h + j); 25 | minR = Math.min(minR, (c >> 16) & 0xFF); 26 | minG = Math.min(minG, (c >> 8) & 0xFF); 27 | minB = Math.min(minB, c & 0xFF); 28 | } // end if 29 | } // end j 30 | } // end i 31 | 32 | return (minR << 16) | (minG << 8) | minB; 33 | } 34 | 35 | public static BufferedImage apply(BufferedImage _image, int _radius) { 36 | 37 | int width = _image.getWidth(); 38 | int height = _image.getHeight(); 39 | int radius = _radius; 40 | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); 41 | 42 | for (int i = 0; i < width; i++) { 43 | for (int j = 0; j < height; j++) { 44 | image.setRGB(i, j, minPixel(_image, i, j, radius)); 45 | } 46 | } 47 | 48 | return image; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/image2d/Gaussian.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.image.BufferedImage; 8 | 9 | /** 10 | * 11 | * @author pratchaya 12 | */ 13 | public class Gaussian { 14 | 15 | public static double[][] kernel(int _size, double sigma) { 16 | 17 | int size = _size; 18 | double gaussian[][] = new double[size][size]; 19 | for (int j = 0; j < size; j++) { 20 | for (int i = 0; i < size; i++) { 21 | int xValue = i - (size / 2); 22 | int yValue = j - (size / 2); 23 | 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))))); 24 | 25 | } 26 | } 27 | 28 | return gaussian; 29 | } 30 | 31 | public static double kernel_sum(double[][] kernel) { 32 | double kernel_sum = 0.0; 33 | for (int i = 0; i < kernel.length; i++) { 34 | for (int j = 0; j < kernel.length; j++) { 35 | kernel_sum += kernel[i][j]; 36 | } 37 | } 38 | return kernel_sum; 39 | } 40 | 41 | public static BufferedImage apply(BufferedImage _image, int size, double sigma) { 42 | 43 | BufferedImage imageOutput = new BufferedImage(_image.getWidth(), _image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); // Set initial BufferedImage 44 | // Set initial BufferedImage 45 | int c = 0; 46 | 47 | double gaussian[][] = Gaussian.kernel(size, sigma); 48 | double agv = Gaussian.kernel_sum(gaussian); 49 | int wight = _image.getWidth(); // image wight 50 | int heigth = _image.getHeight(); // image hight 51 | int kernelSize = gaussian.length; // size kernel 52 | int kernelXY = kernelSize / 2; // find a center of kernel 53 | // make a result with convolution method 54 | // return image result 55 | 56 | for (int i = 0; i < wight; i++) { 57 | for (int j = 0; j < heigth; j++) { 58 | int r = 0, g = 0, b = 0; // store RGB 59 | 60 | for (int k = -kernelXY; k <= kernelXY; k++) { 61 | for (int l = -kernelXY; l <= kernelXY; l++) { 62 | if (k * k + l * l < gaussian.length * gaussian.length) { 63 | int p = RGB.getRGBW(_image, i + k, j + l); 64 | // calculate a RGB by chip bit 65 | r += ((p >> 16) & 0xFF) * gaussian[k + kernelXY][l + kernelXY]; 66 | g += ((p >> 8) & 0xFF) * gaussian[k + kernelXY][l + kernelXY]; 67 | b += (p & 0xFF) * gaussian[k + kernelXY][l + kernelXY]; 68 | } 69 | } //end l 70 | }//end k 71 | int rgb = ((int) (r / agv) << 16) | ((int) (g / agv) << 8) | ((int) (b / agv)); 72 | //set RGB revert to image 73 | imageOutput.setRGB(i, j, rgb); 74 | }// end i 75 | } //end j; 76 | return imageOutput; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/image2d/Grayscale.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.image.BufferedImage; 8 | 9 | /** 10 | * 11 | * @author pratchaya 12 | */ 13 | public class Grayscale { 14 | 15 | public static BufferedImage apply(BufferedImage _image) { 16 | 17 | BufferedImage imageOutput = Unitys.copyImage(_image); 18 | int grayscale; 19 | for (int i = 0; i < _image.getWidth(); i++) { 20 | for (int j = 0; j < _image.getHeight(); j++) { 21 | int rgb; 22 | int p = RGB.getRGBW(_image, i, j); 23 | 24 | rgb = (int) ((((p >> 16) & 0xFF) * 0.2125) + (((p >> 8) & 0xFF) * 0.7154) + ((p & 0xFF) * 0.0721)); 25 | rgb = (rgb << 16) | (rgb << 8) | (rgb); 26 | 27 | imageOutput.setRGB(i, j, rgb); 28 | } 29 | } 30 | return imageOutput; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/image2d/Histogram.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.image.BufferedImage; 8 | 9 | /** 10 | * 11 | * @author pratchaya 12 | */ 13 | public class Histogram { 14 | 15 | public static int[] histogtam(BufferedImage _image) { 16 | int interval[] = new int[256]; 17 | for (int i = 0; i < _image.getWidth(); i++) { 18 | for (int j = 0; j < _image.getHeight(); j++) { 19 | int p = RGB.getRGBW(_image, i, j); 20 | int r = (p >> 16) & 0xff; 21 | interval[r]++; 22 | } 23 | 24 | } 25 | return interval; 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/image2d/Image2D.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | //import java.awt.Graphics2D; 8 | import java.awt.BorderLayout; 9 | import java.awt.Dimension; 10 | import java.awt.Toolkit; 11 | import java.awt.image.BufferedImage; 12 | import javax.swing.JFrame; 13 | 14 | public class Image2D { 15 | 16 | public Image2D() { 17 | Toolkit toolkit = Toolkit.getDefaultToolkit(); 18 | Dimension dim = toolkit.getScreenSize(); 19 | String url = "C:\\javacv-bin\\samples\\rice.jpg"; // this program have 4 images : wr.png ,sh.jpg , ca.jpg , icon.jpg ,r1,r2,r3,r4.jpg 20 | BufferedImage image = ImageReader.load_image(url); 21 | image = Gaussian.apply(image, 7, 0.84089642); //.94089642 22 | image = Grayscale.apply(image); 23 | // image = AutoBalance.apply(image); 24 | image = Threshold.apply(image); 25 | image = Opening.apply(image, 3); 26 | image = Opening.apply(image, 3); 27 | image = Opening.apply(image, 3); 28 | // image = Closing.apply(image, 2); 29 | //image = EdgeDetector.EdgeSobel(image); 30 | 31 | // swing for tester { 32 | JFrame frame = new JFrame("Display Image"); 33 | ImagePanel iPanel = new ImagePanel(image); 34 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 35 | frame.getContentPane().setLayout(new BorderLayout()); 36 | frame.getContentPane().add("Center", iPanel); 37 | //frame.setSize(65, 134); 38 | frame.setSize(image.getWidth() + 8, image.getHeight() + 34); 39 | frame.setLocation((int) image.getWidth() / dim.width + 455, (int) image.getHeight() / dim.height); 40 | frame.setVisible(true); 41 | // } 42 | 43 | } 44 | 45 | public static void main(String[] args) { 46 | Image2D i = new Image2D(); 47 | 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/image2d/ImagePanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.Graphics; 8 | import java.awt.image.BufferedImage; 9 | import javax.swing.JPanel; 10 | 11 | /** 12 | * 13 | * @author atitp 14 | */ 15 | public class ImagePanel extends JPanel { 16 | 17 | private BufferedImage image; 18 | 19 | public ImagePanel(BufferedImage _image) { 20 | image = _image; 21 | } 22 | 23 | @Override 24 | public void paintComponent(Graphics g) { 25 | super.paintComponent(g); 26 | if (image != null) { 27 | g.drawImage(image, 0, 0, this); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/image2d/ImageReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.Color; 8 | import java.awt.image.BufferedImage; 9 | import java.io.File; 10 | import javax.imageio.ImageIO; 11 | import javax.swing.JOptionPane; 12 | 13 | /** 14 | * 15 | * @author pratchaya 16 | */ 17 | public class ImageReader { 18 | 19 | // get image form url to BufferedImage 20 | public static BufferedImage load_image(String url) { 21 | // init BufferedImage null 22 | BufferedImage image = null; 23 | try { 24 | // read file form BufferedImage 25 | image = ImageIO.read(new File(url)); 26 | if (!image.equals(null)) { 27 | 28 | } 29 | 30 | } catch (Exception e) { 31 | 32 | JOptionPane.showMessageDialog(null, e.getMessage() + " File does not exist because name or extension file is not correct." 33 | + "\nPlease check your file again."); 34 | } 35 | // return result image when read url done! 36 | return image; 37 | } 38 | } 39 | //---------------------------------end-------------------------------------- 40 | /* 41 | * public static int[] balancing(BufferedImage _image) { int _histogram[] = 42 | * histogtam(_image); int _factor[] = new int[256]; _factor = new 43 | * Unitys().randArray(_factor, 0); long sum = 0; float scale = (float) (255.0 / 44 | * (_image.getWidth() * _image.getHeight())); 45 | * 46 | * for (int i = 0; i < _factor.length; i++) { sum += _histogram[i]; int value = 47 | * (int) (sum * scale); if (value > 255) { _factor[i] = 255; } else { _factor[i] 48 | * = value; } } return _factor; 49 | * 50 | * } 51 | * 52 | * public static BufferedImage balancingImg(BufferedImage _image) { int 53 | * new_Histogram[] = balancing(_image); BufferedImage output = 54 | * Unitys.copyImage(_image); int r, g, b, rgb; for (int i = 0; i < 55 | * _image.getWidth(); i++) { for (int j = 0; j < _image.getHeight(); j++) { int 56 | * p = RGB.getRGBExtended(_image, i, j); r = (p >> 16) & 0xff; g = (p >> 8) & 57 | * 0xff; b = (p & 0xff); 58 | * 59 | * r = new_Histogram[r]; g = new_Histogram[g]; b = new_Histogram[b]; 60 | * 61 | * r = (r << 16); g = (g << 8); b = (b); 62 | * 63 | * rgb = r + g + b; 64 | * 65 | * output.setRGB(i, j, rgb); } 66 | * 67 | * } 68 | * 69 | * return output; 70 | * 71 | * } 72 | * 73 | * 74 | */ 75 | -------------------------------------------------------------------------------- /src/image2d/RGB.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.image.BufferedImage; 8 | 9 | public class RGB { 10 | 11 | public static int getRGBW(BufferedImage image, int i, int j) { 12 | int width = image.getWidth(); 13 | int height = image.getHeight(); 14 | i = Math.max(0, Math.min(width - 1, i)); 15 | j = Math.max(0, Math.min(height - 1, j)); 16 | return image.getRGB(i, j); 17 | } 18 | 19 | 20 | public static int getRGBH(BufferedImage image, int i, int j) { 21 | int width = image.getWidth(); 22 | int height = image.getHeight(); 23 | j = Math.max(0, Math.min(width - 1, j)); 24 | i = Math.max(0, Math.min(height - 1, i)); 25 | return image.getRGB(i, j); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/image2d/Threshold.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.Color; 8 | import java.awt.image.BufferedImage; 9 | 10 | /** 11 | * 12 | * @author pratchaya 13 | */ 14 | public class Threshold { 15 | 16 | public static BufferedImage apply(BufferedImage _image) { 17 | int _r, p, r, g, b; 18 | double threshold = otsuTreshold(_image); 19 | BufferedImage imageOutput = new BufferedImage(_image.getWidth(), _image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); // Set initial BufferedImage 20 | for (int i = 0; i < _image.getWidth(); i++) { 21 | for (int j = 0; j < _image.getHeight(); j++) { 22 | 23 | // Get pixels 24 | r = RGB.getRGBW(_image, i, j); 25 | r = ((r >> 16) & 0xff); 26 | 27 | if (r > threshold) { 28 | p = 255; 29 | } else { 30 | p = 0; 31 | } 32 | p = (p << 16) | (p << 8) | (p); 33 | imageOutput.setRGB(i, j, p); 34 | 35 | } 36 | } 37 | 38 | return imageOutput; 39 | } 40 | 41 | public static int otsuTreshold(BufferedImage _image) { 42 | int _histogram[] = Histogram.histogtam(_image); 43 | 44 | int total = _image.getWidth() * _image.getHeight(); 45 | float sum = 0; 46 | for (int i = 0; i < 256; i++) { 47 | sum += i * _histogram[i]; 48 | } 49 | float sum_bg = 0; 50 | int wight_bg = 0, wight_fg = 0; 51 | 52 | float varMax = 0; 53 | int threshold = 0; 54 | 55 | for (int i = 0; i < 256; i++) { 56 | wight_bg += _histogram[i]; 57 | if (wight_bg == 0) { 58 | continue; 59 | } 60 | wight_fg = total - wight_bg; 61 | 62 | if (wight_fg == 0) { 63 | break; 64 | } 65 | 66 | sum_bg += (float) (i * _histogram[i]); 67 | float mean_bg = sum_bg / wight_bg; 68 | float mean_fg = (sum - sum_bg) / wight_fg; 69 | float varBetween = (float) wight_bg * (float) wight_fg * (mean_bg - mean_fg) * (mean_bg - mean_fg); 70 | if (varBetween > varMax) { 71 | varMax = varBetween; 72 | threshold = i; 73 | } 74 | } 75 | return threshold; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/image2d/Unitys.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this template, choose Tools | Templates 3 | * and open the template in the editor. 4 | */ 5 | package image2d; 6 | 7 | import java.awt.geom.AffineTransform; 8 | import java.awt.image.AffineTransformOp; 9 | import java.awt.image.BufferedImage; 10 | import java.awt.image.ColorModel; 11 | import java.awt.image.WritableRaster; 12 | 13 | /** 14 | * 15 | * @author pratchaya 16 | */ 17 | public class Unitys { 18 | 19 | private static int IMAGE_TYPE; 20 | 21 | //----------------------------------- helper method--------------------------------- 22 | // use to copy image 23 | public static BufferedImage copyImage(BufferedImage _image) { 24 | ColorModel cm = _image.getColorModel(); 25 | boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); 26 | WritableRaster raster = _image.copyData(null); 27 | return new BufferedImage(cm, raster, isAlphaPremultiplied, null); 28 | 29 | } 30 | 31 | //------------------- 32 | public int operation_Number(String operator, int operand1, int operand2) { 33 | int _num = 0; 34 | try { 35 | _num = (operator.equals("+")) ? operand1 + operand2 36 | : (operator.equals("-")) ? operand1 - operand2 : (operator.equals("*")) ? operand1 * operand2 37 | : (operator.equals("/") && operand2 != 0) ? operand1 / operand2 : operand1 / operand2; 38 | 39 | } catch (ArithmeticException e) { 40 | e.getMessage(); 41 | } 42 | return _num; 43 | 44 | } 45 | 46 | //-------------- set value array2D --------------------------// 47 | public int[][] randArray(int arr[][], int val) { 48 | for (int i = 0; i < arr.length; i++) { 49 | for (int j = 0; j < arr.length; j++) { 50 | // set value 51 | arr[i][j] = val; 52 | } // end j 53 | } // end i 54 | return arr; 55 | } 56 | 57 | public int[] randArray(int arr[], int val) { 58 | for (int i = 0; i < arr.length; i++) { 59 | arr[i] = val; 60 | } 61 | return arr; 62 | } 63 | 64 | public int getRGBExtended(BufferedImage image, int row, int col) { 65 | int width = image.getWidth(); 66 | int height = image.getHeight(); 67 | row = Math.max(0, Math.min(height - 1, row)); 68 | col = Math.max(0, Math.min(width - 1, col)); 69 | return image.getRGB(col, row); 70 | } 71 | } 72 | --------------------------------------------------------------------------------