如何结合多个OCR工具的结果以获得更好的文本识别

Chr*_*mus 7 ocr nlp computer-vision sensor-fusion

想象一下,您有不同的 OCR 工具来从图像中读取文本,但没有一个工具可以为您提供 100% 准确的输出。然而,综合起来,结果可能非常接近事实——将文本“融合”在一起以获得良好结果的最佳技术是什么?

\n\n

例子:

\n\n

实际文本

\n\n
\xc2\xa7 5.1: The contractor is obliged to announce the delay by 01.01.2019 at the latest. The identification-number to be used is OZ-771LS.\n
Run Code Online (Sandbox Code Playgroud)\n\n

光学字符识别工具1

\n\n
5 5.1 The contractor is obliged to announce the delay by O1.O1.2019 at the latest. The identification-number to be used is OZ77lLS.\n
Run Code Online (Sandbox Code Playgroud)\n\n

光学字符识别工具2

\n\n
\xc2\xa75.1: The contract or is obliged to announce theedelay by 01.O1. 2O19 at the latest. The identification number to be used is O7-771LS\n
Run Code Online (Sandbox Code Playgroud)\n\n

OCR工具3

\n\n
\xc2\xa7 5.1: The contractor is oblige to do announced he delay by 01.01.2019 at the latest. T he identification-number ti be used is OZ-771LS.\n
Run Code Online (Sandbox Code Playgroud)\n\n

融合 OCR 1、2 和 3 以获得实际文本的有前途的算法是什么?

\n\n

我的第一个想法是创建一个任意长度的“滚动窗口”,比较窗口中的单词,并从 3 个工具预测的每个位置中取出单词 2。

\n\n

例如,窗口大小为 3:

\n\n
[5 5.1 The] \n
Run Code Online (Sandbox Code Playgroud)\n\n
[\xc2\xa75.1: The contract] \n
Run Code Online (Sandbox Code Playgroud)\n\n
[\xc2\xa7 5.1: The] \n
Run Code Online (Sandbox Code Playgroud)\n\n

如您所见,该算法不起作用,因为所有三个工具对于位置一都有不同的候选者(5、\xc2\xa75.1: 和 \xc2\xa7)。

\n\n

当然,可以添加一些技巧,例如编辑距离,以允许一些偏差,但我担心这实际上不够稳健。

\n

mrk*_*mrk 0

\n

对我来说,这看起来像是一个美丽的集成推理问题

\n
\n

合并多个模型的预测的方法不止一种。对于分类问题来说,这是最简单的,直观上可以将模型的预测视为投票。然后由您决定如何处理投票。您是否想要更多地权衡特定模型(例如,如果它具有卓越的性能),您是否想要获得预测的平均值(对您的 nlp 用例没有多大意义),您是否想要选择类别(字符)具有最大票数。

\n

这称为最大投票。我将以此为例进行展示。

\n
from sklearn.base import BaseEstimator, TransformerMixin\nfrom collections import Counter\n\nclass MaxVotingEnsemble(BaseEstimator, TransformerMixin):\n    def transform(self, X):\n        print("\\nTransforming predictions with MaxVotingEnsemble...")\n\n        # Zip the predictions for each position\n        zipped_predictions = zip(*X)\n\n        # Find the mode for each position\n        merged_predictions = []\n        for position, predictions in enumerate(zipped_predictions):\n            print(f"\\nProcessing position {position + 1}: {predictions}")\n\n            # Find the mode for the current position\n            mode_prediction = Counter(predictions).most_common(1)[0][0]\n            print(f"Mode prediction for position {position + 1}: {mode_prediction}")\n\n            merged_predictions.append(mode_prediction)\n\n        return merged_predictions\n
Run Code Online (Sandbox Code Playgroud)\n

我在 Python 3.11 中运行了这个,我得到:

\n
Merged Predictions:\n\xc2\xa7 5.1: The contractor is obliged to announce the delay by 01.01.2019 at the latest. The identifiiation-nnmber to be used is OZ-771LS.\n
Run Code Online (Sandbox Code Playgroud)\n

正如您所看到的,开箱即用,效果很好。然而,这主要是由于以下事实:如果第一个字符串的预测操作不占多数(仔细检查后,它已经是所需结果的一个很好的近似值)。

\n

这是已经收获了唾手可得的果实的地方,并且要获得改进的结果变得更加麻烦。以下是一些“下一步”的想法:

\n
    \n
  1. 通常添加更多模型会给您带来更好的结果,因为选择第一个字符串出现问题的可能性会降低。
  2. \n
  3. 根据模型的性能来衡量模型也可以使您的预测更加稳健。
  4. \n
  5. 目前,角色是根据其索引/位置进行简单比较的。我们可以使用序列对齐算法来找到字符的最佳对齐方式。其中一种算法是 Needleman-Wunsch 算法,它经常用于生物信息学中的序列比对。在Python中, Bio中的pairwise2模块你提供了支持。
  6. \n
\n

这就是我留给您的地方,为您提供设置解决方案的第一步。

\n