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"));
	}

}

处理前:


处理后:



已标记关键词 清除标记
# Java opencv使用connectedComponents函数如何给标记labelImage区域上色? public class demo07_5 { static { //在使用OpenCV前必须加载Core.NATIVE_LIBRARY_NAME类,否则会报错 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } public static void main(String[] args) { Mat src = Imgcodecs.imread("D:\\Eclipse\\workPlace\\test\\img\\text.png", CvType.CV_8UC1); Mat binary = src.clone(); Mat dst = new Mat(src.size(),CvType.CV_8UC3);//与src等大小的3通道画板dst Imgproc.threshold(src, binary, 128, 255, Imgproc.THRESH_OTSU);// 进行 int connectivity = 4;// 使用四连通邻域 // int connectedComponents(InputArray image, OutputArray labels,int connectivity = 8, int ltype = CV_32S); // image是threshold得到的图,得到的labels是32位 short int(短整型)元素的矩阵 // 假如image中有2个连通域,那么labels是只有0、1、2这三种数的矩阵(0标识背景,1、2标识2个连通域),返回是3(三种数据) // Imgproc.connectedComponents(src, binary, connectivity); Mat labelImage = new Mat(); int nLabels = Imgproc.connectedComponents(binary, labelImage, connectivity);// 0,255的binary图变成0,1,2。。。不同区域标识的labelImage,采用四连通邻域 // labelImage是一个单通道的图像,咋都是0 1 呢,如何获取标记的label呢? // System.out.println(nLabels); Vector<Color> colors = new Vector<Color>(nLabels); colors.add(0, Color.black);//将标号为0的点置为背景色黑色 for(int label = 1 ; label < nLabels ; label++) { colors.add(label, new Color((int)(Math.random() * 0x1000000)));//为每一个标记赋一个颜色 } int label ; for(int r = 0;r < dst.rows();r++) { for(int c = 0;c < dst.cols(); c++) {// 遍历每一个像素 //这里就不明白了,如何能获得不同的标记label并且上色呢? label = labelImage.get(r,c)[0]; System.out.println(label); double[] label = labelImage.get(r, c); System.out.println(label[1]); dst.put(r, c, colors.get(label).getRGB());// 根据不同的标识进行染色 } } HighGui.imshow("ConnectedComponents", dst); HighGui.waitKey(); } } ``` ```
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页