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() дає зображення, де номерний знак знаходиться як справжній прямокутник, готовий до наступного етапу розпізнавання символів або зіставлення із шаблоном.

Якщо форма з чотирма кутами вирішує задачу програми, вона значно корисніша за форму з шістьма параметрами. Програмі не потрібно оцінювати жодних кутів обертання; вона просто передає методу чотири точки і дозволяє методу з’ясувати решту. Форма з шістьма параметрами корисна, коли жодного помітного прямокутника у сцені немає і обертання необхідно налаштовувати вручну на основі зовнішніх знань (наприклад, відкаліброваного кута монтажу).