pandas 在Python中从同一文本的多个OCR结果中查找最可能正确的字符串

busg9geu  于 2022-11-20  发布在  Python
关注(0)|答案(2)|浏览(109)

我用Python对大量焊接组件上的白色文本图像运行了EasyOCR,目的是收集每个组件上的文字。结果大部分都很好,但有一些不一致的结果我想过滤掉。
我使用了同一组件的多个图片,并且它们都带有标签,因此我的DataFrame看起来像这样。
| 识别码|OCR猜测|
| - -|- -|
| 组分1| [RNGSE, BN65E, 8NGse, BN65E, BN65E]|
| 组成部分2| [DFEAW, DFEAW, DF3AW, DFEAW]|
| 组分3| [1002, 1002, l002, 1002]|
正如您所看到的,大多数字母都被正确识别,但有时其中一个字母被识别为数字,反之亦然。是否有一种简单的方法可以对这些字符串“取平均值”,以找到最可能正确的OCR结果?我的目标结果如下所示:
| 识别码|OCR猜测|正确|
| - -|- -|- -|
| 组分1| [RNGSE, BN65E, 8NGse, BN65E, BN65E]|孟加拉国证券交易所|
| 组成部分2| [DFEAW, DFEAW, DF3AW, DFEAW]|双头自动焊|
| 组分3| [1002, 1002, l002, 1002]|千零二|
这将是伟大的,如果有一个模块,考虑到常见的混淆字符,如1和l,6和G,B和R等。
任何帮助都是感激不尽的。谢谢!

xxhby3vn

xxhby3vn1#

您可以找到每对猜测的Levenshtein distance(或编辑距离),然后选择与所有其他猜测更接近的一个。
有很多库实现Levenshtein distance,在这个例子中我将使用editdistance(可能有更好的实现,需要调整更多的参数,这是我刚刚发现的一个)。

import numpy as np
import editdistance

guesses = ['foo', 'foo 2', 'Foo 2']
pair_distances = np.zeros((len(guesses), len(guesses))

for i, gi in enumerate (guesses):
    for j, gj in enumerate (guesses):
        pair_distances[i, j] = editdistance.eval(gi, gj)

sum_distances = np.sum(pair_distances, axis=0)

idx_min = np.argmin(sum_distances)

best_guess = guesses[idx_min]

请注意,np.argmin通过保留第一个匹配项来打破平局。以前的代码可能会导致多个候选项具有最佳距离的情况。您可以采取一些其他决策来打破平局,例如考虑大小写无关的最佳猜测(即,只是相同的代码,但在计算之前将猜测转换为小写)。然而,这也可能会导致平局。
也就是说,这个代码片段应该可以工作,但它不是很有效(每个距离都计算两次,因为d(i,j)== d(j,i),并且d(i,i)总是0,所以不需要计算它)),但我认为它足够清楚地解释我的观点。

cu6pst1q

cu6pst1q2#

一种简单的方法是计算每个字符出现的次数,并每次取出现频率最高的字符。
例如:

pred_list = ["DFEAW", "DFEAW", "DF3AW", "DFEAW"]
avg_string = ""

for i in range(len(pred_list[0])):
    character_count = {}
    
    for pred in pred_list:
        if pred[i] not in character_count:
            character_count[pred[i]] = 1
        else: 
            character_count[pred[i]] += 1
    
    avg_string += max(character_count, key=character_count.get)

print(avg_string)

结果:“DFEAW”
请注意,这种方法不考虑经常混淆的字符。
如果OCR结果之间可能存在未对齐的情况(例如,OCR预测两个字符而不是一个字符,存在额外的空格...),则需要首先对齐不同的字符串(请参阅:多序列对齐)。
python-Levenshtein模块在这种情况下非常有用:

import Levenshtein 
Levenshtein.median(["  DFEA W", "DFEAW", "DF3AW", "DFEAVV"])

结果:“DFEAW”

相关问题