java中的直方图均衡化

时间:2012-12-21 22:27:35

标签: java bufferedimage

我尝试编译以下代码,但我发现只有我输入用于测试的所有图像,图像变为全黑。

P.S。我是Java新手,除了内置软件包

,我不允许使用任何软件包
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.*;

public class ImageProcessor
{   
public static BufferedImage convert(Image img)
{
    BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
    Graphics bg = bi.getGraphics();
    bg.drawImage(img, 0, 0, null);
    bg.dispose();
    return bi;
}

public static BufferedImage toGrayScale(Image img)
{
    // Convert image from type Image to BufferedImage
    BufferedImage bufImg = convert(img);

    // Scan through each row of the image
    for(int j=0; j < bufImg.getHeight(); j++)
    {
        // Scan through each columns of the image
        for(int i=0; i < bufImg.getWidth(); i++)
        {
            // Returns an integer pixel in the default RGB color model
            int values=bufImg.getRGB(i,j);
            // Convert the single integer pixel value to RGB color
            Color oldColor = new Color(values);

            int red = oldColor.getRed();        // get red value
            int green = oldColor.getGreen();    // get green value
            int blue = oldColor.getBlue();  // get blue value

            // Convert RGB to gray scale using formula
            // gray = 0.299 * R + 0.587 * G + 0.114 * B
            double grayVal = 0.299*red + 0.587*green + 0.114*blue;

            // Assign each channel of RGB with the same value
            Color newColor = new Color((int)grayVal, (int)grayVal, (int)grayVal);

            // Get back the integer representation of RGB color
            // and assign it back to the original position
            bufImg.setRGB(i, j, newColor.getRGB());
        }
    }
    // return back the resulting image in BufferedImage type
    return bufImg;
}

public static BufferedImage histEqualization(Image img)
{
    //Convert image to BufferedImage
    img = ImageProcessor.toGrayScale(img);
    BufferedImage bufImg = convert(img);


    //Getting information of each pixel;
    int[][] intensity = new int[bufImg.getWidth()][ bufImg.getHeight()];
    int[] counter = new int[256];
    for(int j=0; j < bufImg.getHeight();j++)
        for(int i=0; i < bufImg.getWidth();i++)
        {
            int values=bufImg.getRGB(i,j);              
            Color oldColor = new Color(values);
            intensity[i][j] = oldColor.getBlue();
            counter[intensity[i][j]]++;
        }

    //BEGIN OF Histogram Equalization

    //find out how many rows the table have
    int row=0;

    for(int i=0;i<256;i++)
        if(counter[i]!=0)
            row++;

    //Find out the v column of the table
    //table[row][0] = v column
    //table[row][1] = c column
    int temp=0;
    int[][] table = new int[row][2];


    for(int i=0;i<256;i++)
        if(counter[i]!=0)
        {
            table[temp][0] = i;
            temp++;
        }

    //Find out the c column of the table
    for(int i=0;i<row;i++)
        table[i][1] = counter[table[i][0]];

    //C-> CS

    int sum = 0;

    for(int i=0;i<row;i++)
    {
        sum += table[i][1];
        table[i][1] = sum;
    }

    //CS->NCS
    int min = table[0][1], max = table[row-1][1];

    for(int i=0;i<row;i++)
        table[i][1] = Math.round((table[i][1]-min)/(max-min));

    //Mapping
    for(int j=0;j<bufImg.getHeight();j++)
        for(int i=0;i<bufImg.getWidth();i++)
        {
            for(int k=0;k<row;k++)
                if(intensity[i][j]==table[k][0])
                    intensity[i][j] = table[k][1];

            Color newColor = new Color(intensity[i][j], intensity[i][j], intensity[i][j]);

            bufImg.setRGB(i, j, newColor.getRGB());
        }


    return bufImg;
}

}

1 个答案:

答案 0 :(得分:0)

转换方法可以简化为:

return new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_BYTE_GRAY) ;

因为您只想要一个灰度(单通道)图像。那么toGrayScale的方法是:

 BufferedImage bufImg = convert(img);
 byte[] bufferbyte = ((DataBufferByte) bufImg.getRaster().getDataBuffer()).getData() ;
 for(int j=0, pos=0; j < bufImg.getHeight(); j++)
      for(int i=0; i < bufImg.getWidth(); i++, pos++)
           {
           int red   = bufImg().getSample(i, j, 0) ;
           int green = bufImg().getSample(i, j, 1) ;
           int blue  = bufImg().getSample(i, j, 2) ;
           // gray = 0.299 * R + 0.587 * G + 0.114 * B
           bufferbyte[pos] = (byte)(int)(0.299*red + 0.587*green + 0.114*blue) ;
           }
return bufImg ;

我使用Raster()来获取RBG值,但是直接访问DataBuffer会更快(比如缓冲区)。

然后你可以进行直方图均衡,但第一行是错误的,应该删除。