5.2. Координати та області

Обробка зображень діє на пікселі, а щоб впливати на піксель, алгоритм повинен адресувати його за координатою. Те саме стосується прямокутника пікселів – прямокутник слід описати так, щоб між алгоритмом і кодом застосунку було узгодження. Угода, яку модуль image використовує для координат і прямокутників, є прямолінійною, однак містить одну деталь, яка застає зненацька читачів, що звикли до математичної, а не комп’ютерно-графічної угоди, – і саме цю деталь варто пояснити одразу.

5.2.1. Сітка пікселів

Піксель (0, 0) знаходиться в лівому верхньому куті зображення. Вісь x спрямована вправо, тому більше x означає далі вправо. Вісь y спрямована вниз, тому більше y означає далі вниз зображення. Зображення шириною w та висотою h містить пікселі з цілими координатами від (0, 0) до (width - 1, height - 1); пікселя в (width, 0) або (0, height) немає – ці позиції є правою та нижньою межами, на один крок далі від останнього фактичного пікселя у кожному напрямку.

Напрямок осі y донизу – це та деталь, згадана вище. Читач, звиклий до координатної геометрії, очікує, що більше y означає вище; тут ця інтуїція перевернута з точністю до навпаки. Причина інверсії полягає в тому, що цифрові датчики та цифрові дисплеї обидва починають з лівого верхнього кута і обходять кожен рядок зліва направо, зверху вниз, і розміщення пікселів у пам’яті в такому самому порядку робить зв’язок між «позицією i у буфері» і «рядком r, стовпцем c зображення» настільки простою арифметикою, наскільки це можливо – позиція i пікселя (x, y) дорівнює просто y * width + x. Усі бібліотеки обробки зображень домовилися про таке розташування десятиліття тому з тієї самої причини, і ціна цього – одне невелике ментальне коригування при першому знайомстві із зображеннями.

A rectangle representing an image. A marker at its top-left corner is labelled (0, 0). An arrow along the top edge points to the right labelled x; an arrow down the left edge points downward labelled y. A smaller rectangle drawn inside is labelled ROI, with its top-left corner at (x, y) and its dimensions w and h marked along the edges.

Система координат зображення: початок у лівому верхньому куті, x спрямований вправо, y – вниз. Прямокутна область усередині зображення задається лівим верхнім кутом (x, y) і розмірами (w, h).

5.2.2. Прямокутники

Більшість операцій над зображенням цікавить не окремий піксель, а прямокутник пікселів – область для пошуку, регіон для копіювання, кадр у кадрі для обчислення статистики. Форма задання прямокутника є максимально простим розширенням угоди для окремого пікселя: задається координата лівого верхнього кута, а потім розміри прямокутника, упакованих у чотириелементний кортеж (x, y, w, h). Пікселі всередині прямокутника знаходяться у стовпцях від x до x + w - 1 і рядках від y до y + h - 1.

Деталь, про яку варто сказати явно: w і h – це розміри, а не координати правого нижнього кута. Прямокутник (10, 20, 4, 3) охоплює стовпці 10, 11, 12, 13 і рядки 20, 21, 22 – дванадцять пікселів загалом – а не область від (10, 20) до (4, 3). Угода є єдиною по всьому модулю, тому після її засвоєння помилки припиняються, але вона застає людей зненацька при першому знайомстві.

Форма (x, y, w, h) зустрічається в трьох місцях, які виглядають різними, але поділяють одну угоду. Перше – коли зображення описує власні розміри: прямокутник, що охоплює все зображення, є (0, 0, width, height). Друге – коли метод виявлення повертає результат з обмежувальним прямокутником – blob, rect, apriltag – і прямокутник повертається як (x, y, w, h). Третє – коли методу потрібно вказати, що він має працювати з підобластю зображення, а не з усім кадром; ключовий аргумент roi, що обмежує операцію, приймає той самий чотириелементний кортеж.

Взяти обмежувальний прямокутник з одного методу і передати його в аргумент roi наступного – один з найпоширеніших шаблонів в обробці зображень. Обмежувальний прямокутник грубого первинного виявлення звужує область пошуку для більш точного вторинного, і однакова термінологія у результатах виявлення та аргументах методів робить цей шаблон настільки прямолінійним – одна форма кортежу, що використовується однаково з обох боків передачі.

5.2.3. Цілі адреси, дробові центроїди

Адреси пікселів самі по собі є цілими числами. Піксель або є, або не є в заданому цілому стовпці та рядку, і питання, що знаходиться в координаті (40.5, 30.7), є некоректним – жоден піксель не знаходиться точно в цій позиції. Однак деяка кількість величин, які модуль image обчислює на основі позицій пікселів, є дробовими, і варто розуміти чому, щоб ця відмінність не застала застосунок зненацька пізніше.

