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: }
效果



浙公网安备 33010602011771号