Realization of histogram equalization in java

In the experiment of digital image processing, most of my classmates use MATLAB, because there are few codes about java implementation found on the Internet, but I prefer java implementation. However, they still refer to the code on the Internet, but they didn't say how to use buffer image. I chewed the source code myself, and it took me two hours to get it out. No more nonsense, just code.

The TransF class is used to achieve equalization:

import java.awt.image.BufferedImage;

public class TransF {
    double[] count = new double[256];//Number of gray values recorded
    double[] Count = new double[256];//Statistical gray value of new graph
    double[] NSK=new double[256];//Transformation function
    public  BufferedImage run(BufferedImage image) {
        double H,S,I;
        int width = image.getWidth();
        int height = image.getHeight();
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int j = 0; j < height; j++) {
            for(int i=0; i<width; i++) {
                Object data=image.getRaster().getDataElements(i,j,null);
                int red = image.getColorModel().getRed(data);
                int blue = image.getColorModel().getBlue(data);
                int green = image.getColorModel().getGreen(data);
                I= ((double)(red+green+blue)/(double)3);
                if (count[(int)I]==0){
                    count[(int)I]=1;
                }else {
                    count[(int)I]+=1;
                }
            }
        }
        double[] Pr=new double[256];//Calculate the occurrence probability of each gray value
        for (int i=0;i<256;i++){
            Pr[i]=(double)count[i]/(double)(width*height);
        }
        double[] sk = new double[256];//Cumulative probability
        for (int i=0;i<256;i++){
            for (int j=0;j<=i;j++){
                sk[i]+=Pr[j];
            }
        }
        for (int i=0;i<256;i++){
            NSK[i]=(255*sk[i]+0.5);
        }
        int[] rgb=new int[3];
        for (int j=0;j<height;j++){
            for(int i=0;i<width;i++){
                Object data=image.getRaster().getDataElements(i,j,null);//Get rgb value of image points
                int red = image.getColorModel().getRed(data);
                int blue = image.getColorModel().getBlue(data);
                int green = image.getColorModel().getGreen(data);
                int Alpha = image.getColorModel().getAlpha(data);
                if (green>blue){//Set of formula calculation H
                    H=Math.acos((red-green+red-blue)
                            /(2.0*Math.sqrt((red-green)*(red-green)+(red-blue)*(green-blue))));
                }else{
                    H=2.0*Math.PI-Math.acos((red-green+red-blue)
                            /(2.0*Math.sqrt((red-green)*(red-green)+(red-blue)*(green-blue))));
                }
                I= ((double)(red+green+blue)/(double)3);
                I=NSK[(int)I];//I transformed i

                if (Count[(int)I]==0){
                    Count[(int)I]=1;
                }else {
                    Count[(int)I]+=1;
                }
                if (red==green&&green==blue){//Processing of black and white image
                    rgb[0]=(int)I;
                    rgb[1]=(int)I;
                    rgb[2]=(int)I;
                }else {     //Processing of color image
                    S = 1 - ((double) 3 / (double) (red + green + blue)) * (double) red;//Calculate S
                    if(H<=2.09){
                        rgb[0]=(int)(I*(1.0+(S*Math.cos(H))/Math.cos((Math.PI/3.0)-H)));
                        rgb[0]=rgb[0]>255?255:rgb[0];
                        rgb[0]=rgb[0]<0?0:rgb[0];
                        rgb[2]=(int)(I*(1.0-S));
                        rgb[2]=rgb[2]<0?0:rgb[2];
                        rgb[2]=rgb[2]>255?255:rgb[2];
                        rgb[1]=(int)(3.0*I-rgb[0]-rgb[2]);
                        rgb[1]=rgb[1]>255?255:rgb[1];
                        rgb[1]=rgb[1]<0?0:rgb[1];
                    }else if(H>2.09&&H<=4.18){
                        rgb[1]=(int)(I*(1.0+(S*Math.cos(H-(Math.PI*2.0/3.0)))/Math.cos((Math.PI)-H)));
                        rgb[1]=rgb[1]>255?255:rgb[1];
                        rgb[1]=rgb[1]<0?0:rgb[1];
                        rgb[0]=(int)(I*(1.0-S));
                        rgb[0]=rgb[0]>255?255:rgb[0];
                        rgb[0]=rgb[0]<0?0:rgb[0];
                        rgb[2]=(int)(3.0*I-rgb[0]-rgb[1]);
                        rgb[2]=rgb[2]>255?255:rgb[2];
                        rgb[2]=rgb[2]<0?0:rgb[2];
                    }else if(H>4.18){
                        rgb[2]=(int)(I*(1.0+(S*Math.cos(H-(Math.PI*4.0/3.0)))/Math.cos((Math.PI*5.0/3.0)-H)));
                        rgb[2]=rgb[2]>255?255:rgb[2];
                        rgb[2]=rgb[2]<0?0:rgb[2];
                        rgb[1]=(int)(I*(1.0-S));
                        rgb[1]=rgb[1]>255?255:rgb[1];
                        rgb[1]=rgb[1]<0?0:rgb[1];
                        rgb[0]=(int)(3.0*I-rgb[1]-rgb[2]);
                        rgb[0]=rgb[0]>255?255:rgb[0];
                        rgb[0]=rgb[0]<0?0:rgb[0];
                    }
                }
                int srgb=Alpha<<24|rgb[2]<<16|rgb[1]<<8|rgb[0];
                result.setRGB(i,j, srgb);
            }
        }
        return result;
    }
}

