5.22. Коррекция объектива и перспективы

Два класса геометрической коррекции искажают изображение способами, которые невозможно описать отображением прямоугольника в прямоугольник. Коррекция объектива устраняет радиальную дисторсию, вносимую реальным широкоугольным объективом, – эффект «рыбьего глаза», который изгибает прямые линии сцены в заметные кривые вблизи углов кадра. Коррекция перспективы устраняет трапециевидное искажение, возникающее, когда объектив направлен не перпендикулярно сцене, – трапециевидную деформацию, которая превращает известный прямоугольник в реальном мире в непрямоугольный блоб на изображении. Обе коррекции устраняют уже после съёмки эффекты, имеющие оптическое происхождение.

5.22.1. Радиальная дисторсия объектива

Материал о реальных эффектах объектива описывает бочкообразную дисторсию, вносимую недорогими широкоугольными объективами. Пиксели вблизи центра кадра расположены примерно там, где их предсказывает модель камеры-обскуры; пиксели вблизи краёв выгнуты наружу на величину, которая растёт пропорционально квадрату радиального расстояния от оптической оси. Прямая линия в сцене, проходящая вблизи края кадра, заметно искривляется на снятом изображении, и любой классический алгоритм машинного зрения, предполагающий, что прямые линии остаются прямыми, – обнаружение углов AprilTag, отслеживание границ, навигация по линии – даёт неверный результат вблизи углов.

lens_corr() устраняет дисторсию. Метод выполняет обратное отображение: каждый выходной пиксель берётся из той позиции во входном изображении, в которую объектив выгнул бы его наружу, и в результате получается геометрически прямое изображение.

img.lens_corr(strength=1.8)

Параметр strength – это сердце коррекции. Это одно число, описывающее, насколько сильно объектив выгибает изображение; значение около 1.0 соответствует мягкой коррекции для умеренно широкого объектива, а значения примерно до 2.0 разумны для сильного «рыбьего глаза». Значение по умолчанию 1.8 является разумной отправной точкой для штатных объективов OpenMV Cam; правильное значение для конкретного объектива подбирается экспериментально, наблюдая за изображением.

Два дополнительных параметра обычно хорошо работают со значениями по умолчанию. zoom (по умолчанию 1.0) масштабирует выход – значение больше единицы обрезает изображение наружу, чтобы компенсировать то, как коррекция объектива выталкивает углы дальше; меньшие значения оставляют больше скорректированной сцены видимой ценой включения пустых пикселей по краям изображения. x_corr и y_corr смещают центр коррекции от геометрического центра изображения, что полезно, когда объектив оптически не отцентрирован относительно датчика (необычный случай, но о нём стоит знать).

Типичный конвейер: захват, однократный вызов lens_corr() для выпрямления геометрии, а затем выполнение того, что приложение фактически делает с результатом.

5.22.2. Коррекция трёхмерного поворота

Другой класс геометрических искажений – это перспективная деформация, возникающая, когда плоскость датчика не параллельна плоскости сцены. Классический случай – знак или номерной знак, видимый снизу: верх знака находится дальше от объектива, чем низ, поэтому проецируется меньше, и на снятом изображении прямоугольник выглядит как трапеция, у которой верхняя грань короче нижней.

Исправление состоит в применении к снятому кадру трёхмерного поворота, который виртуально переориентирует плоскость датчика так, чтобы она была параллельна плоскости сцены. Математика здесь та же, что и в перспективном отображении, которое обнаружение AprilTag использует для восстановления положения метки по её четырём углам, но выполняемом в обратном порядке: при заданном повороте операция отображает каждый выходной пиксель обратно во входную позицию, из которой произошёл бы поворот.

rotation_corr() выполняет эту коррекцию:

img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)

Три параметра поворота заданы в градусах и описывают повороты вокруг осей x, y и z виртуальной камеры, отцентрированной на изображении. x_rotation наклоняет камеру вверх или вниз (естественная коррекция для снимка стены с уровня земли); y_rotation поворачивает камеру влево или вправо; z_rotation вращает камеру вокруг её оптической оси (естественная коррекция для неровно установленного крепления).

x_translation и y_translation перемещают виртуальную камеру в боковом направлении, не поворачивая её. zoom (по умолчанию 1.0) масштабирует выход. fov (по умолчанию 60.0) описывает вертикальное поле зрения камеры, используемое для вычисления проекции, – значение должно соответствовать фактическому объективу, чтобы сохранить согласованность геометрии.

Для произвольной комбинации наклона и поворота несколько ненулевых поворотов комбинируются в одном вызове. Порядок операций фиксирован внутри реализации; приложение просто задаёт углы, и результат получается на выходе.

5.22.3. Выпрямление известного прямоугольника

Наиболее часто полезная форма rotation_corr() – это ключевое слово corners=, которое принимает список из четырёх кортежей (x, y), описывающих углы известного прямоугольника во входном изображении. Метод вычисляет, какой трёхмерный поворот отобразил бы настоящий прямоугольник в эти конкретные четыре точки, применяет ко всему изображению обратный этому повороту и возвращает результат, в котором известный прямоугольник снова становится прямоугольным:

plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)

Классическое применение – именно то, что подсказывает название: номерной знак (или любой другой прямоугольный признак), сфотографированный под косым углом. Предшествующий этап обнаруживает номер и сообщает позиции его четырёх углов на снятом изображении; передача этих углов в rotation_corr() создаёт изображение, в котором номер выглядит настоящим прямоугольником, готовым для последующего этапа распознавания символов или сопоставления с шаблоном.

Когда форма с четырьмя углами решает задачу, которую пытается решить приложение, она значительно полезнее формы с шестью параметрами. Приложению не нужно оценивать какие-либо углы поворота; оно просто передаёт методу четыре точки и позволяет методу разобраться с остальным. Форма с шестью параметрами полезна, когда в сцене не видно никакого распознаваемого прямоугольника и поворот приходится подбирать вручную на основе внешних знаний (например, откалиброванного угла крепления).