EXIF-поворот фото шаблона: как не потерять координаты ячеек

Телефон может показывать снимок шаблона вертикально, хотя пиксели внутри файла записаны в другом положении. Подсказку о повороте хранит EXIF-ориентация, и разные просмотрщики или библиотеки применяют её на разных этапах. Если разметить угловые маркеры в одном положении, а извлекать буквы из другого, координаты ячеек окажутся повернуты или отражены. Решение — один раз нормализовать изображение, а затем размечать и извлекать клетки только из полученного файла.
Почему фотография выглядит правильно, а координаты расходятся
JPEG с телефона может содержать пиксельный растр и отдельное поле Orientation. В нём указано, как показать этот растр: повернуть на четверть оборота, перевернуть или совместить оба действия. Поэтому размеры, видимые в редакторе, и направление, в котором алгоритм читает исходные пиксели, иногда не совпадают. Ориентация не меняет точки в самом растре, пока программу не попросят применить это преобразование.
Для шаблона это важно из-за угловых меток и привязанных к ним прямоугольников. Допустим, разметчик указал верхнюю левую метку уже на визуально повёрнутом кадре и сохранил координаты (x, y). Если следующий компонент откроет файл без применения EXIF, его начало изображения может соответствовать другому углу; после поворота на 90 градусов ширина и высота также меняются местами. В итоге найденная координата формально лежит внутри изображения, но относится к другой его точке.
EXIF хранит не только четыре поворота. Варианты ориентации могут включать зеркальное отражение, в том числе вместе с перестановкой осей. Поэтому исправлять сбой простым поворотом «пока метки не окажутся сверху» рискованно: картинка визуально может встать правильно, а порядок строк и столбцов остаться обратным. Полезно сначала определить, какой именно файл и какая система координат использовались при разметке.
Как понять, что проблема именно в метаданных
Сначала сравните исходный файл, а не его скриншот. Откройте один и тот же JPEG в двух независимых программах и посмотрите на ориентацию шаблона и размеры изображения. Если в одной программе лист портретный, а в другой альбомный, проверьте EXIF Orientation. Некоторые инструменты показывают уже исправленное изображение и скрывают тот факт, что поворот задан меткой.
Характерный симптом — после импорта меняется не только наклон, но и расположение угловых маркеров относительно ширины и высоты. Например, файл, который оператор ожидал как 4032 × 3024, поступает в обработку как 3024 × 4032. Это пример возможного размера, а не требование к камере: важен сам факт обмена сторон. Другой сигнал — тот же файл в предпросмотре выглядит правильно, а диагностический экран координат показывает маркеры по другой стороне.
Отличайте EXIF-поворот от реального поворота пикселей. Если вы повернули изображение в редакторе и сохранили его как новый растр, геометрия уже физически изменилась. Если изменилось лишь поле Orientation, преобразование ещё нужно применить при чтении. В сомнительном случае сравните оригинальный файл с копией после экспорта без метаданных и проверьте, совпадает ли положение четырёх маркеров.
Надёжный порядок подготовки кадра
1. Сохраните оригинал и зафиксируйте его свойства
Не перезаписывайте исходный снимок. Создайте копию для обработки и запишите имя файла, формат, ширину, высоту, наличие Orientation и то, применён ли поворот к пикселям. Если есть несколько экспортов одной фотографии, добавьте в заметку, из какого именно получены координаты. Это помогает отличить ошибку системы координат от повторной съёмки или автокадрирования.
2. Примените ориентацию до поиска маркеров
Нормализуйте изображение один раз: примените указанное в метаданных преобразование к пикселям и сохраните новый файл с нейтральной ориентацией. Например, в Pillow для этого предназначена ImageOps.exif_transpose: она применяет EXIF Orientation и удаляет поле ориентации из результата. У других программ есть похожие функции, но важно проверить их поведение и итоговый файл, а не полагаться на название команды.
Не применяйте два преобразования подряд. Частая ошибка — сначала экспортировать уже ориентированную копию из фото-просмотрщика, а затем ещё раз применить Orientation в обработчике. Другая ошибка — повернуть растр вручную, но оставить старый тег. При следующем импорте приложение может повернуть файл повторно. После нормализации откройте сохранённую копию в другом просмотрщике: она должна выглядеть одинаково, даже если тот не учитывает EXIF.
3. Проверьте размеры и углы после преобразования
Запишите фактические размеры нормализованного растра. Если стороны поменялись местами, это ожидаемо для поворота на 90 градусов. Затем заново найдите четыре метки на этой версии изображения и присвойте им роли верхний левый, верхний правый, нижний правый и нижний левый. Сопоставляйте порядок по самому шаблону и его сетке, а не по координатам от прежнего файла.
Отдельно проверьте направление первой строки и первого столбца. После отражения кадр может пройти проверку «все четыре угла найдены», но символы будут идти в обратном порядке. Удобно временно выделить одну известную клетку — например, первую заполненную в верхней строке — и убедиться, что её метка совпадает с ожидаемым знаком.
4. Создайте разметку именно для нормализованного файла
Все новые координаты должны ссылаться на неизменённую нормализованную копию. Не переносите точки мышью «на глаз» из исходного окна: поворот и отражение требуют преобразовать каждую пару координат, а ручной перенос добавляет погрешность. Если разметку необходимо сохранить в sidecar-файле, укажите рядом идентификатор версии изображения, его ширину и высоту. Тогда прямоугольники нельзя случайно применить к файлу с другим размером.
5. Сделайте пробное извлечение трёх клеток
До пакетной обработки выберите клетку в каждом из трёх мест: у начала верхней строки, в центре и ближе к противоположному углу. Проверьте, что в вырезке находятся ожидаемые штрихи, соседняя клетка не попала внутрь, а порядок соответствует разметке. Такая проба быстро обнаруживает повёрнутые оси или зеркальный порядок, которые могут быть незаметны по одной центральной клетке.
Какие данные хранить вместе с координатами
Пара чисел (x, y) недостаточна, если неизвестно, к какому изображению она относится. Для воспроизводимой обработки сохраните короткий паспорт исходника и этапов преобразования:
- имя оригинала и нормализованной копии;
- ширину и высоту файла, на котором поставлены метки;
- значение Orientation до нормализации и отметку, что его применили;
- последовательность выполненных операций: ориентация, обрезка, выравнивание;
- дату разметки и версию схемы ячеек;
- координаты маркеров и границы сетки, привязанные к конкретной версии файла.
Не обязательно строить сложную базу данных. Для отдельного проекта хватит JSON или таблицы рядом с изображением. Главное — не хранить координаты без ссылки на версию растра и не переиспользовать их после поворота, отражения, пересохранения с новым размером или автокадрирования.
Контрольный список перед извлечением
Перед запуском полного извлечения пройдите короткую проверку:
- Есть ли в исходнике EXIF Orientation и чему равно значение?
- Применена ли ориентация к пикселям ровно один раз?
- У нормализованной копии ожидаемые ширина и высота?
- Все четыре маркера найдены и назначены нужным углам?
- Первая строка, первый столбец и направление чтения проверены на знакомом знаке?
- Координаты разметки созданы для той же версии файла, которую получает извлечение?
- Три контрольные вырезки из разных областей содержат ожидаемые клетки?
Если любой ответ неясен, остановитесь до пакетного экспорта. Массовое сохранение ошибочных вырезок усложнит проверку: придётся сравнивать не только координаты, но и порядок имён файлов и символов.
Ошибки, из-за которых сбой повторяется
Разметить кадр в просмотрщике и передать исходник в другую программу. Просмотрщик мог автоматически применить ориентацию, а следующая программа — показать сырой пиксельный растр либо применить тег иначе. Разметьте нормализованную копию, которая будет входом обработки.
Считать, что поворот на 90 градусов — единственный вариант. Orientation может задавать отражение. Поэтому проверяйте порядок углов и контрольную клетку, а не только положение заголовка листа.
Исправить положение изображения после разметки. Любая новая ориентация, обрезка или изменение размера инвалидирует координаты, если не выполнен точный пересчёт. Безопаснее сделать преобразование сначала, а точки поставить заново.
Сохранить визуально правильный файл со старым тегом. Это создаёт риск двойного поворота. После экспорта проверьте и пиксели, и метаданные; в нормализованной копии поле ориентации должно быть нейтральным или отсутствовать.
Проверить только центр сетки. Центральная клетка может выглядеть верно даже при перевёрнутом порядке осей. Сравните минимум одну клетку у начала и одну у конца строки или столбца.
Частые вопросы
Почему один просмотрщик показывает фото правильно, а другой — боком?
Один просмотрщик мог применить EXIF Orientation при отображении, а другой показывает пиксельный растр без этого преобразования. Проверьте метаданные файла и создайте нормализованную копию, у которой нужная ориентация уже применена к пикселям. После этого повторная проверка в разных приложениях покажет одинаковый результат.
Меняются ли координаты ячеек после применения EXIF-поворота?
Да. Если растр повернули или отразили, точки и прямоугольники нужно заново найти либо точно преобразовать в новую систему координат. Надёжнее сначала нормализовать копию, затем разметить её, не используя координаты из прежнего положения.
Что делать, если координаты уже поставлены?
Сначала выясните, к какой версии файла относится разметка: к автоматически ориентированному виду или к исходным пикселям. Если это неизвестно, не исправляйте все точки вручную; повторно откройте нормализованную копию и поставьте четыре маркера заново. Сверьте первую клетку с известным символом.
Нужно ли удалять EXIF из нормализованного файла?
Важно устранить неоднозначность: либо записать ориентацию в пиксели и сбросить Orientation, либо гарантировать, что все этапы одинаково трактуют метаданные. Для рабочего конвейера первый вариант проще проверить. Сохраняйте оригинал отдельно, если нужно оставить исходные данные съёмки.
Как понять, что после поворота появился зеркальный порядок?
Сопоставьте угловые метки и проверьте известную клетку в начале строки, затем клетку ближе к её концу. При зеркальном отражении порядок столбцов меняется, даже если все клетки остаются внутри сетки. Проверка четырёх углов и одного известного знака помогает заметить это до пакетного сохранения.
Влияет ли EXIF Orientation на обычный сканер?
Обычно этот вопрос возникает у снимков телефона и приложений, которые записывают ориентацию в EXIF. Но сканер или редактор тоже может сохранить повернутый растр, поэтому проверяйте результат экспорта, а не предполагайте его поведение по устройству. Принцип один: координаты привязаны к конкретной версии пиксельного изображения.
Вывод
Перед поиском маркеров превратите направление из метаданных в фактическую ориентацию растра, сохраните нормализованную копию и создавайте координаты только для неё. Контроль углов и нескольких вырезок подтвердит, что извлечение использует ту же систему координат и сохраняет порядок символов. Для следующего этапа полезно также проверить, как объединять перспективное выравнивание и расчёт ячеек в руководстве об извлечении после коррекции перспективы; свой шаблон можно подготовить к извлечению на Fontgenerator.
Источники
- [Документация Pillow: ImageOps.exif_transpose](https://pillow.readthedocs.io/en/stable/reference/ImageOps.html) — применение EXIF Orientation к изображению и удаление поля ориентации из результата.
- [Документация OpenCV: чтение изображений](https://docs.opencv.org/4.13.0/d4/da8/group__imgcodecs.html) — учёт EXIF-ориентации при чтении и режимы, которые её игнорируют.