美文网首页
简单的图像二值化处理

简单的图像二值化处理

作者: archerdu | 来源:发表于2019-09-29 16:59 被阅读0次
    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

    相关文章

      网友评论

          本文标题:简单的图像二值化处理

          本文链接:https://www.haomeiwen.com/subject/kthwyctx.html