java 图像灰度化与二值化

转载:http://www.chinasb.org/archives/2013/01/5053.shtml

   1:  package org.chinasb.client;
   2:   
   3:  import java.awt.Color;
   4:  import java.awt.image.BufferedImage;
   5:  import java.io.File;
   6:  import java.io.IOException;
   7:   
   8:  import javax.imageio.ImageIO;
   9:   
  10:  public class BinaryTest {
  11:   
  12:      public static void main(String[] args) throws IOException {
  13:          BufferedImage bufferedImage = ImageIO.read(new File("D:/passCodeAction.jpg"));
  14:          int h = bufferedImage.getHeight();
  15:          int w = bufferedImage.getWidth();
  16:   
  17:          // 灰度化
  18:          int[][] gray = new int[w][h];
  19:          for (int x = 0; x < w; x++) {
  20:              for (int y = 0; y < h; y++) {
  21:                  int argb = bufferedImage.getRGB(x, y);
  22:                  int r = (argb >> 16) & 0xFF;
  23:                  int g = (argb >> 8) & 0xFF;
  24:                  int b = (argb >> 0) & 0xFF;
  25:                  int grayPixel = (int) ((b * 29 + g * 150 + r * 77 + 128) >> 8);                
  26:                  gray[x][y] = grayPixel;
  27:              }
  28:          }
  29:   
  30:          // 二值化
  31:          int threshold = ostu(gray, w, h);
  32:          BufferedImage binaryBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
  33:          for (int x = 0; x < w; x++) {
  34:              for (int y = 0; y < h; y++) {
  35:                  if (gray[x][y] > threshold) {
  36:                      gray[x][y] |= 0x00FFFF;
  37:                  } else {
  38:                      gray[x][y] &= 0xFF0000;
  39:                  }
  40:                  binaryBufferedImage.setRGB(x, y, gray[x][y]);
  41:              }
  42:          }
  43:   
  44:          // 矩阵打印
  45:          for (int y = 0; y < h; y++) {
  46:              for (int x = 0; x < w; x++) {
  47:                  if (isBlack(binaryBufferedImage.getRGB(x, y))) {
  48:                      System.out.print("*");
  49:                  } else {
  50:                      System.out.print(" ");
  51:                  }
  52:              }
  53:              System.out.println();
  54:          }
  55:   
  56:          ImageIO.write(binaryBufferedImage, "jpg", new File("D:/code.jpg"));
  57:      }
  58:   
  59:      public static boolean isBlack(int colorInt) {
  60:          Color color = new Color(colorInt);
  61:          if (color.getRed() + color.getGreen() + color.getBlue() <= 300) {
  62:              return true;
  63:          }
  64:          return false;
  65:      }
  66:   
  67:      public static boolean isWhite(int colorInt) {
  68:          Color color = new Color(colorInt);
  69:          if (color.getRed() + color.getGreen() + color.getBlue() > 300) {
  70:              return true;
  71:          }
  72:          return false;
  73:      }
  74:   
  75:      public static int isBlackOrWhite(int colorInt) {
  76:          if (getColorBright(colorInt) < 30 || getColorBright(colorInt) > 730) {
  77:              return 1;
  78:          }
  79:          return 0;
  80:      }
  81:   
  82:      public static int getColorBright(int colorInt) {
  83:          Color color = new Color(colorInt);
  84:          return color.getRed() + color.getGreen() + color.getBlue();
  85:      }
  86:   
  87:      public static int ostu(int[][] gray, int w, int h) {
  88:          int[] histData = new int[w * h];
  89:          // Calculate histogram
  90:          for (int x = 0; x < w; x++) {
  91:              for (int y = 0; y < h; y++) {
  92:                  int red = 0xFF & gray[x][y];
  93:                  histData[red]++;
  94:              }
  95:          }
  96:   
  97:          // Total number of pixels
  98:          int total = w * h;
  99:   
 100:          float sum = 0;
 101:          for (int t = 0; t < 256; t++)
 102:              sum += t * histData[t];
 103:   
 104:          float sumB = 0;
 105:          int wB = 0;
 106:          int wF = 0;
 107:   
 108:          float varMax = 0;
 109:          int threshold = 0;
 110:   
 111:          for (int t = 0; t < 256; t++) {
 112:              wB += histData[t]; // Weight Background
 113:              if (wB == 0)
 114:                  continue;
 115:   
 116:              wF = total - wB; // Weight Foreground
 117:              if (wF == 0)
 118:                  break;
 119:   
 120:              sumB += (float) (t * histData[t]);
 121:   
 122:              float mB = sumB / wB; // Mean Background
 123:              float mF = (sum - sumB) / wF; // Mean Foreground
 124:   
 125:              // Calculate Between Class Variance
 126:              float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);
 127:   
 128:              // Check if new maximum found
 129:              if (varBetween > varMax) {
 130:                  varMax = varBetween;
 131:                  threshold = t;
 132:              }
 133:          }
 134:   
 135:          return threshold;
 136:      }
 137:  }

 

效果

src

dest

posted @ 2014-03-23 17:27  姜楠  阅读(8518)  评论(0编辑  收藏  举报