MERCI SPACE
Навчальні матеріали

Лабораторна робота 17

Лабораторна робота №17. Взаємне білінійне перетворення координат

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

Результати навчання та передумови

Після виконання студент уміє:

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

Передумови: системи координат, вектори та матриці, базовий Python, NumPy, Matplotlib. Апаратний допуск не потрібний.

Середовище виконання

СередовищеСтатусПримітка
Google ColabосновнеВиконання розрахунків і побудова графіків
Локальний ПКдозволеноПотрібні Python, NumPy, Matplotlib і CV_library; версії потребують перевірки
Raspberry Piне використовуєтьсяПеренесення обчислень на контролер комплексу не входить до цієї версії роботи
Фізичний комплекс MERC-I5не потрібенКоординати обробляються програмно; рух робота заборонений у межах цієї роботи

Необхідні знання та матеріали

Ризики та правила безпеки

Робота виконується повністю в обчислювальному середовищі. Рух робота заборонений у межах цієї роботи.

Заборонені дії

  • передавати обчислену координату роботу без окремого дозволу оператора;
  • використовувати точку, для якої only_inside=True дав відмову;
  • вважати малу числову похибку доказом фізичної точності захоплення;
  • підбирати контрольні точки так, щоб зменшити похибку на тих самих точках, на яких вона вимірюється.

Чому це критично

Помилка в перетворенні координат не проявляється як виняток у програмі — вона проявляється як рух робота в неправильну точку. Саме тому обчислена координата обов'язково проходить перевірку меж і візуалізацію траєкторії до фізичного запуску. Програмна перевірка зменшує ризик, але не доводить фізичну безпечність і не є дозволом на рух.

Безпечний стан

Якщо точка не належить каліброваній області, зворотне перетворення не збігається або похибка перевищує допуск — координата не передається роботу, а цикл переходить у стан помилки.

Хід виконання роботи

  1. Опрацювати методичні вказівки.
  2. Отримати індивідуальний варіант завдання.
  3. Реалізувати взаємне перетворення координат згідно з варіантом.
  4. Виконати перетворення тестових об'єктів.
  5. Оцінити похибку на незалежних контрольних точках.
  6. Перевірити поведінку для точок поза каліброваною областю.
  7. Проаналізувати отримані результати.
  8. Оформити звіт і надіслати викладачу для перевірки.

Методичні вказівки й теоретичні відомості

1. Теоретичні відомості

При використанні роботизованих комплексів часто виникає задача визначення координат об'єкта, виявленого камерою, у системі координат робота. Координати центра об'єкта на зображенні задаються у пікселях:

$(x_{c}, y_{c})$

Однак робот працює у власній системі координат:

$(x_{r}, y_{r})$

Для виконання операцій захоплення необхідно перетворити координати між цими двома системами.

У найпростішому випадку використовується афінне перетворення. Проте через перспективні спотворення камери та особливості розташування робочої області такого перетворення часто недостатньо. Тому застосовується білінійне перетворення.

Нехай прямокутна область описується чотирма вершинами:

$P_{00}, P_{01}, P_{10}, P_{11}$

Тоді координати довільної точки всередині області визначаються параметрами:

$u∈[0,1], v∈[0,1]$

за формулою

$P(u,v)=P_{00}+uA+vB+uvC$

де

$A=P_{01}-P_{00}$

$B=P_{10}-P_{00}$

$C=P_{00}-P_{01}-P_{10}+P_{11}.$

Координати $(u,v)$ є локальними координатами точки всередині області.

Геометрична схема білінійного перетворення

Рис. 1. Демонстрація білінійного перетворення

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

  • камера визначає положення об'єктів у пікселях зображення;

  • робот використовує власну систему координат, що зазвичай задається в міліметрах.

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

  • у системі координат камери вершинами

$C_{00}, C_{01}, C_{10}, C_{11},$

  • у системі координат робота вершинами

$R_{00}, R_{01}, R_{10}, R_{11}.$

Тоді довільна точка об'єкта, знайдена камерою, $P_{c}=(x_{c},y_{c})$ спочатку переводиться у локальні координати області $(u,v)$ за допомогою оберненого білінійного перетворення. Після цього ті самі локальні координати використовуються для побудови відповідної точки в системі координат робота $P_{r}=(x_{r},y_{r})$

Таким чином координати об'єкта перетворюються за схемою:

$(x_{c},y_{c})→(u,v)→(x_{r},y_{r}).$

Схема перетворення між координатними сітками камери та робота

Рис. 2. Схема перетворення координатної сітки робота та камери

2. Програмна реалізація

Для спрощення роботи з білінійними перетвореннями використовується клас Area, який реалізує пряме та обернене перетворення координат між локальною системою координат $(u,v)$ та декартовою системою координат області.

