1. 程式人生 > >java 圖片二值化

java 圖片二值化

/**
 *  ━━━━━━神獸出沒━━━━━━ 
 *   ┏┓   ┏┓ 
 *  ┏┛┻━━━┛┻┓ 
 *     ┃       ┃
 * 	  ┃   ━   ┃ 
 *     ┃ ┳┛ ┗┳    ┃ 
 *  ┃       ┃ 
 *  ┃   ┻   ┃ 
 *  ┃       ┃ 
 *  ┗━┓   ┏━┛Code is far away from bug with the animal protecting 
 *    ┃   ┃    神獸保佑,程式碼無bug 
 *    ┃   ┃ 
 *    ┃   ┗━━━┓ 
 *    ┃       ┣┓ 
 *    ┃       ┏┛ 
 *    ┗┓┓┏━┳┓┏┛ 
 *     ┃┫┫ ┃┫┫ 
 *     ┗┻┛ ┗┻┛ 
 * 
 * ━━━━━━感覺萌萌噠━━━━━━ 
 */
package gt.controller.Images;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

/**
 * 類名稱:ImageDemo4.java 類描述: 作 者:why 時 間:2017年3月17日
 */
public class ImageDemo4 {
	/**
	 * 二值化(好用)
	 * @param src
	 * @param dest
	 * @return
	 */
	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
		int width = src.getWidth();
		int height = src.getHeight();

		// if ( dest == null )
		// dest = createCompatibleDestImage( src, null );

		int[] inPixels = new int[width * height];
		int[] outPixels = new int[width * height];
		// src = super.filter(src, null); // we need to create new one
		getRGB(src, 0, 0, width, height, inPixels);
		int index = 0;
		int means = getThreshold(inPixels, height, width);
		for (int row = 0; row < height; row++) {
			int ta = 0, tr = 0, tg = 0, tb = 0;
			for (int col = 0; col < width; col++) {
				index = row * width + col;
				ta = (inPixels[index] >> 24) & 0xff;
				tr = (inPixels[index] >> 16) & 0xff;
				tg = (inPixels[index] >> 8) & 0xff;
				tb = inPixels[index] & 0xff;
				if (tr > means) {
					tr = tg = tb = 255; // white
				} else {
					tr = tg = tb = 0; // black
				}
				outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
			}
		}
		setRGB(dest, 0, 0, width, height, outPixels);
		return dest;
	}

	private int getThreshold(int[] inPixels, int height, int width) {
		// maybe this value can reduce the calculation consume;
		int inithreshold = 127;
		int finalthreshold = 0;
		int temp[] = new int[inPixels.length];
		for (int index = 0; index < inPixels.length; index++) {
			temp[index] = (inPixels[index] >> 16) & 0xff;
		}
		List<Integer> sub1 = new ArrayList<Integer>();
		List<Integer> sub2 = new ArrayList<Integer>();
		int means1 = 0, means2 = 0;
		while (finalthreshold != inithreshold) {
			finalthreshold = inithreshold;
			for (int i = 0; i < temp.length; i++) {
				if (temp[i] <= inithreshold) {
					sub1.add(temp[i]);
				} else {
					sub2.add(temp[i]);
				}
			}
			means1 = getMeans(sub1);
			means2 = getMeans(sub2);
			sub1.clear();
			sub2.clear();
			inithreshold = (means1 + means2) / 2;
		}
		long start = System.currentTimeMillis();
		System.out.println("Final threshold  = " + finalthreshold);
		long endTime = System.currentTimeMillis() - start;
		System.out.println("Time consumes : " + endTime);
		return finalthreshold;
	}

	private static int getMeans(List<Integer> data) {
		int result = 0;
		int size = data.size();
		for (Integer i : data) {
			result += i;
		}
		return (result / size);
	}

	public void setRGB(BufferedImage image, int x, int y, int width,
			int height, int[] pixels) {
		int type = image.getType();
		if (type == BufferedImage.TYPE_INT_ARGB
				|| type == BufferedImage.TYPE_INT_RGB)
			image.getRaster().setDataElements(x, y, width, height, pixels);
		else
			image.setRGB(x, y, width, height, pixels, 0, width);
	}

	public void getRGB(BufferedImage image, int x, int y, int width,
			int height, int[] pixels) {
		int type = image.getType();
		if (type == BufferedImage.TYPE_INT_ARGB
				|| type == BufferedImage.TYPE_INT_RGB)
			image.getRaster().getDataElements(x, y, width, height, pixels);
		else
			image.getRGB(x, y, width, height, pixels, 0, width);
	}
	
	public static void main(String[] args) throws IOException {
		ImageDemo4 i = new ImageDemo4();
		BufferedImage bi=ImageIO.read(new File("D:/ocrpic/test3.png"));
		ImageIO.write(i.filter(bi, bi), "png", new File("D:/ocrpic/test3333.png"));
	}

}

處理前:


處理後: