package template;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* 图像二值化
*
* @author duxuefu
* 2018/9/10 13:46
*/
public class ImageBinaryzation {
@Test
public void binaryzation() {
// 原图
String from = "d:/image/5b3b4f8fN871fbc51.jpg";
// 二值化后图片
String tob = "d:/image/colatob.png";
try {
BufferedImage bufferedImage = ImageIO.read(new File(from));
BufferedImage binaryBufferedImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_BGR);
// 抽象成线条
// fuseLine(bufferedImage, binaryBufferedImage);
// 抽象成色块
fuseArea(bufferedImage, binaryBufferedImage);
ImageIO.write(binaryBufferedImage, "png", new File(tob));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 抽象成色块
*
* @param bufferedImage 原图
* @param newBufferedImage 处理后图片
*/
private void fuseArea(BufferedImage bufferedImage, BufferedImage newBufferedImage) {
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
System.out.println("----------------------------");
int accumulate = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int pixel = bufferedImage.getRGB(j, i);
int rx = (pixel & 0xff0000) >> 16;
int gx = (pixel & 0xff00) >> 8;
int bx = (pixel & 0xff);
int gray = (rx + gx + bx) / 3;
// TODO 阈值动态设定
int highThreshold = 200;
int lowThreshold = 70;
gray += accumulate;
/* if (rx > 250 && gx < 240 && bx < 240) {
newBufferedImage.setRGB(j, i, (255 << 16) + (0 << 8) + 0);
} else */
if ((rx + gx + bx) / 3 <= lowThreshold) {
// 处理黑色
newBufferedImage.setRGB(j, i, 0);
accumulate = 0;
} else if ((rx + gx + bx) / 3 >= highThreshold) {
// 处理白色
newBufferedImage.setRGB(j, i, (255 << 16) + (255 << 8) + 255);
accumulate = 0;
} else if (gray >= highThreshold) {
newBufferedImage.setRGB(j, i, (255 << 16) + (255 << 8) + 255);
accumulate = gray - 255;
} else {
accumulate += gray;
}
}
System.out.println();
}
}
/**
* 抽象成线条
*
* @param bufferedImage 原图
* @param newBufferedImage 处理后图片
*/
private void fuseLine(BufferedImage bufferedImage, BufferedImage newBufferedImage) {
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
System.out.println("----------------------------");
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int pixel = bufferedImage.getRGB(j, i);
int rx = (pixel & 0xff0000) >> 16;
int gx = (pixel & 0xff00) >> 8;
int bx = (pixel & 0xff);
//灰化
int gray = (rx + gx + bx) / 3;
int fromx = j == 0 ? j : j - 1;
int tox = j == bufferedImage.getWidth() - 1 ? j : j + 1;
int fromy = i == 0 ? i : i - 1;
int toy = i == bufferedImage.getHeight() - 1 ? i : i + 1;
int max = 0; //最大值
int average;//平均值
int sum = 0;
int count = 0;
for (int m = fromx; m <= tox; m++) {
for (int n = fromy; n <= toy; n++) {
int pixelArea = bufferedImage.getRGB(m, n);
int grayArea = (((pixelArea & 0xff0000) >> 16) + ((pixelArea & 0xff00) >> 8) + (pixelArea & 0xff)) / 3;
if (grayArea > max) {
max = grayArea;
}
sum += grayArea;
count++;
// System.out.print(String.format("grayArea: %d", grayArea));
}
}
average = sum / count;
// System.out.println(String.format("gray: %d sum: %d average: %d", gray, sum, average));
// TODO 阈值动态设定
if (rx > 250 && gx < 240 && bx < 240) {
newBufferedImage.setRGB(j, i, (255 << 16) + 0);
} else if (gray >= average && average > 50) {
//System.out.println(sum + " " + average);
newBufferedImage.setRGB(j, i, (255 << 16) + (255 << 8) + 255);
}
}
}
}
}
原图
5b3b4f8fN871fbc51.jpg
fuseArea方法处理后的图片
colatob.png
fuseLine方法处理后的图片
colatob.png
网友评论