现在的位置: 首页 > 综合 > 正文

图像的灰度化,直方图均衡化

2018年01月30日 ⁄ 综合 ⁄ 共 9128字 ⁄ 字号 评论关闭

它的核心思想就是让图像暗的地方变亮,亮的地方变暗。问题是,如果图像原本的亮暗程度就非常符合人眼的观察结果,那么直方图均衡化之后的图像就变的很糟。所以该方法要依据图像数据的特点而定。

图像整体变亮,暗处的细节得到了突出:

import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.*; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.*; 

public class chongcaiyang extends Frame{ 
Image im, tmp; 
int iw, ih; 
int[] pixels; 
boolean flag_load = false; 
//构造方法 
public chongcaiyang(){ 
super("chongcaiyang"); 
Panel pdown; 
    Button load, run, save, quit; 
    addWindowListener(new WindowAdapter(){ 
    public void windowClosing(WindowEvent e){ 
    System.exit(0); 
    } 
    }); 
    
    pdown = new Panel(); 
    pdown.setBackground(Color.lightGray); 
    //定义按钮 
    load = new Button("装载图像");    
    run = new Button("重采样"); 
    save = new Button("保存"); 
    quit = new Button("退出"); 
    
    this.add(pdown, BorderLayout.SOUTH); 
    //添加按钮 此处的顺序为案板上的左->右的顺序 
    pdown.add(load);    
    pdown.add(run); 
    pdown.add(save); 
    pdown.add(quit); 
        //按钮的动作程序  装载图像 
    load.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    try { 
jLoad_ActionPerformed(e); 
} catch (IOException e1) { 
e1.printStackTrace(); 
} 
    } 
    }); 
    //按钮的动作程序  重采样 
    run.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    try { 
jRun_ActionPerformed(e); 
} catch (IOException e1) { 
// TODO Auto-generated catch block 
e1.printStackTrace(); 
} 
    } 
    }); 
    //按钮的动作程序 保存 
    save.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    try { 
jSave_ActionPerformed(e); 
} catch (IOException e1) { 
e1.printStackTrace(); 
} 
    } 
    }); 
    //按钮的动作程序  退出 
    quit.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    jQuit_ActionPerformed(e); 
    } 
    }); 
} 
//按钮动作的实现  加载图像 
    public void jLoad_ActionPerformed(ActionEvent e) throws IOException{    
    File inputFile = new File("d:\\java\\sc\\lena_grey.jpg"); 
        BufferedImage input = ImageIO.read(inputFile); 
tmp = input; 
        flag_load = true; 
        repaint(); 
} 
  //按钮动作的实现  重采样 
  public void jRun_ActionPerformed(ActionEvent e) throws IOException{    
  if(flag_load){ 
  File inputFile = new File("d:\\java\\sc\\lena_grey.jpg"); 
          BufferedImage input = ImageIO.read(inputFile); 
          iw = input.getWidth(this); 
          ih = input.getHeight(this); 
  //设定N值 
  int N = iw; 
  String s = JOptionPane.showInputDialog(null,"请输入N值(512/256/128/64/32/16/8)"); 
  if(s!= null&& !s.equals("")){ 
  N = Integer.parseInt(s); 
  } 
  //检查输入是否正确 
  if((N>512)|(N<8)){ 
  N = 512; 
  JOptionPane.showMessageDialog(null, "输入不正确,请重新输入!"); 
  } 
               //图像重采样 
  BufferedImage grayImage = new BufferedImage(iw, ih, 
BufferedImage.TYPE_BYTE_GRAY); 
  //kao!三个循环就就能搞定,不就是重采样吗? 
for(int i=0; i<ih-1; i++){ 
for(int j=0; j<iw-1; j=j+(ih/N)){ 
for(int k=0; k<(ih/N); k++){ 
int rgb = input.getRGB(i, j);  
  int grey = (int) (0.3*((rgb&0xff0000)>>16)+0.59*((rgb&0xff00)>>8)+0.11*((rgb&0xff))); 
  rgb = 255<<24|grey<<16|grey<<8|grey; 
  grayImage.setRGB(i, j+k, rgb); 
} 
} 
} 
                //产生图像 
  tmp = grayImage; 
  flag_load = true; 
  repaint(); 
  }else{ 
  JOptionPane.showMessageDialog(null, "先点击“装载图像”,3Q!","提示:", 
          JOptionPane.WARNING_MESSAGE); 
  } 
  } 
  //按钮动作的实现保存 
  public void jSave_ActionPerformed(ActionEvent e) throws IOException{    
        if(flag_load){ 
        
    BufferedImage bi = new BufferedImage(tmp.getWidth(null),tmp.getHeight(null), 
    BufferedImage.TYPE_INT_RGB); 
            Graphics g = bi.getGraphics(); 
            g.drawImage(tmp,0, 0,null); 
            g.dispose(); 
    
      File save_path=new File("d:\\java\\sc\\save_t01.jpg"); 
            ImageIO.write(bi, "JPG", save_path); 

  }else{ 
  JOptionPane.showMessageDialog(null, "先点击“装载图像”,3Q!","提示:", 
  JOptionPane.WARNING_MESSAGE); 
  } 
  } 
  //按钮动作的实现  退出 
  public void jQuit_ActionPerformed(ActionEvent e){ 
  System.exit(0); 
  } 
  //绘图函数 
  public void paint(Graphics g){ 
  //if(flag_Load){ 
  g.drawImage(tmp,50,50,this); 
  //}else{} 
  } 
  