Область визначається чотирма вершинами:

Python
area = Area(p00, p01, p10, p11)

де:

$p_{00}$— стартова точка;

$p_{01}$— перша сусідня (по вектору

$p_{10}$— інша сусідня (по вектору

$p_{11}$— діагональна.

При створенні об'єкта виконується автоматична перевірка коректності області:

  • область не повинна вироджуватися в пряму;

  • область повинна задавати взаємно-однозначне білінійне відображення;

  • порядок вершин повинен відповідати наведеній схемі.

У випадку порушення цих умов буде видано помилку.

Властивість area

Повертає вершини області у порядку обходу контуру. Властивість використовується для відображення області на графіку.

Python
polygon = area.area

Результат:

Контур області, отриманий через властивість area

Рис. 3. Приклад контуру області, отриманого через властивість area

Властивість affine

Визначає тип перетворення. Повертає True, якщо область відповідає афінному перетворенню (якщо область є паралелограм) та False, якщо для області необхідно використовувати повне білінійне перетворення.

Python
area.affine

Метод find_xy()

Метод виконує пряме білінійне перетворення координат. За локальними координатами $(u, v)$ обчислюються координати точки в області. Координати можуть виходити за межі діапазону $[0,1]$, що відповідає екстраполяції.

Формат виклику:

Python
xy = area.find_xy(uv)  # -> np.ndarray

Приклад:

Python
xy = area.find_xy(0.5, 0.5)

Метод find_uv()

Метод виконує обернене білінійне перетворення. За координатами точки в області визначаються локальні координати $(u, v)$. Метод використовується для визначення положення точки всередині області та перетворення координат між різними системами.

Формат виклику:

Python
uv = area.find_uv(xy)  # -> np.ndarray

Приклад:

Python
uv = area.find_uv(150, 120)

Параметр only_inside

Для методу find_uv() за замовчуванням False. Якщо вказати True - будуть повернуті лише ті точки, які лежать всередині області.

Python
uv = area.find_uv(points, only_inside=True)

Метод contains()

Перевіряє належність точки області.

True — точка належить області;

False — точка лежить за межами області.

Перевірка виконується через знаходження локальних координат $(u, v)$. Точка вважається внутрішньою, якщо:

$0≤u≤1$

та

$0≤v≤1$

Формат виклику:

Python
mask = area.contains(points)

Приклад:

Python
points = np.array([[150, 120], [500, 400]])
mask = area.contains(points)

Результат:

Text
[ True False ]

Приклад взаємного перетворення координат

Нехай створено дві області:

Python
camera_area = Area(...)
robot_area = Area(...)

Координати об'єкта, отримані камерою:

Python
point_camera = np.array(220, 180)

Перетворення до системи координат робота:

Python
uv = camera_area.find_uv(point_camera)
point_robot = robot_area.find_xy(uv)

Виконання лабораторної роботи

Крок 1. Отримання індивідуального варіанту

Завантажте CV_library із вказаного репозиторію. Імпортуйте решту необхідних бібліотек. Створіть текстовий ключ key_word за правилами викладача та отримайте варіант завдання за допомогою функції CV_library.get_variant(). Не публікуйте ключ разом зі звітом, якщо він містить персональні дані. Після виконання функції буде сформовано словник з індивідуальними даними:

  • area1 — базова область;

  • area2 — альтернативна область;

  • grid1 — базова координатна сітка;

  • grid2 — альтернативна координатна сітка;

  • points — контрольні точки для перетворення;

  • line — рівняння прямої;

  • polynom — поліном третього порядку.

У Google Colab виконайте:

Python
!git clone https://github.com/Chiptrees/first_labs
!pip install -r first_labs/requirements.txt

import matplotlib.pyplot as plt
import numpy as np
from first_labs import CV_library

key_word = "ВКАЖІТЬ_КЛЮЧ_ЗА_ПРАВИЛАМИ_ВИКЛАДАЧА"
var = CV_library.get_variant(1, key_word)

for name, element in var.items():
    print(f"{name}:\n{element}\n")

Очікуваний результат: отримано словник з областями, сітками, контрольними точками, прямою та поліномом.

Критерій правильності: словник містить ключі area1, area2, grid1, grid2, points, line і polynom, а дані мають числовий формат без NaN.

Якщо результат не отримано: перевірте встановлення бібліотеки та ключ; не створюйте довільний варіант замість відсутніх даних.

Крок 2. Побудова областей

Python
Area1 = CV_library.Area(*var["area1"].reshape(-1, 2))
Area2 = CV_library.Area(*var["area2"].reshape(-1, 2))
Дві області білінійного перетворення

Рис. 4. Базова та альтернативна області

Очікуваний результат: створено два невироджені об'єкти Area, а їхні контури відображаються на одному графіку.

Критерій правильності: вершини з'єднані в правильному порядку, контури не мають самоперетинів, масштаб осей дозволяє порівняти області.

Якщо результат не отримано: перевірте форму масивів і порядок вершин; не продовжуйте перетворення для області, конструктор якої повернув помилку.

Крок 3. Перетворення контрольних точок

Python
points = var["points"]
uv = Area1.find_uv(points)
alt_points = Area2.find_xy(uv)
Контрольні точки у двох областях

Рис. 5. Результат перетворення контрольних точок

Очікуваний результат: для кожної контрольної точки отримано локальні координати та відповідну точку в альтернативній області.

Критерій правильності: кількість вхідних і вихідних точок однакова, а зворотне перетворення відтворює початкові точки з малою числовою похибкою.

Якщо результат не отримано: перевірте форму масиву points і належність точок області за допомогою Area1.contains(points).

Крок 4. Перетворення прямої

Python
points = points[Area1.contains(points)]
Python
uv = Area1.find_uv(points)
alt_points = Area2.find_xy(uv)
Пряма та її білінійне перетворення

Рис. 6. Перетворення точок прямої

Очікуваний результат: точки прямої, що належать базовій області, перетворено й побудовано в альтернативній області.

Критерій правильності: жодна точка поза базовою областю не потрапляє до перетворення, порядок точок уздовж лінії збережено.

Якщо результат не отримано: окремо виведіть маску contains() і перевірте, що після фільтрації залишилася непорожня множина точок.

Крок 5. Перетворення кривої третього порядку

Python
points = points[Area1.contains(points)]
Python
uv = Area1.find_uv(points)
alt_points = Area2.find_xy(uv)
Крива третього порядку та її білінійне перетворення

Рис. 7. Перетворення кривої третього порядку

Очікуваний результат: частину кривої всередині базової області перетворено й побудовано в альтернативній області.

Критерій правильності: вихідна і перетворена криві мають однакову кількість точок після фільтрації, без розривів, спричинених неправильним порядком масиву.

Якщо результат не отримано: перевірте діапазон параметра полінома, маску належності та наявність скінченних координат.

Крок 6. Перетворення на основі координатних сіток

Python
grid1 = var["grid1"]
grid2 = var["grid2"]

grid1_in_areas = []
for i, j in [(0, 0), (0, 1), (1, 0), (1, 1)]:
    vertices = grid1[i:i + 2, j:j + 2, :].reshape(-1, 2)
    grid1_in_areas.append(CV_library.Area(*vertices))

grid2_in_areas = []
for i, j in [(0, 0), (0, 1), (1, 0), (1, 1)]:
    vertices = grid2[i:i + 2, j:j + 2, :].reshape(-1, 2)
    grid2_in_areas.append(CV_library.Area(*vertices))
Базова й альтернативна координатні сітки

Рис. 8. Розбиття координатних сіток на області

Очікуваний результат: кожну сітку розбито на чотири коректні області Area та побудовано графічно.

Критерій правильності: сусідні області мають спільні межі без проміжків і накладань, усі конструктори завершуються без помилок.

Якщо результат не отримано: перевірте порядок вершин у кожному зрізі сітки та форму масивів перед створенням Area.

Крок 7. Перетворення контрольних точок (для сітки)

Python
alt_points_parts = []
for area1, area2 in zip(grid1_in_areas, grid2_in_areas):
    uv = area1.find_uv(points, only_inside=True)
    if len(uv) > 0:
        alt_points_parts.append(area2.find_xy(uv))

alt_points = np.concatenate(alt_points_parts) if alt_points_parts else np.empty((0, 2))
Перетворення контрольних точок між координатними сітками

Рис. 9. Контрольні точки після перетворення між сітками

Очікуваний результат: контрольні точки розподілено за підобластями та перетворено у відповідні підобласті другої сітки.

Критерій правильності: кожна точка оброблена не більше одного разу; кількість результатів збігається з кількістю точок усередині всієї сітки.

Якщо результат не отримано: перевірте точки на межах підобластей і зафіксуйте правило, якій області належить спільна межа.

Крок 8. Перетворення прямої (для сітки)

Python
alt_points_parts = []
for area1, area2 in zip(grid1_in_areas, grid2_in_areas):
    uv = area1.find_uv(points, only_inside=True)
    if len(uv) > 0:
        transformed = area2.find_xy(uv)
        alt_points_parts.append(transformed)
        ax[1].plot(transformed[:, 0], transformed[:, 1], color="green")

alt_points = np.concatenate(alt_points_parts) if alt_points_parts else np.empty((0, 2))
Перетворення прямої між координатними сітками

Рис. 10. Пряма після перетворення між сітками

Очікуваний результат: усі фрагменти прямої перетворено відповідними парами підобластей і побудовано на одному графіку.

Критерій правильності: на межах сусідніх областей немає необґрунтованих розривів або подвійних точок.

Якщо результат не отримано: порівняйте кінцеві точки сусідніх фрагментів і перевірте порядок пар у zip().

Крок 9. Перетворення кривої третього порядку (для сітки)

Python
alt_points_parts = []
for area1, area2 in zip(grid1_in_areas, grid2_in_areas):
    uv = area1.find_uv(points, only_inside=True)
    if len(uv) > 0:
        transformed = area2.find_xy(uv)
        alt_points_parts.append(transformed)
        ax[1].plot(transformed[:, 0], transformed[:, 1], color="green")

alt_points = np.concatenate(alt_points_parts) if alt_points_parts else np.empty((0, 2))
Перетворення кривої третього порядку між координатними сітками

Рис. 11. Крива третього порядку після перетворення між сітками

Очікуваний результат: усі фрагменти кривої перетворено між відповідними підобластями сіток.

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

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

Крок 10. Оцінювання похибки на незалежних точках

Похибка, виміряна на тих самих точках, за якими побудовано перетворення, завжди буде малою — це не характеризує якість калібрування. Оцінюйте похибку на окремому наборі точок, який не використовувався для побудови області.

Python
import numpy as np

def round_trip_error(area, points):
    """Похибка замикання: точка -> (u, v) -> точка."""
    errors = []
    for p in points:
        uv = area.find_uv(*p, only_inside=True)
        if uv is None:
            errors.append(None)          # точка поза каліброваною областю
            continue
        back = area.find_xy(*uv)
        errors.append(float(np.hypot(back[0] - p[0], back[1] - p[1])))
    return errors

Обчисліть для незалежного набору: середню похибку, максимальну похибку та кількість відхилених точок.

Очікуваний результат: три числові метрики й перелік точок, для яких перетворення не визначене.

Критерій правильності: максимальна похибка замикання не перевищує обраного вами допуску, а всі точки поза областю відхилені, а не перетворені.

Якщо результат не отримано: не змінюйте допуск під отриманий результат — перевірте порядок вершин, виродженість області та правильність вибору незалежних точок; зафіксуйте фактичну похибку у звіті.

Крок 11. Перевірка точок поза каліброваною областю

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

Очікуваний результат: точка поза областю повертає відмову при only_inside=True; точки на межах не губляться й не дублюються.

Критерій правильності: жодна відхилена точка не потрапляє в перелік координат, придатних для передавання роботу.

Якщо результат не отримано: перевірте умову включення межі в contains() і послідовність обходу підобластей.

Сценарії перевірки

  • Позитивний: точка всередині області проходить пряме й зворотне перетворення з малою числовою похибкою.
  • Негативний: точка поза областю відхиляється при only_inside=True і не передається як безпечна координата робота.
  • Граничний: точки на вершинах і межах областей не губляться та не дублюються під час обробки сітки.
  • Вироджена область: конструктор або перевірка даних має завершити обробку з помилкою, а не повертати неперевірені координати.
  • Незалежна вибірка: похибка вимірюється на точках, які не використовувались для побудови перетворення.

Таблиці вимірювань і метрики

Контрольні точки

ТочкаВхідні координатиЛокальні (u, v)Вихідні координатиПохибка замикання
P00
P01
P10
P11

Похибка на незалежному наборі

ПоказникОдна областьКоординатна сітка
Кількість точок
Середня похибка замикання
Максимальна похибка замикання
Відхилено як поза областю

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

Вимоги до звіту

Виконайте загальні вимоги до звіту. Додатково наведіть обидві таблиці вимірювань, обраний допуск похибки з обґрунтуванням, графіки областей, прямої, полінома й сіток, аналіз точок поза областю та пояснення, чому мала числова похибка не є доказом фізичної точності захоплення.

Критерії оцінювання

Застосовується базова рубрика: підготовка — 10%, реалізація — 40%, перевірка — 25%, аналіз — 15%, звіт — 10%.

Контрольні питання

  1. Чим білінійне перетворення відрізняється від афінного?
  2. Як визначити, що точка лежить поза каліброваною областю?
  3. Як перевірити похибку прямого та зворотного перетворень?
  4. Чому точки на спільних межах підобластей можуть дублюватися?

Висновки

Напишіть висновки щодо виконаної роботи.

Посилання на лабораторну роботу №17 та приклад тут:

MERCI SPACE