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以前的 ...
随机推荐
- Math.min() / Math.max() 使用方法
首先弄懂apply 和 call 都是js函数自带的方法.区别如下: apply和call的用法只有一个地方不一样,除此之外,其他地方基本一模一样 1. a.call(b,arg1,arg2…) 2. ...
- es6安装babel包
1.前面下载node.js及安装淘宝镜像可以查看我写的vue.js环境搭建 2.安装完node后,安装babel npm install -g babel-cli 3.检验babel是否安装成功: b ...
- unity3D iTween的使用
iTween是一个动画库,作者创建它的目的就是最小的投入实现最大的产出.让你做开发更轻松,用它能够轻松实现各种动画,晃动,旋转,移动,褪色,上色,控制音频等等 到官网看看 http://itwe ...
- Qt入门之基础篇 ( 一 ) :Qt4及Qt5的下载与安装
转载请注明出处:CN_Simo. 导语: Qt是一个跨平台的C++图形界面应用程序框架.它提供给开发者建立图形用户界面所需的功能,广泛用于开发GUI程序,也可用于开发非GUI程序.Qt很容易扩展,并且 ...
- python-webbrowser模块 浏览器操作
python的webbrowser模块支持对浏览器进行一些操作,对于爬虫来说是比较基础的知识点 1.主要有以下三个方法: webbrowser.open(url, new=0, autoraise=T ...
- leetcode16—3 Sum Closet
Given an array nums of n integers and an integer target, find three integers in nums such that the s ...
- leetcode18—4Sum
Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums s ...
- 大数据入门第十七天——storm上游数据源 之kafka详解(三)其他问题
一.kafka文件存储机制 1.topic存储 在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序 ...
- Oracle-归档日志详解(运行模式、分类)
一.Oracle日志分类 分三大类: Alert log files--警报日志,Trace files--跟踪日志(用户和进程)和 redo log 重做日志(记录数据库的更改 ...
- VB6 CHECK is run as admin privilege
vb6 code: Private Declare Function IsUserAnAdmin Lib "Shell32" Alias "#680" () A ...