`
hello_wangfeng
  • 浏览: 32265 次
社区版块
存档分类
最新评论

直方图均衡化的java代码

阅读更多
自我感觉直方图均衡化作用并不是很大,有的时候甚至会适得其反。它的核心思想就是让图像暗的地方变亮,亮的地方变暗。问题是,如果图像原本的亮暗程度就非常符合人眼的观察结果,那么直方图均衡化之后的图像就变的很糟。所以该方法要依据图像数据的特点而定。先看一下效果比较好的案例:
彩色的lena图像:lena_color.jpg




将彩色lena变为灰度lena:




对灰度lena进行直方图均衡化,结果如下,可以看出,图像整体变亮,暗处的细节得到了突出:





但是对于某些图像,尤其是亮背景的图像,本来前景和背景有很好的区分,但是直方图均衡化之后,亮的背景变暗,图像灰度成平稳过渡状态,反而不利于图像信息的展示,如下图:girl.jpg:





直方图均衡化后,结果如下,可以看到,结果并不理想:







package p01;

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("E:\\f2\\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("E:\\f2\\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("E:\\f2\\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);
	}
}

//上面的代码应用到了histshow类,如下:

package p01;

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);
	}
}
  • 大小: 11.1 KB
  • 大小: 13.9 KB
  • 大小: 30.6 KB
  • 大小: 19.9 KB
  • 大小: 22.9 KB
  • 大小: 20.5 KB
  • 大小: 20.3 KB
  • 大小: 21.1 KB
  • 大小: 17.3 KB
分享到:
评论
1 楼 探花郎 2013-07-22  
最近在做数字图像处理的大作业,需要做出直方图的均衡化和规定化。在你程序的基础上怎么做菜能实现直方图的规定化。望您不吝赐教。

相关推荐

    直方图均衡化

    此外,虽然本文主要介绍了C#和OpenCV的实现,但直方图均衡化也可以在其他编程语言(如Python、Java等)和库(如OpenCV、PIL等)中实现,基本原理和步骤都是相同的。 在实际应用中,直方图均衡化常用于医学图像分析...

    灰度图像的直方图均衡化

    Java虽然不像MATLAB那样有内置的图像处理函数库,但可以利用如Java Advanced Imaging (JAI)库或者OpenCV库来实现图像处理功能,包括直方图均衡化。 在实际应用中,直方图均衡化可以用于医学图像分析、遥感图像处理...

    JAVA实现直方图的均衡化Java实用源码整理learns

    本资源主要探讨了如何使用Java实现这一过程,对于学习和理解直方图均衡化的原理及其在Java中的应用具有很高的价值。 直方图是描述图像中各灰度级出现频率的图形,它可以帮助我们直观地了解图像的整体亮度分布。直方...

    用opencv完成对图像和视频的边缘检测和直方图均衡化等操作

    本项目聚焦于使用OpenCV在VC++环境下实现图像和视频的边缘检测以及直方图均衡化。以下是对这些核心概念的详细阐述。 1. **OpenCV库**:OpenCV是一个跨平台的计算机视觉库,包含了大量的图像处理和计算机视觉算法,...

    数字图像处理中直方图均衡化实现

    在数字图像处理领域,直方图均衡化是一种重要的图像增强技术,它通过对图像像素值的重分布来改善图像的整体对比度...通过理解直方图均衡化的基本原理和Java代码实现,我们可以更好地应用这项技术来改进图像的视觉效果。

    Java/Matlab灰度图像的直方图均衡化、图像分割

    在图像处理领域,直方图均衡化和图像分割是两个重要的技术,特别是在处理灰度图像时。本项目涉及了从彩色图像转换到灰度图像,分析图像的灰度分布,执行直方图均衡化,以及基于直方图的图像分割过程。以下是这些概念...

    zhifangtujunhenghua.rar_直方图均衡化

    直方图均衡化是一种在数字图像处理中广泛使用的增强图像对比度的方法。它通过改变图像的灰度级分布,使得图像的整体亮度分布更加均匀,从而有效...通过阅读和理解代码,我们可以深入理解直方图均衡化的原理和实现方法。

    数字图像处理灰度化直方图均衡化灰度拉伸.pdf

    总的来说,这个实验通过Java实现了从彩色图像到灰度图像的转换,接着进行了直方图均衡化,以增强图像的视觉效果。直方图均衡化是图像处理中的一个基础但强大的工具,尤其适用于改善低对比度或非均匀光照条件下的图像...

    BMP图像直方图均衡和灰度变换

    在这个主题中,我们将深入探讨直方图均衡化和线性灰度变换的概念,以及如何在Java编程环境下实现这些技术。 【描述】所提及的“北航图像处理选修课第一次作业”表明这是一个教学项目,旨在让学生掌握图像处理的基础...

    数字图像处理灰度化直方图均衡化灰度拉伸.docx

    在本实验中,我们关注的是两个基本的图像处理技术:【灰度化】和【直方图均衡化】,以及【灰度拉伸】。 【灰度化】是一种将彩色图像转换为单色(灰阶)图像的过程。在Java中,通过ColorModel类的getRed(), getGreen...

    GraphProcess_直方图均衡_灰度拉伸_图像处理_

    在图像处理领域,直方图均衡化和灰度拉伸是两种常见的图像增强技术,用于改善图像的视觉效果。这两种技术都是基于像素灰度值的分布进行操作的,旨在优化图像的整体亮度和对比度。 直方图均衡化是一种非线性的灰度...

    图像直方图对比

    3. **直方图均衡化**:直方图均衡化是一种常见的对比度增强技术,它通过重新分配像素值来扩展图像的亮度范围。OpenCV中的`equalizeHist()`函数可以实现这个过程。 4. **应用变换**:将经过均衡化的直方图应用回原始...

    Java+opencv3.2.0之直方图均衡详解

    Java+OpenCV3.2.0之直方图均衡详解 ...本文详细介绍了Java+OpenCV3.2.0之直方图均衡的相关知识点,包括直方图均衡化的步骤和实现代码。通过直方图均衡,可以有效地增强图像对比度和可读性,提高图像处理和分析的效果。

    基于Matlab实现图像去雾处理系统的毕业设计(源码+图片数据集+课题介绍).rar

    2.局部直方图均衡化;3.Retinex单尺度去雾算法;4.Retinex多尺度去雾算法 代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 适用对象:工科生、数学专业、算法等方向学习者。 作者介绍:某大厂...

    1.对模糊车牌图像进行清晰处理;2.对高斯模糊图像进行高斯平滑滤波处理;4.对雾化图像进行直方图均衡化处理;

    4.对雾化图像进行直方图均衡化处理;5.对模糊图像进行对比度拉伸与灰度拉伸处理;6.对运动模糊图像进行维纳滤波处理 包含前端、后端、移动开发、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源...

    数字图像JAVA实现灰度 均衡化 中值滤波等

    通过以上Java代码,我们可以实现对灰度图像的均衡化和中值滤波处理。这些操作对于图像的预处理和分析至关重要,可以提高图像质量,便于后续的特征提取和分析。在实际项目中,通常会结合其他图像处理技术,如边缘检测...

    JAVA实现的图片的直方均衡与灰度拉伸

    直方图均衡化是一种基于统计的方法,通过改变图像的灰度级分布,使得图像的灰度直方图更加均匀。这种方法通常用于增强图像的全局对比度,尤其适用于图像中大部分像素集中在某一灰度范围的情况。在JAVA中,我们可以...

    二值化图片_java代码

    此外,JAI库提供了更多高级的图像处理功能,如直方图均衡化、Otsu二值化等,可以进一步提升处理效果。 在描述中提到,代码的效果不错但可能不够完美。这可能意味着代码可能没有采用更复杂的算法,或者阈值选择不够...

    图像处理基本算法 java代码

    本项目聚焦于几个基础但关键的图像处理算法,包括直方图均衡化、中值滤波、谐波均值滤波以及拉普拉斯锐化。这些算法都是图像增强和去噪的重要手段,尤其适用于改善图像的对比度和清晰度。 首先,直方图均衡化是一种...

Global site tag (gtag.js) - Google Analytics