• 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

  • 相关阅读:
    函数式编程语言
    Http
    小解_beginthreadex与_beginthreadex和CreateThread的区别
    Ring0句柄表遍历
    异步读写(ReadFileEx和ReadFile)之overlapped
    异步读写之利用完成历程
    windows核心编程第17章 一个文件两个缓存
    windows核心编程第17章 一个文件一个缓存
    windows核心编程第17章 一个文件 0个缓存
    进程间通信之利用CreateFilemapping()
  • 原文地址:https://www.cnblogs.com/ZJUT-jiangnan/p/3619288.html
Copyright © 2020-2023  润新知