兴趣使然,想做个自动登录某网站并且爬取一些数据的的功能,然而虽然其他功能做完了,但是需要手动输验证码…于是了解了Tesseract-OCR尝试自动识别。

准备工作

java代码

1
2
3
4
5
6
7
8
9
10
11
Tesseract tesseract = new Tesseract();
tesseract.setDatapath("src/tessdata");
//识别库文件,默认就是eng,在src/tessdata下
//扩充识别库:https://github.com/tesseract-ocr/tessdata
tesseract.setLanguage("eng");
//使用旧版本的模式 并设置只识别为数字/字母 不是用于识别验证码可不加下面两行
tesseract.setOcrEngineMode(1);
tesseract.setTessVariable("tessedit_char_whitelist","0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");

String result = tesseract.doOCR(ImageIO.read(new File("图片路径"));
System.out.println(result);

二值化验证码图片

上面已经能够正常识别了,但是如果是验证码的话准确度仍然不是很高,所以我们可以对验证码图片先进行二值化处理

  • 贴个工具方法,择情修改
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public static void toBinary(File imageFile) throws IOException {
    BufferedImage image = ImageIO.read(imageFile);
    int w = image.getWidth();
    int h = image.getHeight();
    float[] rgb = new float[3];
    double[][] pos = new double[w][h];
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
    for (int x = 0; x < w; x++) {
    for (int y = 0; y < h; y++) {
    int pixel = image.getRGB(x, y);
    rgb[0] = (pixel & 0xff0000) >> 16;
    rgb[1] = (pixel & 0xff00) >> 8;
    rgb[2] = (pixel & 0xff);
    float avg = (rgb[0] + rgb[1] + rgb[2]) / 3;
    pos[x][y] = avg;
    }
    }
    double SW = 170;
    for (int x = 0; x < w; x++) {
    for (int y = 0; y < h; y++) {
    if (pos[x][y] <= SW) {
    int max = new Color(0, 0, 0).getRGB();
    bi.setRGB(x, y, max);
    } else {
    int min = new Color(255, 255, 255).getRGB();
    bi.setRGB(x, y, min);
    }
    }
    }
    ImageIO.write(bi, "png", imageFile);
    }

扭曲与旋转文字识别

暂未成功

训练识别库

推荐一下参考地址,蛮详细的

  • 下载jTessBoxEditor https://sourceforge.net/projects/vietocr/files/jTessBoxEditor/
  • 打开jTessBoxEditor.jar文件
  • 准备一些验证码样本,必须是白底黑字,可以使用二值化处理后的验证码图片
  • 选择Tools -> Merge TIFF,进入训练样本所在文件夹,选中要参与训练的样本图片
  • 点击 打开 后弹出保存对话框,选择保存在当前路径下,文件命名为 zwp.test.exp0.tif 。
    tif文面命名格式[语言名称].[字体名称].exp[自定义数字].tif
  • 生成.box文件 执行 tesseract zwp.test.exp0.tif zwp.test.exp0 batch.nochop makebox
  • 使用jTessBoxEditor矫正.box文件的错误
  • 选择Box Editor -> Open,打开步骤2中生成的 zwp.test.exp0.tif ,会自动关联到 zwp.test.exp0.box 文件,这两文件要求在同一目录下。调整完点击save保存修改。
  • 生成font_properties文件:执行echo test 0 0 0 0 0 >font_properties
    test 0 0 0 0 0表示字体test的粗体、倾斜等共计5个属性。这里的test必须与zwp.test.exp0.box中的test名称一致。
  • 最后,生成一坨文件并合并训练文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    :: 生成字符集文件
    tesseract zwp.test.exp0.tif zwp.test.exp0 nobatch box.train
    :: 生成shape文件
    unicharset_extractor zwp.test.exp0.box
    :: 生成聚字符特征文件
    mftraining -F font_properties -U unicharset -O zwp.unicharset zwp.test.exp0.tr
    :: 生成字符正常化特征文件
    cntraining zwp.test.exp0.tr
    :: 文件重命名
    rename normproto zwp.normproto
    rename inttemp zwp.inttemp
    rename pffmtable zwp.pffmtable
    rename shapetable zwp.shapetable
    :: 合并.traineddata训练文件
    combine_tessdata zwp.

怎么用就不需要我多说了吧
令人遗憾的是,我调整了30个验证码样本,仍旧是识别不够准确,暂时先放弃吧