Загрузка данных
import json
import csv
from pathlib import Path
from reader import MeterReader
ROOT = Path(__file__).resolve().parent.parent
PHOTO_DIR = Path(
r"G:\Robotization\Recognizer\KiloWatcher\9_Грибанова"
)
JSON_FILE = Path(
r"G:\Robotization\Recognizer\аннотации\9_Грибанова.json"
)
reader = MeterReader(
ROOT / "data" / "best.pt"
)
def levenshtein(a, b):
if a == b:
return 0
m = len(a)
n = len(b)
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(m + 1):
dp[i][0] = i
for j in range(n + 1):
dp[0][j] = j
for i in range(1, m + 1):
for j in range(1, n + 1):
cost = 0 if a[i - 1] == b[j - 1] else 1
dp[i][j] = min(
dp[i - 1][j] + 1,
dp[i][j - 1] + 1,
dp[i - 1][j - 1] + cost
)
return dp[m][n]
with open(
JSON_FILE,
"r",
encoding="utf-8"
) as f:
data = json.load(f)
metadata = data["_via_img_metadata"]
total = 0
exact_match = 0
empty_ocr = 0
wrong_1 = 0
wrong_2 = 0
wrong_3_plus = 0
char_total = 0
char_correct = 0
lev_sum = 0
errors = []
print(
f"Найдено записей: {len(metadata)}"
)
for item in metadata.values():
filename = item.get(
"filename",
""
)
regions = item.get(
"regions"
) or []
true_value = None
for region in regions:
if not isinstance(
region,
dict
):
continue
attrs = region.get(
"region_attributes",
{}
)
name = (
attrs.get(
"name",
""
)
.strip()
.lower()
)
if name == "indications":
true_value = (
attrs.get(
"values",
""
)
.strip()
)
break
if not true_value:
continue
photo_path = PHOTO_DIR / filename
if not photo_path.exists():
errors.append(
[
filename,
true_value,
"FILE_NOT_FOUND"
]
)
continue
total += 1
print(
f"[{total}/{len(metadata)}] {filename}"
)
try:
pred = reader.read(
str(photo_path)
)
except Exception as ex:
print(
f"Ошибка OCR: {filename}"
)
print(ex)
pred = ""
pred = str(pred).strip()
if pred == "":
empty_ocr += 1
if pred == true_value:
exact_match += 1
else:
dist = levenshtein(
true_value,
pred
)
if dist == 1:
wrong_1 += 1
elif dist == 2:
wrong_2 += 1
else:
wrong_3_plus += 1
errors.append(
[
filename,
true_value,
pred
]
)
max_len = max(
len(true_value),
len(pred)
)
char_total += max_len
for i in range(
min(
len(true_value),
len(pred)
)
):
if true_value[i] == pred[i]:
char_correct += 1
lev_sum += levenshtein(
true_value,
pred
)
accuracy = (
exact_match / total * 100
) if total else 0
char_accuracy = (
char_correct / char_total * 100
) if char_total else 0
avg_lev = (
lev_sum / total
) if total else 0
print()
print("=" * 60)
print("OCR EVALUATION")
print("=" * 60)
print(
f"Всего изображений: {total}"
)
print(
f"Точные совпадения: {exact_match}"
)
print(
f"Accuracy: {accuracy:.2f}%"
)
print()
print(
f"Ошибок: {total - exact_match}"
)
print(
f"Ошибка в 1 символ: {wrong_1}"
)
print(
f"Ошибка в 2 символа: {wrong_2}"
)
print(
f"Ошибка в 3+ символов: {wrong_3_plus}"
)
print(
f"Пустой OCR: {empty_ocr}"
)
print()
print(
f"Character Accuracy: {char_accuracy:.2f}%"
)
print(
f"Средняя Levenshtein Distance: {avg_lev:.3f}"
)
csv_file = ROOT / "ocr_errors.csv"
with open(
csv_file,
"w",
newline="",
encoding="utf-8-sig"
) as f:
writer = csv.writer(f)
writer.writerow(
[
"filename",
"true",
"predicted"
]
)
writer.writerows(
errors
)
print()
print(
f"Ошибок сохранено: {len(errors)}"
)
print(
f"CSV: {csv_file}"
)