public static void main(String[] args) { 
chongcaiyang ti = new chongcaiyang(); 
ti.setSize(1000,860); 
ti.setVisible(true); 
} 
} 

 

 

import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.*; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.*; 

public class hist extends Frame{ 
Image im, tmp; 
int iw, ih; 
int[] pixels; 
boolean flag_load = false; 
boolean flag_grey = false; 
//hist的构造方法 
public hist(){ 
this.setTitle("直方图均衡化"); 
Panel pdown; 
Button load, grey, hist, run, save, quit; 
//添加窗口监听事件 
addWindowListener(new WindowAdapter(){ 
public void windowClosing(WindowEvent e){ 
System.exit(0); 
} 
} 
); 
    pdown = new Panel(); 
    pdown.setBackground(Color.LIGHT_GRAY); 
    //按钮名称 
    load = new Button("装载图像"); 
    grey = new Button("灰度图像"); 
    hist = new Button("直方图"); 
    run = new Button("均衡化"); 
    save = new Button("保存"); 
    quit = new Button("退出"); 
    
    this.add(pdown, BorderLayout.SOUTH); 
    //增加按钮 
    pdown.add(load); 
    pdown.add(grey); 
    pdown.add(hist); 
    pdown.add(run); 
    pdown.add(save); 
    pdown.add(quit); 
    //按钮的动作程序  装载图像 
    load.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    try { 
       jLoad_ActionPerformed(e); 
    } catch (IOException e1) { 
       e1.printStackTrace(); 
    } 
    } 
    }); 
    //按钮的动作程序  灰度化 
    grey.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    try { 
jGrey_ActionPerformed(e); 
} catch (IOException e1) { 
e1.printStackTrace(); 
} 
    } 
    }); 
    //按钮的动作程序  直方图 
    hist.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    jHist_ActionPerformed(e); 
    } 
    }); 
    //按钮的动作程序 直方图均衡化 
    run.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    jRun_ActionPerformed(e); 
    } 
    }); 
    //按钮的动作程序 保存 
    save.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    try { 
jSave_ActionPerformed(e); 
} catch (IOException e1) { 
e1.printStackTrace(); 
} 
    } 
    }); 
    //按钮的动作程序  退出 
    quit.addActionListener(new ActionListener(){    
    public void actionPerformed(ActionEvent e){ 
    jQuit_ActionPerformed(e); 
    } 
    });    
} 
//按钮动作的实现  加载图像 
    public void jLoad_ActionPerformed(ActionEvent e) throws IOException{    
    File inputFile = new File("d:\\java\\sc\\source.jpg"); 
        BufferedImage input = ImageIO.read(inputFile); 
        
        im = input; 
tmp = input; 
        flag_load = true; 
        repaint(); 
} 
    //按钮动作的实现  灰度化 
    public void jGrey_ActionPerformed(ActionEvent e) throws IOException{ 
if(flag_load){ 
File inputFile = new File("d:\\java\\sc\\source.jpg"); 
  BufferedImage input = ImageIO.read(inputFile); 
  iw = input.getWidth(this); 
      ih = input.getHeight(this); 
      pixels = new int[iw*ih]; 
      
BufferedImage grayImage = new BufferedImage(iw, ih, 
  BufferedImage.TYPE_BYTE_GRAY); 
for(int i=0; i<iw; i++){ 
  for(int j=0; j<ih; j++){ 
  int rgb = input.getRGB(i, j);  
  int grey = (int) (0.3*((rgb&0xff0000 )>>16)+0.59*((rgb&0xff00 )>>8)+0.11*((rgb&0xff))); 
  rgb = 255<<24|grey<<16|grey<<8|grey; 
  grayImage.setRGB(i, j, rgb); 
  } 
  } 
  tmp = grayImage; 
  try{ 
    PixelGrabber pg = new PixelGrabber(tmp,0,0,iw,ih,pixels,0,iw); 
    pg.grabPixels(); 
    }catch(InterruptedException e3){ 
    e3.printStackTrace(); 
    } 
  flag_grey = true; 
  repaint(); 
} else{ 
JOptionPane.showMessageDialog(null, "先点击“装载图像”,3Q!","提示:", 
JOptionPane.WARNING_MESSAGE); 
} 
} 
    //按钮动作的实现 直方图显示 调用histshow这个类进行操作 
    public void jHist_ActionPerformed(ActionEvent e){ 
    histshow h = new histshow(); 
    h.getData(pixels, iw, ih); 
    h.setSize(480,350); 
    h.setVisible(true); 
    
    } 
  //按钮动作的实现 直方图均衡化 
    public void jRun_ActionPerformed(ActionEvent e){ 
    if(flag_load&&flag_grey){ 
    try{ 
    PixelGrabber pg = new PixelGrabber(tmp,0,0,iw,ih,pixels,0,iw); 
    pg.grabPixels(); 
    }catch(InterruptedException e3){ 
    e3.printStackTrace(); 
    } 
    BufferedImage greyImage = new BufferedImage(iw, ih, 
BufferedImage.TYPE_BYTE_GRAY); 
    //获取图像的直方图 
    int[] histogram = new int[256]; 
    for(int i=0; i<ih-1; i++){ 
    for(int j=0; j<iw-1; j++){ 
    int grey = pixels[i*iw+j]&0xff; 
    histogram[grey]++; 
    } 
    } 
    //直方图均衡化 
    double a = (double)255/(iw*ih); 
    double[] c = new double [256]; 
    c[0] = (a*histogram[0]); 
    for(int i=1; i<256; i++){ 
    c[i] = c[i-1]+(int)(a*histogram[i]); 
    } 
    for(int i=0; i<ih; i++){ 
    for(int j=0; j<iw; j++){ 
    int grey = pixels[i*iw+j]&0x0000ff; 
    int hist = (int)(c[grey]); 
    pixels[i*iw+j] = 255<<24|hist<<16|hist<<8|hist; 
    greyImage.setRGB(j, i, pixels[i*iw+j]); 
    } 
    } 
    tmp = greyImage; 
  flag_load = true; 
  repaint(); 
    }else{ 
JOptionPane.showMessageDialog(null, "先点击“装载图像”,3Q!","提示:", 
JOptionPane.WARNING_MESSAGE); 
} 
    } 

  //按钮动作的实现保存 
  public void jSave_ActionPerformed(ActionEvent e) throws IOException{    
        if(flag_load){ 
        
    BufferedImage bi = new BufferedImage(tmp.getWidth(null),tmp.getHeight(null), 
    BufferedImage.TYPE_INT_RGB); 
            Graphics g = bi.getGraphics(); 
            g.drawImage(tmp,0, 0,null); 
            g.dispose(); 
    
      File save_path=new File("d:\\java\\sc\\save_t01.jpg"); 
            ImageIO.write(bi, "JPG", save_path); 
  }else{ 
  JOptionPane.showMessageDialog(null, "先点击“装载图像”,3Q!","提示:", 
  JOptionPane.WARNING_MESSAGE); 
  } 
  } 
   //按钮动作的实现  退出 
  public void jQuit_ActionPerformed(ActionEvent e){ 
    System.exit(0); 
  } 
    //绘图函数 
  public void paint(Graphics g){ 
    //if(flag_Load){ 
    g.drawImage(tmp,50,50,this); 
   //}else{} 
  } 
  
 public static void main(String[] args) { 
  hist ti = new hist(); 
  ti.setSize(900,860); 
  ti.setVisible(true); 
 } 
} 

 

 

