zoukankan      html  css  js  c++  java
  • 关于tesseract-ocr3的训练和使用

    众所周知,这是一个出色的字符识别软件。这个开源项目可以在http://code.google.com/p/tesseract-ocr/downloads/list下载。

    在使用时,建议使用3而不要使用2,因为一些原因,2虽然可以直接用在工程,但是由于一些显而易见的BUG和其他原因,多导致程序无法运行甚至崩溃。所以建议使用命令行版本的3 。

    除了下载tesseract安装程序以外,还可以在下载页面下载一些语言库,当然,也可以在安装过程中选择一些语言库来进行安装。

    一、训练

    在很多时候,默认的字库等完全可以高准确度的识别,但是有些时候我们需要训练自己的库来使用。训练步骤如下:

    注:

    A、均以DOS命令为例,即将每步下面的命令保存为.BAT运行,或运行CMD进入tesseract所在目录运行

    B、注意保证文件名的一致性(此处均为DDT)

    0、复制training目录下的全部文件到tesseract3所在目录

    copy . raining*.exe .

    1、标记边框

    tesseract ddt.tif ddt -l eng digits batch.nochop makebox

    解释一下

    ddt.tif为要识别的文件,支持jpg,gif,tiff等格式,建议用tif

    ddt 为要保存的文件名(自动添加扩展名.box)

    -l eng 使用的库,这个参数可以让我们选择用哪个字库来标记边框

    后面的都是配置文件了,也就是tesseract的其他参数被以文件形式加载,而不是直接输入参数

    digits指定了只识别0-9的数字(当然你可以编辑它,使它包含更多的字符),当你不需要指定时,一定要去掉这个参数,但使用这种字符集限定,可以最大程度上减少被错误识别搞的你编辑ddt.box头昏脑胀的几率。

    注:

    这一步非常关键,但也经常出现问题,即使你在http://code.google.com/p/bbtesseract/downloads/list下载了bbtesseract也是如此,所以我感觉应该自己编一个边框识别,但没有时间做。完全可以将命令写入到软件里,实现图形化。所以,注意编辑你生成的ddt.box文件,保证字符都被识别且边框正确。

    这里也有一个小技巧,例如我做过这样一个tif:1.2-34567089,在这一步的时候,只识别了2-9这一部分,于是我修改tif为:001.2-34567089,就全部识别了。也许可以给你一些启示。

    2、形成语言库

    tesseract ddt.tif ddt -l eng digits nobatch box.train
    unicharset_extractor ddt.box
    rename unicharset ddt.unicharset
    mftraining -U unicharset -O ddt.unicharset ddt.tr
    rename inttemp ddt.inttemp
    rename pffmtable ddt.pffmtable
    rename Microfeat ddt.Microfeat
    cntraining ddt.tr
    rename normproto ddt.normproto
    combine_tessdata ddt.

    这里面包含了若干步骤,但其他人扒的“教程”已经啰嗦很多了,不再啰嗦。

    注:那几个rename是必要的,因为生成的文件只有扩展名。只要注意了这些,就没问题了。

    3、测试语言库

    copy ddt.traineddata . essdataddt.traineddata

    tesseract ddt.tif ddt -l ddt
    notepad ddt.txt

    如果测试失败了,你应该检查:

    A、是否tif宽度太小,如果是,我建议你在下面增加一行,就是说把1行改成2行,增加什么呢,随意增加一些你字库里面的字符,但最好和图像一样宽。

    B、如果还没正确识别,回头仔细检查你的ddt.box

    如果你失败了,记得清理前面生成的文件,可以使用一下命令:

    copy ddt.tif tmp.tif
    del ddt.* /f /s
    copy tmp.tif ddt.tif
    del tmp.tif

    然后从第一步重新来过。

    二、使用

    使用时,只需要注意,对于单行并且字符数较少的图像,如果不识别,最好是在下面添加一行无用行,并保证该行基本达到图像宽。

    注:

    在使用时,可能会发生找不到字库的情况(尤其当你卸载后重装tesseract时),此时,应修改

    HKEY_CURRENT_USEREnvironmentTESSDATA_PREFIX的值为你的tesseract所在目录。

    三、示例

    最后给出一个tesseract3在VB.NET下使用的示例代码。

    Public Class TessOCR

        Dim path As String = My.Application.Info.DirectoryPath & " esseract3"

        Sub New()
            My.Computer.Registry.CurrentUser.OpenSubKey("Environment", True).SetValue("TESSDATA_PREFIX", path)
        End Sub

        Public Function Tess3OCR(ByVal Rect As Rectangle, ByVal clr As Integer) As String
            '建立图像,注意屏幕复制时使用SourceCopy以符合OCR要求的图像格式,否则出错或直接关闭
            Dim bmp As Bitmap = New Bitmap(Rect.Width, Rect.Height * 2)
            Dim gr As Graphics = Graphics.FromImage(bmp)
            gr.Clear(Color.White)
            gr.CopyFromScreen(Rect.Location, Point.Empty, Rect.Size, CopyPixelOperation.SourceCopy)
            '校正为白纸黑字
            For y As Integer = 0 To bmp.Height - 1
                For x As Integer = 0 To bmp.Width - 1
                    If bmp.GetPixel(x, y).ToArgb = clr Then bmp.SetPixel(x, y, Color.Black) Else bmp.SetPixel(x, y, Color.White)
                Next
            Next
            Dim str As String = IIf(clr = AngleColor, "45.000000", "0.000000")
            gr.DrawString(str, New Font("Arial Black", 14), Brushes.Black, 0, Rect.Height)

            bmp.Save(path & "tmp.tif", System.Drawing.Imaging.ImageFormat.Tiff)
            Shell(path & "tesseract " & path & "tmp.tif " & path & "tmp -l ddt digits", AppWinStyle.Hide, True)
            My.Computer.FileSystem.DeleteFile(path & "tmp.tif")
            Dim ret As String = My.Computer.FileSystem.ReadAllText(path & "tmp.txt").Split(vbCrLf)(0)
            My.Computer.FileSystem.DeleteFile(path & "tmp.txt")
            Return ret
        End Function

    End Class

    在代码的new函数中,我修改了注册表,以防止出错,更好的做法应该是在这之前记录原始值并在类销毁时恢复。之后,指出了屏幕复制时可能存在的一些问题,当然,如果你是取验证码啥的,那就不用关心这些了。然后对图像进行了简单的校正,需要注意的是,必须校正为白底黑字才行,否则不识别。而后,我在下面添加了一行无用的文字,并在返回值时进行了适当处理。再有一点需要注意的是,shell函数的最后一个参数,指出了等待调用进程结束,如果你要在vb6当中使用,这里就需要用api来实现等待——而不要用sleep等定时等待函数,那将会使得你的程序不够健壮。

    转自:http://blog.csdn.net/foxwit/article/details/6547465

    OCR识别引擎tesseract使用方法

    最近一直跟OCR打交道,学习了下google的OCR引擎TESSERACT,是个很好的识别工具。tesseract-3.0已支持版面分析,功能很强大。安装tesseract前可选择性地安装leptonica和libtiff。不过建议先安装这两个库。不安装tiff的话只能处理bmp文件。

         这里只是说明怎么识别中文。依次安装好libtiff,leptonica和tesseract后,下载简体中文和繁体中文的训练数据,在tesseract的下载页可以找到。放到某个目录的tessdata文件夹下。然后设置环境变量TESSDATA_PREFIX=tessdata的目录。然后,新建一个ocr.cpp文件,编写如下代码:

    #include <mfcpch.h>

    #include <ctype.h>

    #include <sys/time.h>

    #include "applybox.h"

    #include "control.h"

    #include "tessvars.h"

    #include "tessedit.h"

    #include "baseapi.h"

    #include "thresholder.h"

    #include "pageres.h"

    #include "imgs.h"

    #include "varabled.h"

    #include "tprintf.h"

    #include "stderr.h"

    #include "notdll.h"

    #include "mainblk.h"

    #include "output.h"

    #include "globals.h"

    #include "helpers.h"

    #include "blread.h"

    #include "tfacep.h"

    #include "callnet.h"

    #include "allheaders.h"

    int main(int argc,char **argv){

    if(argc!=3){

    printf("usage:%s <bmp file> <txt file>/n",argv[0]);

    return -1;

    }

    char *image_file=argv[1];

    char *txt_file=argv[2];

    STRING text_out;

    struct timeval beg,end;

    tesseract::TessBaseAPI  api;

    IMAGE image;

    api.Init(argv[0], "chi_sim", NULL, 0, false);//初始化api对象

    api.SetPageSegMode(tesseract::PSM_AUTO);//设置自动进行版面分析

    api.SetAccuracyVSpeed(tesseract::AVS_FASTEST);//要求速度最快

    if (image.read_header(image_file) < 0) {//读取bmp文件的元信息

    printf("Read of file %s failed./n", image_file);

    exit(1);

        }

    if (image.read(image.get_ysize ()) < 0){//读取bmp文件

    printf("Read of image %s error/n", image_file);

    exit(1);

    }

    invert_image(&image);//反转图像的每个像素,即使1变0,0变1

    int bytes_per_line = check_legal_image_size(image.get_xsize(),

                                                    image.get_ysize(),

                                                    image.get_bpp());//计算每一行像素所占字节数

        api.SetImage(image.get_buffer(), image.get_xsize(), image.get_ysize(),

                      image.get_bpp() / 8, bytes_per_line);//设置图像

    gettimeofday(&beg,NULL);

    char* text = api.GetUTF8Text();//识别图像中的文字

    gettimeofday(&end,NULL);

    printf("%s:reconize sec=%f/n",argv[0],end.tv_sec-beg.tv_sec+(double)(end.tv_usec-beg.tv_usec)/1000000.0);//打印识别的时间

    text_out += text;

    delete [] text;

    FILE* fout = fopen(txt_file, "w");

    fwrite(text_out.string(), 1, text_out.length(), fout);//将识别结果写入输出文件

    fclose(fout);

    }

    再编写一个makefile文件如下:

    all:ocr

    CFLAGS=-Wall -g

    LDFLAGS= -lz  -lm  -ltesseract_textord /

    -ltesseract_wordrec -ltesseract_classify -ltesseract_dict -ltesseract_ccstruct/

    -ltesseract_ccstruct -ltesseract_cutil -ltesseract_viewer -ltesseract_ccutil/

    -ltesseract_api -ltesseract_image -ltesseract_main -llept

    LD_LIBRARY_PATH =

    INCLUDES= -I/usr/local/include/tesseract/ -I/usr/local/include/leptonica/

    %.o:%.cpp

    g++ -c $(CFLAGS) $(INCLUDES)  $(SOURCE) -o $@ $<

    ocr:ocr.o

    g++ -o $@ $^ -g $(LD_LIBRARY_PATH) $(LDFLAGS)

    clean:

    rm ocr.o

        在该目录下运行make编译成可执行文件ocr,运行./ocr 1.bmp 1.txt就可以将图像1.bmp识别结果写到1.txt了,程序会打印识别的时间。值得注意的是,tesseract中文识别速度很慢,运行几分钟很正常。不知有哪位大虾知道怎么调优?

       更郁闷的是tesseract不支持多线程,不能在同一进程中运行多个实例。

    其他参考博客:

    1、http://blog.csdn.net/zhoushuyan/article/details/5948289

    2、http://www.blogjava.net/wangxinsh55/archive/2011/03/22/346787.html

    3、http://haiquan.iteye.com/blog/945701

    4、http://www.cnblogs.com/brooks-dotnet/archive/2010/10/05/1844203.html

    5、http://www.cnblogs.com/physoft/archive/2011/07/15/2107417.html

    6、http://hi.baidu.com/kuliuheng/blog/item/aae32d32216a9fcda2cc2ba1.html

    7、http://code.google.com/p/leptonica/downloads/list

    8、http://tesseract-ocr.repairfaq.org/

    9、http://blog.wudilabs.org/entry/f25efc5f/

     
    0
  • 相关阅读:
    118. Pascal's Triangle
    172. Factorial Trailing Zeroes
    345. Reverse Vowels of a String
    58. Length of Last Word
    383. Ransom Note
    387. First Unique Character in a String
    83. Remove Duplicates from Sorted List
    关于Assembly.CreateInstance()与Activator.CreateInstance()方法
    查看占用指定端口的进程
    如何使用eclipse打开已有工程
  • 原文地址:https://www.cnblogs.com/SeaTop/p/5582288.html
Copyright © 2011-2022 走看看