写了四个方法,分别实现图片的灰度化,直方图均衡,灰度线性变化,灰度拉伸,其中好多地方特别是灰度拉伸这一块觉得自己实现的有问题,请大大们多多指教。
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>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;i0)
{
if(imax)
max=i;
}
}//找出灰度的最大级和最小级
double k=(ma-mi)/(max-min);//计算变换比
BufferedImage greyImage=new BufferedImage(iwidth, iheight, BufferedImage.TYPE_BYTE_GRAY);
for(int i=0;i255)
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=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);//在原路径下输出拉伸后的图像
}
}