美文网首页红红火火恍恍惚惚OCR相关
文本对比算法的简单实现

文本对比算法的简单实现

作者: 欠我的都给我吐出来 | 来源:发表于2019-07-29 22:33 被阅读0次

    我们小组当前有需要要测试ocr场景文字识别的效果,给定真实文本和ocr模型预测的文本,希望给出评价指标验证模型的效果。

    去网上查阅了python有一个特别好用的文本对比工具包,difflib,做了一些调研之后,依旧选择自己写代码实现文本的对比函数。difflib初步感觉不好用的原因是,如果两行文本的文字不一样的稍微多一点,就无法给表示出其中的差异了。比如

    假设真实语句为:
    正式始工作。好好学习

    检测出来的语句为:
    正式开始工作

    这两句话,我希望可以得到检测到的比真实的多了一个字,少了四个汉字的情况。而使用difflib的compare方法,只会认为这两句话完全不一样。

    另一个相似的情况是

    假设真实语句为:
    正式始工作。好好学习

    检测出来的语句为:
    正式开始工作

    这时,difflib就可以检测出这两句话的区别,并给予标注

    文本对比函数主要为了测试ocr文本检测的效果,因此我采取一行为最小的检测单元,分别输入text1标准结果、text2录入结果,检测每一行文本检测的匹配字符数、错字字符数、多字字符数、漏字字符数。

    代码的主要思路参考文本比对的一种算法探索、比对算法中的难点及解决方法

    其主要的思想是:p1,p2分别指向两个句子的指针。

    • 当两句话的指针位置text1[p1]==text[p2]时,两个指针同时指向下一个位置。

    • 当指针的位置的内容不同的时候,保持p2不变,首先遍历text1的p1指针后面的位置,一直遍历到最后,如果出现了text1[p1']==text[p2],那么意味着检测的语句有漏检的字符。

       考虑下面的例子
       
       **正式开始工作。**
       
       **正式工作。**
      
    • 如果p1'遍历到text1的末尾依旧没有找到,则进行多字检测。也就是保持p1不变,遍历text2在p2后面的位置,看看是否有text1[p1]==text[p2']的情况,如果有,则意味着检测语句多出了真实语句没有的词语。

       考虑下面的例子
       
       **正式工作。**
       
       **正式开始工作。**
      
    • 如果这两种遍历方式都没有找到结果,那么意味着存在错字问题,将p1和p2同时+1.

    代码如下:

    def get_textline_match(text1, text2):
        lose_words = 0
        more_words = 0
        wrong_words = 0
        match_words = 0
        p1 = 0
        t1 = 0
        p2 = 0
        t2 = 0
    
        len1 = len(text1)
        len2 = len(text2)
    
        def loss_words(p, text, word):
            len1 = len(text)
            if p >= len1:
                return -1
            while p < len1:
                if text[p] == word:
                    return p
                else:
                    p += 1
            return -1
    
        while (p1 < len1) & (p2 < len2):
            if text1[p1] == text2[p2]:
                match_words += 1
                p1 += 1
                p2 += 1
            else:
                t1 = loss_words(p1 + 1, text1, text2[p2])
                if t1 == -1:  # 搜索标准行,没有找到
                    t2 = loss_words(p2 + 1, text2, text1[p1])
                    if t2 == -1:  # 搜素识别行,没有找到对应位置,表示这是一个错字
                        wrong_words += 1
                        p1 += 1
                        p2 += 1
                    else:
                        more_words += (t2 - p2)
                        p2 = t2
                else:
                    lose_words += (t1 - p1)
                    p1 = t1
    
        lose_words += len1 - p1
        more_words += len2 - p2
        return match_words, wrong_words, lose_words, more_words
    
    
    if __name__ == "__main__":
        text1 = """我们班里喜欢数学的学生大多数是女生。"""
        text2 = """我们班里的学生大多数是女生。"""
    
        match_words, wrong_words, lose_words, more_words = get_textline_match(text1, text2)
    
        print("匹配字符数量: ", match_words)
        print("错误字符数量: ", wrong_words)
        print("丢失字符数量: ", lose_words)
        print("多出字符数量: ", more_words)
    

    会输出结果

    匹配字符数量:  14
    错误字符数量:  0
    丢失字符数量:  4
    多出字符数量:  0
    

    需要的优化是,为了加快速度,可以不必一直遍历到末尾,只要遍历到四五个字之后,如果还没有出现,就可以认为是漏字、多字或者错字了。

    如果有更好的思路或者这边代码存在某些我还没有发现的问题,欢迎留言讨论

    相关文章

      网友评论

        本文标题:文本对比算法的简单实现

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