• java实现图像的直方图均衡以及灰度线性变化,灰度拉伸


    写了四个方法,分别实现图片的灰度化,直方图均衡,灰度线性变化,灰度拉伸,其中好多地方特别是灰度拉伸这一块觉得自己实现的有问题,请大大们多多指教。

      1 import java.awt.Image;
      2 import java.awt.image.BufferedImage;
      3 import java.awt.image.PixelGrabber;
      4 import java.io.File;
      5 import java.io.IOException;
      6 import java.util.Iterator;
      7 import java.util.Scanner;
      8 
      9 import javax.imageio.ImageIO;
     10 import javax.imageio.ImageReader;
     11 import javax.imageio.stream.ImageInputStream;
     12 import javax.swing.filechooser.FileNameExtensionFilter;
     13 
     14 
     15 public class ImageProcessing {
     16 
     17     /**
     18      * @param args
     19      */
     20     
     21     static Image tmp;
     22     static int iwidth,iheight;//图像宽度,高度
     23     static double ma,mi;//线性变化灰度上下限
     24     static int[] pixels;//图像所有像素点
     25     static int[] pixels2;//备份pixels,用于灰度线性变化
     26     static int[] pixels3;//备份pixels,用于灰度拉伸
     27     static int[] histogram=new int[256];
     28     static String filename=null,directory=null,fileFormat=null;//要变换的图像路径名+文件名
     29     public static void main(String[] args) throws IOException, InterruptedException {
     30         // TODO Auto-generated method stub
     31         System.out.println("请输入文件路径");
     32         Scanner in=new Scanner(System.in);
     33         directory=in.next();//读入文件路径
     34         System.out.println("请输入文件名");
     35         filename=in.next();//读入文件名
     36         System.out.println("请输入文件格式");
     37         fileFormat=in.next();//读入文件格式
     38         grayImage();//灰度化
     39         histogramEqualization();//均衡化并输出
     40         System.out.println("请输入线性变换的灰度下限");
     41         mi=in.nextInt();
     42         System.out.println("请输入线性变换的灰度上限");
     43         ma=in.nextInt();
     44         linearConversion();
     45         grayStretch();
     46     }
     47 
     48     //灰度化
     49     public static void grayImage() throws IOException, InterruptedException
     50     {
     51         File input=new File(directory+"\"+filename+"."+fileFormat);
     52         BufferedImage reader=ImageIO.read(input);//图片文件读入流
     53         
     54         iwidth=reader.getWidth();
     55         iheight=reader.getHeight();
     56         pixels=new int[iwidth*iheight];
     57         pixels2=new int[iwidth*iheight];
     58         pixels3=new int[iwidth*iheight];
     59         
     60         BufferedImage grayImage=new BufferedImage(iwidth,iheight,BufferedImage.TYPE_BYTE_GRAY);//无符号 byte 灰度级图像
     61         for(int i=0;i<iwidth;i++)
     62             for(int j=0;j<iheight;j++)
     63             {
     64                 int rgb=reader.getRGB(i, j);
     65                 int grey=(int) ((0.3*((rgb&0xff0000)>>16)+0.59*((rgb&0xff00)>>8))+0.11*((rgb&0xff)));
     66                 rgb=255<<24|grey<<16|grey<<8|grey;
     67                 grayImage.setRGB(i, j, rgb);
     68             }//读入所有像素,转换图像信号,使其灰度化
     69         tmp=grayImage;
     70         PixelGrabber pg=new PixelGrabber(tmp, 0, 0, iwidth, iheight, pixels,0,iwidth);
     71         pg.grabPixels();//将该灰度化后的图片所有像素点读入pixels数组
     72         PixelGrabber pg2=new PixelGrabber(tmp, 0, 0, iwidth, iheight, pixels2,0,iwidth);
     73         pg2.grabPixels();
     74         PixelGrabber pg3=new PixelGrabber(tmp, 0, 0, iwidth, iheight, pixels3,0,iwidth);
     75         pg3.grabPixels();//
     76     }
     77     
     78     //直方图均衡
     79     public static void histogramEqualization() throws InterruptedException, IOException
     80     {
     81         //PixelGrabber pg=new PixelGrabber(tmp, 0, 0, iwidth, iheight, pixels,0,iwidth);
     82         //pg.grabPixels();
     83         BufferedImage greyImage=new BufferedImage(iwidth, iheight, BufferedImage.TYPE_BYTE_GRAY);
     84         
     85         for(int i=0;i<iheight-1;i++)
     86             for(int j=0;j<iwidth-1;j++)
     87             {
     88                 int grey=pixels[i*iwidth+j]&0xff;
     89                 histogram[grey]++;
     90             }//计算每一个灰度级的像素数
     91         double a=(double)255/(iwidth*iheight);
     92         double[] c=new double[256];
     93         c[0]=(a*histogram[0]);
     94         for(int i=1;i<256;i++)
     95             c[i]=c[i-1]+(int)(a*histogram[i]);//直方图均衡化(离散情况)
     96         for(int i=0;i<iheight;i++)
     97             for(int j=0;j<iwidth;j++)
     98             {
     99                 int grey=pixels[i*iwidth+j]&0x0000ff;
    100                 int hist=(int)c[grey];
    101                 pixels[i*iwidth+j]=255<<24|hist<<16|hist<<8|hist;
    102                 greyImage.setRGB(j, i, pixels[i*iwidth+j]);
    103             }
    104         tmp=greyImage;
    105         File f=new File(directory+"\"+"均衡化.jpg");
    106         ImageIO.write(greyImage, "jpg", f);//在原路径下输出均衡化后的图像
    107     }
    108     
    109     //灰度线性变换
    110     public static void linearConversion() throws IOException
    111     {
    112         int min=255,max=0;
    113         for(int i=0;i<256;i++)
    114         {
    115             if(histogram[i]>0)
    116             {
    117                 if(i<min)
    118                     min=i;
    119                 if(i>max)
    120                     max=i;
    121             }
    122         }//找出灰度的最大级和最小级
    123         double k=(ma-mi)/(max-min);//计算变换比
    124         BufferedImage greyImage=new BufferedImage(iwidth, iheight, BufferedImage.TYPE_BYTE_GRAY);
    125         for(int i=0;i<iheight;i++)
    126             for(int j=0;j<iwidth;j++)
    127             {
    128                 int grey=pixels2[i*iwidth+j]&0xff;
    129                 grey=(int)(k*(grey-min)+mi);
    130                 if(grey>255)
    131                     grey=255;
    132                 if(grey<0)
    133                     grey=0;
    134                 pixels2[i*iwidth+j]=255<<24|grey<<16|grey<<8|grey;
    135                 greyImage.setRGB(j, i, pixels2[i*iwidth+j]);
    136             }//灰度线性变换
    137         File f=new File(directory+"\"+"线性变换.jpg");
    138         ImageIO.write(greyImage, "jpg", f);//在原路径下输出均衡化后的图像
    139     }
    140     
    141     //灰度拉伸
    142     public static void grayStretch() throws IOException
    143     {
    144         int min = 0,max = 1;
    145         int sum=0;
    146         for(int i=0;i<256;i++)
    147         {
    148             sum+=histogram[i];
    149             if(sum>iwidth*iheight*0.05)
    150             {
    151                 min=i;
    152                 break;
    153             }
    154         }//找出灰度的大部分像素范围的最小级
    155         sum=0;
    156         for(int i=255;i>=0;i--)
    157         {
    158             sum+=histogram[i];
    159             if(sum>iwidth*iheight*0.05)
    160             {
    161                 max=i;
    162                 break;
    163             }
    164         }//找出灰度的大部分像素范围的最大级
    165         double k=(ma-mi)/(max-min);
    166         BufferedImage greyImage=new BufferedImage(iwidth, iheight, BufferedImage.TYPE_BYTE_GRAY);
    167         for(int i=0;i<iheight;i++)
    168             for(int j=0;j<iwidth;j++)
    169             {
    170                 int grey=pixels3[i*iwidth+j]&0xff;
    171                 if(grey<min)
    172                     grey=(int) mi;//小于min部分设为下限
    173                 else if(grey>=max)
    174                     grey=(int) ma;//大于max部分设为上限
    175                 else 
    176                 {
    177                     grey=(int)(k*(grey-min)+mi);
    178                     if(grey>255)
    179                         grey=255;
    180                     if(grey<0)
    181                         grey=0;
    182                 }//大部分区域线性变换
    183                 
    184                 pixels3[i*iwidth+j]=255<<24|grey<<16|grey<<8|grey;
    185                 greyImage.setRGB(j, i, pixels3[i*iwidth+j]);
    186             }//灰度拉伸
    187         File f=new File(directory+"\"+"灰度拉伸.jpg");
    188         ImageIO.write(greyImage, "jpg", f);//在原路径下输出拉伸后的图像
    189     }
    190 }
  • 相关阅读:
    柯西恒等式 FPGA中信号的跨时钟域处理模板(二)
    OSPF
    Windows多网卡路由设置
    使用线程时需要注意的地方
    dicom 影像通信(scu、scp)的c-echo、c-store、c-find、c-move
    关于python3没有numpy和matplotlib库怎么办
    使用centos6.5时的几个小问题
    关于用Apache Beam跑WordCount
    MarkdownPad2的安装、破解和汉化
    安装Photoshop CS64
  • 原文地址:https://www.cnblogs.com/freestyle-sn/p/3618349.html
Copyright © 2020-2023  润新知