美文网首页
使用tesseract在移动端上做OCR的一些小优化

使用tesseract在移动端上做OCR的一些小优化

作者: 曹俊_413f | 来源:发表于2017-05-19 11:30 被阅读0次

    业务需求

    通过用户的股票App中的自选股截图,使用OCR来识别图中的股票名字和股票编码。通过这样的方式,让用户方便地迁移他的自选股。而且我们希望做到离线的识别。

    通过选型,我们最后选择了tesseract。它是一款开源的OCR;更重要的是它在移动端有现成的轮子:Tesseract-OCR-iOStess-two

    优化

    提升速度

    使用了chi_sim+eng两个训练集来识别,发现识别速度不够快。怎么样优化呢?tesseract利用了机器学习,机器学习这个方式是拟人的。我们就想到了如果是人的话,会怎么办?

    我们发现,绝大多数(几乎所有)国内股票App自选股名字和代码都在左侧,而且大多数都是这样的布局:status-bar navigation-bar tab-bar。所以优化方案呼之欲出。那就是减少识别区域,加快了识别速度。具体就是在横向,只识别从最左侧到中线。纵向,去掉3个bar的高度和位置。和人一样,人在看到自选股的时候,他所关心的是股票代码和名字,自然而然他会把视线集中在左侧,加快识别速度和准确率。

    这样做不仅加快了速度,也提高了准确率,对于tesseract干扰更少了。因为干扰更少了,所以速度提升超过了50%这个我们当初的猜想。优化速度到达65%。

    提升识别能力

    我们发现国内股票App场上的色系风格都很雷同,但这样就导致了一个问题,识别率不高,甚至识别不出。所以我们通过滤镜的方式,增强对比度,做到一个黑底白字来提供高识别能力。iOS上具体的代码:

    - (UIImage *)g8_blackAndWhite
    {
        CIImage *beginImage = [CIImage imageWithCGImage:self.CGImage];
    
        CIImage *blackAndWhite = [CIFilter filterWithName:@"CIColorControls" keysAndValues:kCIInputImageKey, beginImage, @"inputBrightness", @0.0, @"inputContrast", @1.1, @"inputSaturation", @0.0, nil].outputImage;
        CIImage *output = [CIFilter filterWithName:@"CIExposureAdjust" keysAndValues:kCIInputImageKey, blackAndWhite, @"inputEV", @0.7, nil].outputImage;
        
        CIContext *context = [CIContext contextWithOptions:nil];
        CGImageRef cgiimage = [context createCGImage:output fromRect:output.extent];
        UIImage *newImage = [UIImage imageWithCGImage:cgiimage scale:0 orientation:self.imageOrientation];
        
        CGImageRelease(cgiimage);
        return newImage;
    }
    

    训练集大小问题

    训练集大小问题是个头疼的问题。eng+chi_sim加起来有80M,压缩后也有44M。这个大小进入到App是不可以接受的。那怎么办呢?两个方案:1.在线下载/使用时下载。2.自己制作训练集。

    我们选择2.

    实际上常用汉子有2500个字,还包含了各种字体。但3000只股票用到的汉子肯定不到2500个字。粗略估计在800个字左右。这样就可以减少3分之2大小。另外,目标App所使用的字体也是一个有限集,例如iOS上基本上都是苹方。苹方虽然也有中黑,标准等字体,但实际上只要一种就可以把其他的也识别出来。所以减少的包大小是很可观的。

    如何制作训练集

    参考这篇。我也自己额外写了一个简单的shell脚步。

    创建一个chi_$FontName.$FontName.exp0.tif的tif就可以。

    FontName=$1
    
    NeedEng=$2
    
    LAN = 'chi_sim'
    if [ NeedEng ]; then
        LAN = 'chi_sim+eng'
    fi
    
    tesseract chi_$FontName.$FontName.exp0.tif chi_$FontName.$FontName.exp0 -l $LAN batch.nochop makebox
    echo '修改完box后按回车'
    read
    unicharset_extractor chi_$FontName.$FontName.exp0.box
    tesseract chi_pfzh.pfzh.exp0.tif chi_pfzh.pfzh.exp0 -l $LAN nobatch box.train
    echo pfzh 0 0 0 0 0 >font_properties
    mftraining -F font_properties -U unicharset -O chi_$FontName.unicharset chi_$FontName.$FontName.exp0.tr
    cntraining chi_$FontName.$FontName.exp0.tr
    
    mv inttemp chi_$FontName.inttemp
    mv pffmtable chi_$FontName.pffmtable
    mv normproto chi_$FontName.normproto
    mv shapetable chi_$FontName.shapetable
    
    combine_tessdata chi_$FontName.
    

    相关文章

      网友评论

          本文标题:使用tesseract在移动端上做OCR的一些小优化

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