Chart class, used to draw histogram and gray transformation curve:

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;

import java.io.File;
import java.io.IOException;
import java.lang.Integer;

public class Chart
{
    public void createBarChart(String filePath,double[] count,String rowKey)
    {
        filePath+="histogram.jpg";
        try
        {
            DefaultCategoryDataset dataset = new DefaultCategoryDataset();
            for(int i=0;i<count.length;i++){
                Integer I=new Integer(i);
                dataset.addValue(count[i], rowKey,I.toString());
            }
            JFreeChart chart = ChartFactory.createBarChart3D("Gray histogram", "Gray value",
                    "Number", dataset, PlotOrientation.VERTICAL, true, true, false);

            ChartUtilities.saveChartAsJPEG(new File(filePath), chart, 400, 300);
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    public void createLineChart(String filePath,double[] NSK){
        filePath+="Gray transformation curve.jpg";
        try
        {
            DefaultCategoryDataset dataset = new DefaultCategoryDataset();
            for(int i=0;i<NSK.length;i++){
                Integer I=new Integer(i);
                dataset.addValue(NSK[i], "Grayscale transformation",I.toString());
            }
            JFreeChart chart = ChartFactory.createLineChart("Gray transformation curve", "Original gray value",
                    "Gray value after transformation", dataset, PlotOrientation.VERTICAL, true, false, false);

            ChartUtilities.saveChartAsJPEG(new File(filePath), chart, 500, 500);
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

Main categories:

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Scanner;

public class JunHeng{
/*made by ☆bright
2020.03.16
*/

    public static void main(String[] args) throws Exception{
        boolean flag=true;
        while (flag){
            Scanner scanner=new Scanner(System.in);
            System.out.println("Input 1 for equalization, input 2 for exit:");
            String type=scanner.nextLine();
            if(type.equals("2")){
                flag=false;
            }
            else {
                System.out.println("Enter the path to process the image:");
                String inputPath=scanner.nextLine();
                System.out.println("Please enter the path to save the processing results:");
                String outputPath=scanner.nextLine();
                TransF transF=new TransF();
                File inputFile=new File(inputPath);
                BufferedImage input = ImageIO.read(inputFile);
                BufferedImage result=transF.run(input);
                File outputFile=new File(outputPath);
                ImageIO.write(result, "JPG", outputFile);

                double[] count=transF.count;
                double[] Count=transF.Count;
                double[] NSK=transF.NSK;
                Chart chart =new Chart();
                chart.createBarChart(inputPath,count,"Gray value of original image");
                chart.createBarChart(outputPath,Count,"Gray value of new image");
                chart.createLineChart(outputPath,NSK);
            }
        }
    }
}

After that, I will list some of the problems I have encountered, hoping to help you.
1. I plan to use java to finish my work, but I don't know how to read and write image files in Java. I use the Internet to look up the data. Most of Java uses the File class to read in the image, and then uses the BufferedImage class to process the image. But there are few on the Internet about the usage of buffered image. I will check the source code and Java manual later. We have roughly understood that it stores pixel values through Raster (through matrix), and it can obtain brg+a values through get method. After getting the rgb value, I can do the subsequent calculation.
2. It is found in the calculation that the pixels at (0,0) are incomplete without red. After reading the data, we found that the pixels at (0,0) position were ignored.
3. The conversion from HSI to RGB is a difficulty, because we do not know the formula, then we can find the formula on the Internet and apply it. There are also some precautions: do not handle RGB exceeding 255 and 0.
4. In Java, I get red, green, blue and Alpha. For these four quantities, I need to know how to pass data of type int into ColorModel. Because the return image type I set is: Type > int > RGB. Its source code is as follows:
I know that this type of image inserts byte data into A single byte array in the order of byte address from low to high in each pixel.
Therefore, the rgb calculation formula of BufferedImagergb is obtained: rgb = alpha < 24|blue < 16|green < 8|red;

There is no problem in other aspects, because there are ready-made formulas, only a set of formulas is needed.

Published 12 original articles, won praise 2, visited 201
Private letter follow

Tags: Java MATLAB

Posted on Mon, 16 Mar 2020 04:23:25 -0400 by scottlowe