关于Tesseract OCR 中文训练识别小试(java调用Tess4j)

2017.9.20日小结
最近接到是关于消防系统协议解析仪器的项目,目的是从协议解析仪器获取有效数据,并解析数据(目的是不希望消防主机的数据信息再传给主机厂商而是最后能给自己收集调用)。由于各个消防器材厂商的协议不同,如果从串口读取数据并一个个协议进行解析工程量浩大并非一人之力可以完成,所以采取途径是根据热敏打印机口获取有效数据(打印机报文格式统一),解析报文后可以判断热敏打印机数据集实际上是打印文字的点阵集并获得有效数据。
这里取一帧数据:1B 4B 50 00 00 00 00 10 F0 F0 10 00 00 10 10 F0 F0 10 10 00 00 00 00 60 60 00 00 00 C0 E0 30 10 30 E0 C0 00 C0 E0 30 10 30 E0 C0 00 00 00 00 00 00 00 00 00 00 01 09 12 22 E4 54 48 48 54 54 62 42 03 02 00 80 00 00 FE 04 04 04 E4 04 0C 74 84 04 04 04 00 0D
每帧数据16进制 ,帧头1B 4B,第三位是长度,50代表的长度80,结尾是00 0D。
16进制转换成2进制,对应8位,8位纵向打印,也就是00打印结果是00000000。
第一个想法是将点阵集模拟出来成为图片,调用文字识别。
第一步:将所有由01组成点阵集转换为二维数组
第二步:将二维数组转换成图片,为了方便,0白色1黑色。(调用java的graphics)
第三部:使用google的Tesseract进行识别。这里另发了一篇关于Tesseract识别过程的文章。
第二想法是将点阵集的每个字部分再分割成二维数组,这里二维数组不能转换成直接转换成hashcode,即使相同的二维数组转换成hashcode,其结果也不同。人工添加key-value键值对的形式进行添加。(消防接口打印机输出文字形式较少,使用这种方法可行度较高)
第一种方法测试多次后识别难度比较大,后采用第二种想法(比较简单就不赘述了)。

关于Tesseract OCR文字识别:
1.下载:Tesseract可以识别多种语言,多种图片格式。我使用的是3.0.2版本。网上有很多下载源,CSDN资源库里也有。下载完成后目录:
这里写图片描述

