Читать картинку, когда данным нельзя врать
Заводские таблицы приходят двумя половинками: числа текстом, оси только на скриншоте. Как мы их читаем и почему «не знаю» здесь важнее точности.
Заводскую таблицу из блока управления можно скопировать в текст – получится сетка чисел без подписей. Всё остальное есть только на экране программы: обе оси, их названия, единица измерения. То есть скриншот содержит строго больше, чем текстовый экспорт, и без него непонятно даже то, по какой величине идут строки таблицы.
Значит, задача такая: оси взять с картинки, числа – из текста, и убедиться, что это одна и та же таблица. Ровно так и работает наш импортёр: 108 пар «текст плюс скриншот» по восемнадцати заводским калибровкам.
Требование к результату здесь необычное. Обычно от распознавания хотят точности повыше: 98 % лучше, чем 95 %. Здесь важнее другое – ошибочно прочитанная ось хуже непрочитанной. Непрочитанная приводит к отказу, отказ виден в отчёте, и человек идёт переснимать экран. Ошибочно прочитанная тихо ложится в базу с меткой «проверено» и живёт там месяцами – именно так мы однажды и получили четыре ошибки подряд.
Цель: ноль неверных прочтений
Не «поменьше ошибок», а ноль. Сколько при этом останется нераспознанным – вопрос второй: непрочитанное честно называется в отчёте.
Готовый универсальный распознаватель текста для этого не годится по трём причинам. Он решает задачу гораздо более трудную, чем наша: у нас не фотография документа, а чистая картинка интерфейса, один и тот же шрифт, одна и та же сетка. Он не умеет отказываться – выдаёт лучшую догадку там, где нужно честное «не знаю». И он тянет за собой установку постороннего пакета в конвейер данных.
Поэтому чтение написано под конкретный экран конкретной программы.
Разметку дал сам экспорт
Самая приятная часть. Чтобы научить программу узнавать цифры, обычно нужно вручную разметить сотни примеров: вот это «тройка», вот это «восьмёрка».
Здесь размечать не пришлось вообще. В текстовом экспорте лежит ровно то, что нарисовано в ячейке: написано «18,00» – значит, в ячейке нарисовано «18,00». Разрезаем картинку ячейки на отдельные знаки, и если знаков столько же, сколько в строке текста, каждый получает свою подпись. Автоматически, на 104 тысячах примеров.
Руками размечена только шапка таблицы: она набрана полужирным, и в тексте её нет. Это несколько экранов – не «оси такой-то калибровки», а начертания цифр, которыми потом читаются все остальные.
Пороги подобраны, а не назначены
У чтения два порога: насколько знак должен быть похож на образец и насколько он должен быть похож на него больше, чем на любой другой знак.
Подбирать их на глаз не пришлось. Есть 9563 ячейки, для которых верный ответ известен из текста, – это готовая проверочная выборка. Перебор по сетке значений дал такую картину:
| Порог сходства | Порог запаса | Верно | Ошибок | Не прочитано |
|---|---|---|---|---|
| 0.10 | 0.01 | 74.2 % | 0 | 25.8 % |
| 0.15 | 0.02 | 96.7 % | 0 | 3.3 % |
| 0.20 | 0.02 | 99.4 % | 0 | 0.6 % |
| 0.32 | 0.05 | 96.9 % | 2 | 3.1 % |
Взяты самые мягкие значения, при которых ошибок ещё ноль. Обратите внимание на последнюю строку: дальнейшее смягчение не только добавляет ошибки, но и снижает долю верных ответов – запас начинает работать против себя.