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以前的 ...
随机推荐
- js面对对象编程(二):属性和闭包
上篇博客中解说了一些js对象的基本概念和使用方法.这篇博客解说一下js属性方面的:公有属性.私有属性,特权方法. 假设学过java.公有属性.私有属性,特权方法(即能够訪问和设置私有属性的方法)一定非 ...
- Android-硬件加速
转载请注明来源:http://blog.csdn.net/goldenfish1919/article/details/36890475 从3.0(API level 11)開始.Android 2D ...
- Odoo进销存业务思路浅析
转载请注明原文地址:https://www.cnblogs.com/cnodoo/p/9307485.html 一:采购业务(进) 1:根据采购对象和性质,采购业务主要分为四类: 生产性采购:采购企 ...
- ELK日志收集分析平台 (Elasticsearch+Logstash+Kibana)使用说明
使用ELK对返回502的报警进行日志的收集汇总 eg:Server用户访问网站返回502 首先在zabbix上找到Server的IP 然后登录到elk上使用如下搜索条件: pool_select:X. ...
- 如何利用Grunt生成对应的Source Map文件,线上代码压缩使用chrome浏览器便于调式
如何利用Grunt生成对应的Source Map文件,线上代码压缩使用chrome浏览器便于调式 首先我们来说说为何要生成sourceMap文件呢?简单的说,sourceMap是为了压缩后的代码调式提 ...
- 将myeclipse中不适用的插件禁用掉
转载地址http://blog.csdn.net/yuanboitliuyuan/article/details/7360553 去掉启动时不用的插件启动: 操作方法: windows->pre ...
- fabric简单案例
1 执行一个简单的task任务,显示两台机器的/home/guol/目录下的文件 from fabric.api import * env.users='root' env.port=22 env. ...
- struts2_Interceptor
题目要求:要求当未登录访问某些Action时,自动跳转到登录界面. 1. 2. 3. 4. 5.默认拦截器堆栈为defautStack,但一旦用户添加了拦截器,默认拦截器失效 6. 7. struts ...
- 2018-3-7 20155317 王新玮 Exp1 PC平台逆向破解(5)M
2018-3-7 20155317 王新玮 Exp1 PC平台逆向破解(5)M 任务要求:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数. NOP.JNE.JE.JMP.CM ...
- MiZ702学习笔记11——如何使用vivado isim仿真
说到vivado的仿真确实是很有意思,不管是ISE还是Quartus都可以自己自动生成测试平台的完整构架,但是vivado不行,所有的测试代码自己写!(我反正是查了好久,都没发现vivado如何自动生 ...