2、命令提示符进入你需要识别图片的目录下后,这是我需要识别图片的目录。
这里写图片描述
3、给出一个例图,这是我需要识别的打印机报文转换成的图片。
这里写图片描述
4、对test.jpg图片进行识别 输入如下命令这里写图片描述会将识别结果导入一个result.txt的文件。
这里写图片描述
识别完成。
默认使用的是eng.traineddata字库进行识别。我现在需要的进行tesseract中文识别,所以可以下载chi_sim的中文字库,CSDN中也有相应资源。将下载的chi_sim.traineddata导入下载目录的tessdata下如图:
这里写图片描述
当中文库导入tessdata后,在输入如下命令:
这里写图片描述
谷歌的中chi_sim字库识别中文能力不是特别好,这里需要自己训练自己的中文库满足识别条件。
5、开始自己中文库训练
(1)完成以上部分后,需要下载一个第三方软件jTessBoxEditor工具。这个工具是java写的,运行时需要JRE。功能是用来修改产生的BOX文件,用记事本打开后可以发现这个box文件是用来校验文字的。
这里写图片描述
(2)打开这个软件
这里写图片描述
点击tools后再点击Merge TIFF,将所需要的图片集转换成tif格式,源图片集格式支持jpg和tif两种。合成的图片集命名格式为[chi].[lzh].[exp4].tif 第一个空是字典格式,第二个空位图片集的名字,第三个空位exp[num]。这里写图片描述
这里写图片描述按要求命名后。
这里需要注意生成tif时候单个汉子识别通常会出现问题,比如对“一”这个字进行识别会出现emptypage的提示,编译器认为这个是一张空图片。所以采用一张图上有好几个字的方式进行一起识别。这样也方便后面使用jTessBoxEditor对其进行修改,如果是emptypage的话后面使用Tesseract 3.0.2识别会不显示文字特征,也就无法进行修改了。合成图片集时尽量多张图片,哪怕一样的,我用的是10张一样的图片进行合成tif的这样识别得出来,5张的时候识别还是有一定问题。
(3)生成BOX文件,还是刚才的图片集的目录
输入命令tesseract.exe chi.lzh.exp4.tif chi.lzh.exp4 batch.nochop makebox
这里写图片描述
Box文件生成完毕。
(4)校验文字,用刚才jTessBoxEditor打开刚才生成的tif文件。
这里写图片描述 这里写图片描述
我们会发现文字信息不对,这时候需要手动校验,表示非常的麻烦。
这里注意图片集问题参考第二步注意事项。打开如何没有任何特征矩形框则说明jTessBoxEditor没有识别到任何特征,参考第二步对图片集进行调整。
打开box接口如下
这里写图片描述
(5)生成tr文件,命令为tesseract.exe chi.lzh.exp4.tif chi.lzh.exp4 nobatch box.train,生成成功。
这里写图片描述
(6)生成unicharset文件 unicharset_extractor chi.lzh..exp4.box,生成成功。
这里写图片描述
(7)新建font_properties文件 用记事本新建一个明文font_properties
内容格式为lzh 0 0 0 0 0,lzh是新建tif中间的内容
这里写图片描述
(8)在分别运行三个命令对tr特征集合进行操作
1.shapeclustering.exe -F font-properties.txt -U unicharset chi.lzh.exp4.tr
2.Mftraining.exe -F font_properties.txt -U unicharset - O unicharset chi.lzh.exp4.tr
3.Cntraining.exe chi.lzh.exp4.tr
注意:这个版本的命令必须加上properties.txt 结尾的txt必须加上
(9)给下列重命名找出下列五个文件unicharset,inttemp,pffmtable,shapetable,normproto在前面加上lzh.(就是你的tif中间的名字)
这里写图片描述这里写图片描述
(10)最后执行combine_tessdata lzh.(后面是有点的)
如果最后生成traineddata则说明可以用了,将lzh.traineddata加入安装的tesseract的tessdata文件中就可以进行使用。再用tesseract.exe test.jpg test -l lzh就可以了,打开test
结果:这里写图片描述

这里写图片描述
6.如果要进行字典合并,必须要生成字典过程中tif和box,tr,unicharset存在,同时font_properties也必须修改。最后将所有的tr,unicharset,inttemp,normproto,pfftable全部改成lzh。使用combine_tessdata lzh.合并成一个大的字库文件。

参考:
http://blog.csdn.net/why200981317/article/details/48265621
http://blog.csdn.net/yongshi6/article/details/50773760

后面贴一段eclipse工程中调用Tess4j的代码片段,导入Tess4j JAR包后即可以使用lzh新生成的字库完成调用,注意工程下拷入的tessdata中必须也添加lzh.traineddata;
下载地址:http://sourceforge.net/projects/tess4j/
粗暴的方法是将lib中所有的JAR包中文件全部导入,然后将com.recognition.software.jdeskew和net.开头的package全部转入工程下 即可以实现调用
导入完成后目录如图
这里写图片描述

public class Test {//test
    public static void main(String [] args)
    {
        try{
            //图片位置
            File imageFile = new File("J:\\develop\\jee_workspace2\\protocol_analysis\\picture\\test1.jpg");
            //JNA 接口映射
            ITesseract instance = new Tesseract();
            //设置tessdata位置
            instance.setDatapath("J:\\develop\\jee_workspace2\\protocol_analysis");
            //选择字库文件  只需要文件名 不需要后缀名
            instance.setLanguage("lzh");
            //开始识别
            String result = instance.doOCR(imageFile);
            System.out.println(result);
            }catch (TesseractException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
    }


}

猜你喜欢

转载自blog.csdn.net/weixin_39893439/article/details/78042240