zoukankan      html  css  js  c++  java
  • 基于Java对图片进行二值化处理

    一直以来对Java的图形处理能力表无力,但好像又不是那么一回事,之前用PHP做过一些应用,涉及到验证码的识别,其中有个图片二值化的步骤,今天换成Java来实现下

    在java的扩展包javax.imageio中为我们提供了一个类叫ImageIO,这个类提供了一些执行简单编码和解码的静态便捷方法,具体说明大家可以翻下API看看

    下面来说下关于图片二值化的原理:

    1、首先要获取每个像素点的灰度值。

    2、定义一个阀值。

    3、将每个像素点的灰度值和它周围的8个像素点的灰度值相叠加再除以9,然后和阀值进行比较。

    4、大于阀值则设为黑色,小雨则为白色。

    下面贴下具体代码,注释很全

    • separator是File类的一个常量,因年代久远的关系,那时候的代码规范没有和现在一样,常量必须大写,属于历史遗留问题,不必太纠结(建议使用separator而不是"/",便于跨平台) 。
    • BufferedImage里的getRGB得到的是一个ARGB,A代表透明,R代表红色,G代表绿色,B代表蓝色。
    • 包装类Integer里的parseInt方法,第二个可选参数为"要处理几进制的数"。
    • 关于阀值,网上有许多算法,有兴趣的朋友可以自己研究下,这里我随机给出了一个中间数130。
    • 关于图片的灰度值,这里使用简单的(R+G+B)/3。
     1 import java.awt.Color;
     2 import java.awt.image.BufferedImage;
     3 import java.io.File;
     4 import java.io.IOException;
     5 
     6 import javax.imageio.ImageIO;
     7 
     8 public class ImageTest {
     9 
    10     public static void main(String[] args) throws IOException {
    11         String filename = "D:" + File.separator + "/123.jpg";// separator是File里的一个常量,由于java历史遗留问题故为小写
    12         File file = new File(filename);
    13         BufferedImage bi = ImageIO.read(file);
    14         // 获取当前图片的高,宽,ARGB
    15         int h = bi.getHeight();
    16         int w = bi.getWidth();
    17         int rgb = bi.getRGB(0, 0);
    18         int arr[][] = new int[w][h];
    19 
    20         // 获取图片每一像素点的灰度值
    21         for (int i = 0; i < w; i++) {
    22             for (int j = 0; j < h; j++) {
    23                 // getRGB()返回默认的RGB颜色模型(十进制)
    24                 arr[i][j] = getImageRgb(bi.getRGB(i, j));//该点的灰度值
    25             }
    26 
    27         }
    28         
    29         BufferedImage bufferedImage=new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);//  构造一个类型为预定义图像类型之一的 BufferedImage,TYPE_BYTE_BINARY(表示一个不透明的以字节打包的 1、2 或 4 位图像。)
    30         int FZ=130;
    31         for (int i = 0; i < w; i++) {
    32             for (int j = 0; j < h; j++) {
    33                 if(getGray(arr,i,j,w,h)>FZ){
    34                     int black=new Color(255,255,255).getRGB();
    35                     bufferedImage.setRGB(i, j, black);
    36                 }else{
    37                     int white=new Color(0,0,0).getRGB();
    38                     bufferedImage.setRGB(i, j, white);
    39                 }
    40             }
    41             
    42         }
    43          ImageIO.write(bufferedImage, "jpg", new File("D:"+File.separator+"new123.jpg"));
    44     }
    45 
    46     private static int getImageRgb(int i) {
    47         String argb = Integer.toHexString(i);// 将十进制的颜色值转为十六进制
    48         // argb分别代表透明,红,绿,蓝 分别占16进制2位
    49         int r = Integer.parseInt(argb.substring(2, 4),16);//后面参数为使用进制
    50         int g = Integer.parseInt(argb.substring(4, 6),16);
    51         int b = Integer.parseInt(argb.substring(6, 8),16);
    52         int result=(int)((r+g+b)/3);
    53         return result;
    54     }
    55     
    56     
    57     
    58     //自己加周围8个灰度值再除以9,算出其相对灰度值 
    59      public static int  getGray(int gray[][], int x, int y, int w, int h)  
    60         {  
    61             int rs = gray[x][y]  
    62                             + (x == 0 ? 255 : gray[x - 1][y])  
    63                             + (x == 0 || y == 0 ? 255 : gray[x - 1][y - 1])  
    64                             + (x == 0 || y == h - 1 ? 255 : gray[x - 1][y + 1])  
    65                             + (y == 0 ? 255 : gray[x][y - 1])  
    66                             + (y == h - 1 ? 255 : gray[x][y + 1])  
    67                             + (x == w - 1 ? 255 : gray[x + 1][ y])  
    68                             + (x == w - 1 || y == 0 ? 255 : gray[x + 1][y - 1])  
    69                             + (x == w - 1 || y == h - 1 ? 255 : gray[x + 1][y + 1]);  
    70             return rs / 9;  
    71         }  
    72 }

    看下效果吧:

  • 相关阅读:
    python模块之linecache
    如何在cmd命令下运行python脚本
    Git remote: ERROR: missing Change-Id in commit message
    Git命令git update-index --assume-unchanged,忽略不想提交的文件(忽略跟踪)
    Git命令cherry-pick,选择把一部分代码提交到另一个分支
    Redis可以用来做什么?(摘自http://www.lianpenglin.cc廉鹏林博客)
    Yii笔记:打印sql、Form表单、时间插件、Mysql的 FIND_IN_SET函数使用、是否是post/ajax请求
    Yii1使用Gii生成模块实现CURD
    通过经纬度获取所属城市信息-php
    树莓派进阶之路 (010)
  • 原文地址:https://www.cnblogs.com/lichenwei/p/3932969.html
Copyright © 2011-2022 走看看