java实现图像的直方图均衡以及灰度线性变化,灰度拉伸
写了四个方法,分别实现图片的灰度化,直方图均衡,灰度线性变化,灰度拉伸,其中好多地方特别是灰度拉伸这一块觉得自己实现的有问题,请大大们多多指教。
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Scanner; import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.filechooser.FileNameExtensionFilter; public class ImageProcessing { /**
* @param args
*/ static Image tmp;
static int iwidth,iheight;//图像宽度,高度
static double ma,mi;//线性变化灰度上下限
static int[] pixels;//图像所有像素点
static int[] pixels2;//备份pixels,用于灰度线性变化
static int[] pixels3;//备份pixels,用于灰度拉伸
static int[] histogram=new int[256];
static String filename=null,directory=null,fileFormat=null;//要变换的图像路径名+文件名
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
System.out.println("请输入文件路径");
Scanner in=new Scanner(System.in);
directory=in.next();//读入文件路径
System.out.println("请输入文件名");
filename=in.next();//读入文件名
System.out.println("请输入文件格式");
fileFormat=in.next();//读入文件格式
grayImage();//灰度化
histogramEqualization();//均衡化并输出
System.out.println("请输入线性变换的灰度下限");
mi=in.nextInt();
System.out.println("请输入线性变换的灰度上限");
ma=in.nextInt();
linearConversion();
grayStretch();
} //灰度化
public static void grayImage() throws IOException, InterruptedException
{
File input=new File(directory+"\\"+filename+"."+fileFormat);
BufferedImage reader=ImageIO.read(input);//图片文件读入流 iwidth=reader.getWidth();
iheight=reader.getHeight();
pixels=new int[iwidth*iheight];
pixels2=new int[iwidth*iheight];
pixels3=new int[iwidth*iheight]; BufferedImage grayImage=new BufferedImage(iwidth,iheight,BufferedImage.TYPE_BYTE_GRAY);//无符号 byte 灰度级图像
for(int i=0;i<iwidth;i++)
for(int j=0;j<iheight;j++)
{
int rgb=reader.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;
PixelGrabber pg=new PixelGrabber(tmp, 0, 0, iwidth, iheight, pixels,0,iwidth);
pg.grabPixels();//将该灰度化后的图片所有像素点读入pixels数组
PixelGrabber pg2=new PixelGrabber(tmp, 0, 0, iwidth, iheight, pixels2,0,iwidth);
pg2.grabPixels();
PixelGrabber pg3=new PixelGrabber(tmp, 0, 0, iwidth, iheight, pixels3,0,iwidth);
pg3.grabPixels();//
} //直方图均衡
public static void histogramEqualization() throws InterruptedException, IOException
{
//PixelGrabber pg=new PixelGrabber(tmp, 0, 0, iwidth, iheight, pixels,0,iwidth);
//pg.grabPixels();
BufferedImage greyImage=new BufferedImage(iwidth, iheight, BufferedImage.TYPE_BYTE_GRAY); for(int i=0;i<iheight-1;i++)
for(int j=0;j<iwidth-1;j++)
{
int grey=pixels[i*iwidth+j]&0xff;
histogram[grey]++;
}//计算每一个灰度级的像素数
double a=(double)255/(iwidth*iheight);
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<iheight;i++)
for(int j=0;j<iwidth;j++)
{
int grey=pixels[i*iwidth+j]&0x0000ff;
int hist=(int)c[grey];
pixels[i*iwidth+j]=255<<24|hist<<16|hist<<8|hist;
greyImage.setRGB(j, i, pixels[i*iwidth+j]);
}
tmp=greyImage;
File f=new File(directory+"\\"+"均衡化.jpg");
ImageIO.write(greyImage, "jpg", f);//在原路径下输出均衡化后的图像
} //灰度线性变换
public static void linearConversion() throws IOException
{
int min=255,max=0;
for(int i=0;i<256;i++)
{
if(histogram[i]>0)
{
if(i<min)
min=i;
if(i>max)
max=i;
}
}//找出灰度的最大级和最小级
double k=(ma-mi)/(max-min);//计算变换比
BufferedImage greyImage=new BufferedImage(iwidth, iheight, BufferedImage.TYPE_BYTE_GRAY);
for(int i=0;i<iheight;i++)
for(int j=0;j<iwidth;j++)
{
int grey=pixels2[i*iwidth+j]&0xff;
grey=(int)(k*(grey-min)+mi);
if(grey>255)
grey=255;
if(grey<0)
grey=0;
pixels2[i*iwidth+j]=255<<24|grey<<16|grey<<8|grey;
greyImage.setRGB(j, i, pixels2[i*iwidth+j]);
}//灰度线性变换
File f=new File(directory+"\\"+"线性变换.jpg");
ImageIO.write(greyImage, "jpg", f);//在原路径下输出均衡化后的图像
} //灰度拉伸
public static void grayStretch() throws IOException
{
int min = 0,max = 1;
int sum=0;
for(int i=0;i<256;i++)
{
sum+=histogram[i];
if(sum>iwidth*iheight*0.05)
{
min=i;
break;
}
}//找出灰度的大部分像素范围的最小级
sum=0;
for(int i=255;i>=0;i--)
{
sum+=histogram[i];
if(sum>iwidth*iheight*0.05)
{
max=i;
break;
}
}//找出灰度的大部分像素范围的最大级
double k=(ma-mi)/(max-min);
BufferedImage greyImage=new BufferedImage(iwidth, iheight, BufferedImage.TYPE_BYTE_GRAY);
for(int i=0;i<iheight;i++)
for(int j=0;j<iwidth;j++)
{
int grey=pixels3[i*iwidth+j]&0xff;
if(grey<min)
grey=(int) mi;//小于min部分设为下限
else if(grey>=max)
grey=(int) ma;//大于max部分设为上限
else
{
grey=(int)(k*(grey-min)+mi);
if(grey>255)
grey=255;
if(grey<0)
grey=0;
}//大部分区域线性变换 pixels3[i*iwidth+j]=255<<24|grey<<16|grey<<8|grey;
greyImage.setRGB(j, i, pixels3[i*iwidth+j]);
}//灰度拉伸
File f=new File(directory+"\\"+"灰度拉伸.jpg");
ImageIO.write(greyImage, "jpg", f);//在原路径下输出拉伸后的图像
}
}
java实现图像的直方图均衡以及灰度线性变化,灰度拉伸的更多相关文章
- 【数字图像处理】五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理具体解释
本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行解说.主要通过MFC单文档视图实现显示BMP图片点运算处理.包含图像灰度线性变换 ...
- java实现图像灰度化
/*在研究Java实现将一张图片转成字符画的时候,发现将图像转化字符串是根据照片的灰度采用不同的字符画出来,形成一个灰度表.于是就研究了下关于灰度值这个东西,于是跳了一个大坑...因为鄙人用的ubun ...
- opencv——图像的灰度处理(线性变换/拉伸/直方图/均衡化)
实验内容及实验原理: 1.灰度的线性变换 灰度的线性变换就是将图像中所有的点的灰度按照线性灰度变换函数进行变换.该线性灰度变换函数是一个一维线性函数:f(x)=a*x+b 其中参数a为线性函数的斜率, ...
- Java数据结构和算法(一)线性结构之单链表
Java数据结构和算法(一)线性结构之单链表 prev current next -------------- -------------- -------------- | value | next ...
- Java数据结构和算法(一)线性结构
Java数据结构和算法(一)线性结构 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 线性表 是一种逻辑结构,相同数据类型的 ...
- 灰度发布:灰度很简单,发布很复杂&灰度发布(灰度法则)的6点认识
什么是灰度发布,其要点有哪些? 最近跟几个聊的来的同行来了一次说聚就聚的晚餐,聊了一下最近的工作情况如何以及未来规划等等,酒足饭饱后我们聊了一个话题“灰度发布”. 因为笔者所负责的产品还没有达到他们产 ...
- OpenGLES 关于 数学 的分支 - 线性变化量、离散量、随机量
关于 数学 的分支 - 线性变化量.离散量.随机量 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作 ...
- 【线性代数】7-2:线性变化的矩阵(The Matrix of a Linear Transformation)
title: [线性代数]7-2:线性变化的矩阵(The Matrix of a Linear Transformation) categories: Mathematic Linear Algebr ...
- java整理软件--- Java OCR 图像智能字符识别技术,可识别中文,但是验证码不可以识别...已测识别中文效果很好
国内最专业的OCR软件只有2家,清华TH-OCR和汉王OCR,看了很多的OCR技术 发现好多对英文与数字的支持都很好,可惜很多都不支持中文字符.Asprise-OCR,Tesseract 3.0以前的 ...
随机推荐
- shiro实战系列(六)之Authorization(授权)
授权,又称作为访问控制,是对资源的访问管理的过程.换句话说,控制谁有权限在应用程序中做什么. 授权检查的例子是:该用户是否被允许访问这个网页,编辑此数据,查看此按钮,或打印到这台打印机?这些都是 决定 ...
- GDI+编程小结
GDI+(Graphics Device Interface Plus图形设备接口加)是Windows XP和Windows Server 2003操作系统的子系统,也是.NET框架的重要组成部分,负 ...
- DataGridView如何绑定DataRow对象集合
DataGridView对象是我们在进行Winform程序开发中经常使用的呈现数据的控件,而数据则是通过DataSource这个Property来设置的.根据MSDN的说明,DataGridView对 ...
- JAVA框架 Spring 和Mybatis整合(传统dao)
一:我们使用spring处理service,mybaits处理dao层. 二:导入jar包 pom.xml文件内容: <?xml version="1.0" encoding ...
- 蓝桥杯 历届试题 网络寻路(dfs搜索合法路径计数)
X 国的一个网络使用若干条线路连接若干个节点.节点间的通信是双向的.某重要数据包,为了安全起见,必须恰好被转发两次到达目的地.该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径 ...
- ansible 常用方法
测试:用shell执行一个脚本很麻烦的,用script执行 1)推送脚本过去,并授权 ansible george -m copy -a "src=/tmp/test.sh dest=/tm ...
- 利用IDA6.6进行apk dex代码动态调试
网上公开IDA6.6已经有一段时间,这个版本有个好处就是可以动态调试java代码.正好现在需要动态调试,所以顺便练习一下. 根据android的官方文档,如果要调试一个apk里面的dex代码,必须满足 ...
- 20155233 《网络对抗》Exp2 后门原理与实践
实验过程 1.Win获得Linux Shell windows:使用ipconfig指令查看本机ip: windows:使用ncat命令打开监听: Linux反弹连接win: 输入 nc window ...
- 20155306 白皎 《网络攻防》 EXP8 Web基础
20155306 白皎 <网络攻防> EXP8 Web基础 一.问题回答 - 什么是表单 表单:一般用来收集用户的信息和反馈意见 表单包括两个部分:一部分是HTML源代码用于描述表单(例如 ...
- POJ2488&&3083&&3009&&1321&&2251&&2049
刷完了大力数据结构(水比数据结构专题)后又开始搞无脑搜索专题了 这次的标签是DFS(这TM的到现在了谁还不会) 2488 跳马问题:给出一个棋盘,让你求一个方案使一匹马能花最短的时间不重复不遗漏地跳完 ...