Найпоширенішим випадком є центроїд – центр мас області. Для зв’язної області пікселів центроїд у формі числа з плаваючою комою є середнім значенням позицій пікселів-членів, зваженим за їх щільністю. Область, чиї пікселі охоплюють два стовпці, матиме x центроїда, скажімо, 41.6 – реальну позицію, яку оком описали б як «середина тієї області», хоча жоден фактичний піксель не знаходиться точно на цьому x. Об’єкти результатів виявлення несуть обидві форми як властивості лише для читання: цілочисельну пару (cx / cy, зручну для передачі позиції назад у щось, що очікує цілочисельні координати пікселів) та пару з плаваючою комою (cxf / cyf, зручну, коли позиція потрапляє в контурний контролер, що виграє від субпіксельної роздільної здатності).

Інший випадок – зміщення між двома кадрами, виміряне в частотній області. Методи, які аналізують спектральний вміст зображення, а не безпосередньо його пікселі, можуть визначати зміщення тонші за один піксель і повідомляють про ці зміщення як значення (dx, dy) з плаваючою комою.

Практичне правило: адреси пікселів є цілими числами; позиції та зміщення, що виходять з алгоритму, можуть бути дробовими. Методи малювання приймають обидві форми і округлюють дробові числа до найближчого цілого пікселя, коли результат повинен лягти на сітку.

5.2.4. Декартова і полярна

Описана досі система є декартовою: кожен піксель називається горизонтальним і вертикальним зміщенням від початку координат. Це система, в якій зберігаються байти – піксель i у буфері відповідає пікселю у стовпці i % width і рядку i // width, обходячи рядки від верхнього, – і це система, в якій усі методи працюють за замовчуванням.

Варто знати про другу систему представлення, оскільки деякі алгоритми працюють у ній значно краще. Полярні координати називають кожен піксель його відстанню від обраної центральної точки і кутом між ним і опорним напрямком. Пікселі зображення не переміщуються – байти як і раніше знаходяться в тому самому буфері з рядковою розкладкою – але схема адресації перемикається з «наскільки далеко вправо і вниз» на «наскільки далеко від центру і під яким кутом навколо нього».

Two rectangles side by side, each representing the same image. The left one shows Cartesian coordinates -- top-left origin, x and y axes, a sample point P at coordinates (x, y). The right one shows polar coordinates -- a centre marker C inside the rectangle, with a line from C to the same point P labelled r (distance), and an arc labelled theta (angle).

Та сама точка P, названа двома способами: декартові (x, y) від початку координат у лівому верхньому куті, полярні (r, theta) від обраного центру.

Навіщо перемикатися? Через дві тотожності, що перетворюють складний пошук на простий.

У полярних координатах обертання зображення навколо обраного центру є тією самою операцією, що і зсув його пікселів вздовж осі кута – напрямок x у перепроектованому зображенні. Обернена копія є оригіналом, зсунутим ліворуч або праворуч у полярній формі.

У варіанті log-polar – вісь відстані використовує логарифмічну шкалу, вісь кута залишається лінійною – масштабування зображення навколо обраного центру є тією самою операцією, що і зсув його пікселів вздовж осі відстані – напрямок y. Масштабована копія є оригіналом, зсунутим вгору або вниз у формі log-polar.

Таким чином, алгоритм, що повинен розпізнати відомий шаблон при обертанні або масштабуванні, може виконувати пошук у полярному просторі, де обидва перетворення стають звичайними зсувами. Пошук зсувів значно дешевший, ніж пошук обертань і масштабувань, і саме полярне перепроектування робить таку заміну можливою.

Полярні координати не замінюють декартові для зберігання пікселів; байти завжди зберігаються на декартовій сітці. Модуль надає пару методів, що перепроектують зображення з декартової у полярну форму на запит, алгоритм, якому потрібні полярні координати, виконує свою роботу, і або результат перепроектується назад, або вимір у полярному просторі використовується безпосередньо. Цей механізм є єдиною причиною, чому полярні координати взагалі з’являються на поверхні модуля.

Маючи декартові координати для іменування окремих пікселів, чотириелементний кортеж (x, y, w, h) для іменування їх прямокутників і полярні координати, доступні коли алгоритм виграє від них, застосунок має повний словник для опису де у зображенні знаходиться певний об’єкт. Те, що фактично зберігається в будь-якій з цих позицій, є наступним шаром фундаменту.