import java.awt.*; 
import java.awt.event.*; 
import java.awt.Window; 

public class histshow extends Frame{ 
int data[]; 
int histogram[] = new int[256]; 

public histshow(){ 
this.setTitle("图像的灰度直方图"); 
Panel pdown; 
Button quit; 
pdown = new Panel(); 
quit = new Button("关闭窗口"); 
this.add(pdown, BorderLayout.SOUTH); 
pdown.add(quit); 
quit.addActionListener(new ActionListener(){ 
public void actionPerformed(ActionEvent e){ 
jQuit_ActionPerformed(e); 
} 
}); 
// 添加窗口监听事件 
addWindowListener(new WindowAdapter(){ 
public void windowClosing(WindowEvent e){ 
histshow.this.dispose(); 
} 
}); 
} 
public void jQuit_ActionPerformed(ActionEvent e){ 
this.setVisible(false); 
} 
public void getData(int[] data, int iw, int ih){ 
this.data = data; 
for (int i = 0; i < iw * ih; i++){ 
int grey = data[i] & 0xff; 
histogram[grey]++; 
} 

// 找出最大的数,进行标准化. 
int temp = histogram[0]; 
for (int i = 0; i < 256; i++){ 
if (temp <= histogram[i]){ 
temp = histogram[i]; 
//System.out.println(temp); 
} 
} 
for (int i = 0; i < 256; i++){ 
histogram[i] = histogram[i] * 200 / temp; 
//System.out.println(temp); 
} 
} 
//画出直方图 
public void paint(Graphics g){ 
// 画出水平和垂直的轴 
g.drawLine(100, 250, 356, 250); 
g.drawLine(100, 50, 100, 250); 
// 画出横轴坐标 
g.drawString("0", 98, 263); 
g.drawString("50", 145, 263); 
g.drawString("100", 193, 263); 
g.drawString("150", 243, 263); 
g.drawString("200", 293, 263); 
g.drawString("250", 343, 263); 
// 画出纵轴坐标 
g.drawString("0.5", 83, 145); 
g.drawString("1", 90, 60); 
// 画出图像的直方图 
for (int i = 0; i < 256; i++){ 
g.drawLine(100 + i, 250, 100 + i, 250 - histogram[i]); 
} 
g.drawString("该图像的灰度直方图如上所示.", 160, 280); 
} 
} 

 

抱歉!评论已关闭.