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以前的 ...
随机推荐
- HDU5629:Clarke and tree(DP,Prufer)
Description Input Output Sample Input Sample Output Solution 题意:给你$n$个点,还有每个点的度数,问你任选$i(1\leq i \leq ...
- 包、继承、Super、方法重写
1 包_继承 1.1 包 包(package) 用于管理程序中的类,主要用于解决类的同名问题.包可以看出目录. 包的作用 [1] 防止命名冲突. [2] 允许类组成一个单元(模块),便于管理和维护 [ ...
- kubernetes 的wen pod 无法连接 mysql 的pod
1.分析 查看源代码 既然无法建立连接,那先看下是如何建立连接的.登录到myweb的docker容器里面,查看index.jsp文件,主要内容如下: Class.forName("com.m ...
- 利用WebHook实现PHP自动部署Git代码
平时项目代码都托管在Coding,然后每次提交了代码之后都要SSH到服务器上去git pull一次,很是繁琐,在看了OverTrue的<使用PHP脚本远程部署git项目>后就尝试在自己服务 ...
- Excel frequency函数
计算连续次数最常用的函数就是FREQUENCY,下面就这个函数在计算连续次数的应用做一个详细图解.首先,我们需要了解一下FREQUENCY函数的计算原理. FREQENCY(数据区域,用于设置区 ...
- Swift图书展示项目笔记
1.Swift语言特点 Extensions(扩展):就是向一个已有的类.结构体.枚举类型或者协议类型添加新功能.这包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模) map: 得到一个 ...
- 如何在ASP.NET Core中构造UrlHelper,及ASP.NET Core MVC路由讲解
参考文章: Unable to utilize UrlHelper 除了上面参考文章中介绍的方法,其实在ASP.NET Core MVC的Filter拦截器中要使用UrlHelper非常简单.如下代码 ...
- 服务发现比较:Consul vs Zookeeper vs Etcd vs Eureka
原文:https://blog.csdn.net/dengyisheng/article/details/71215234 服务发现比较:Consul vs Zookeeper vs Etcd vs ...
- sinopia 搭建记录
最近公司有个问题,一些公共部分每次都要手动发送,放到 git 上涉及到父子 git 问题,现在就想在内部搭建一个 npm,涉及到公共模块了就直接 npm update 更新一下.找到了 sinopia ...
- debian系统下改语言设置
debian系统下改语言设置 安装debian 的时候选择了中文zh_CN_UTF-8,然后进系统后想换成en_US_UTF-8 可以使用一下命令选择:找到需要的语言 确定即可 dpkg-reconf ...