Вимірювання прямолінійного сегмента кривої (представлене у вигляді полілінії)


11

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

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

Я шукав відповіді, але не зміг знайти нічого корисного. Буду вдячний за будь-які вказівки.

Відповіді:


9

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

Наприклад, припустимо, ви маєте намір провести систематичний пошукпо всій з'єднаній складовій контуру, представленій як послідовність точок P (0), P (1), ..., P (n). Це було б зроблено шляхом ініціалізації одного вказівника (індексу в послідовності) s = 0 ("s" для "start") і іншого вказівника f (для "закінчення"), щоб бути найменшим показником, за яку відстань (P (f), P (s))> = 100, а потім просуваючись s на довгу відстань (P (f), P (s + 1))> = 100. При цьому утворюється кандидат поліліній (P (s), P (s + 1) ..., P (f-1), P (f)) для оцінки. Оцінивши його "придатність" для підтримки мітки, ви збільшуєте s на 1 (s = s + 1) і продовжуєте збільшувати f до (скажімо) f 'і s до s', поки ще раз поліліній-кандидат не перевищить мінімальний Проміжок 100 виробляється, представлений у вигляді (P (s '), ... P (f), P (f + 1), ..., P (f')). При цьому вершини P (s) ... P (s ' Дуже бажано, щоб фітнес можна було швидко оновлювати на основі знань лише опущених і доданих вершин. (Цю процедуру сканування буде продовжено до s = n; як зазвичай, f має бути дозволено "обернутись" з n назад до 0 у процесі.)

Цей розгляд виключає безліч можливих заходів придатності ( завзятість , змученість тощо), які в іншому випадку можуть бути привабливими. Це призводить до того, що ми віддаємо перевагу заходам на основі L2 , оскільки вони, як правило, можуть швидко оновлюватися, коли основні дані незначно змінюються. Беручи аналогію з аналізом головними компонент передбачає , ми приймаємо такі заходи (де маленьким краще, за запитом): використовуйте менше з двох власних в ковариационной матрицікоординат точок. Геометрично це одна міра "типового" відхилення вершин в межах кандидатської секції полілінії. (Одне тлумачення полягає в тому, що його квадратний корінь - це менша піввісь еліпса, що представляє другий момент інерції вершин поліліну.) Він дорівнює нулю лише для множин колінеарних вершин; в іншому випадку вона перевищує нуль. Він вимірює середнє відхилення в бік відносно базової лінії 100 пікселів, створеної початком і кінцем полілінії, і тим самим має просту інтерпретацію.

Оскільки матриця коваріації становить лише 2 на 2, власні значення швидко знаходять, розв’язуючи єдине квадратичне рівняння. Більше того, матриця коваріації - це сума внесків кожної з вершин у полілінії. Таким чином, він швидко оновлюється, коли точки випадають або додаються, що призводить до алгоритму O (n) для контуру n-точок: це може добре масштабуватись до дуже деталізованих контурів, передбачених у додатку.

Ось приклад результату цього алгоритму. Чорні точки - це вершини контуру. Суцільна червона лінія - найкращий кандидатський полілінійний відрізок довжиною від кінця до кінця більше 100 в межах цього контуру. (Візуально очевидний кандидат у верхньому правому куті не досить довгий.)

Малюнок


Ого, ти мене там загубив :). Ви маєте рацію щодо систематичного пошуку, я вже маю це зробити, щоб отримати дотичну до кожної вершини полілінії / багатокутника (горизонтальні мітки віддають перевагу вертикальній), тому теоретично я міг би розширити цей пошук, щоб охопити інші вимірювання. BTW: Ви створили зразок сюжету, використовуючи власне алгоритм чи вручну?
Ігор Брейц

1
Ілюстрація реальна, але реалізована мною реалізація не використовує процедуру оновлення коваріації і тому не є обчислювально оптимальною.
whuber

2
Графік наприкінці робить цю відповідь ще приголомшливішою
Рагі Ясер Бурхум

2
Ігоре, я мушу зазначити, що напрямок мітки приходить безкоштовно: він задається напрямком основної осі еліпса (власного вектора, пов'язаного з більшим власним значенням). Отже, ви можете одночасно ефективно шукати найкраще поєднання орієнтації етикетки та лінійності контуру.
whuber

3

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


1
Я думав про використання хв. обмежувальні коробки, але я бачу дві проблеми: а) обчислювальна складність обчислення поля, яка дійсно буде мінімальним (і таким чином повертається), б) два сегменти кривих з однаковим співвідношенням сторін можуть мати дуже різну кривизну (подумайте про синусоїдальну крива з однаковою амплітудою, але різними хвилями).
Ігор Брейц

1
Приємно бачити вас тут, на сторінках ГІС, Йосифе!
whuber

1
Так, у мене зараз у мене книга "Обчислювальна геометрія в С" :)
Ігор Брейц

1
Дякуємо за вітання всім! :-) Я усвідомлюю, що моя пропозиція не є ідеальним заходом, але кодування є нестандартним (якщо у вас є правильна полиця). Цей тип проблем досить багато вивчений у виробничих контекстах, де їм потрібно виміряти якість оброблюваної деталі.
Джозеф О'Рурк

3

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

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

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

Я впевнений, що це не дуже допомагає, і те, що я кажу англійською, набагато складніше в будь-якій мові програмування, яку ви використовуєте, але це може бути початком?


Цікава ідея. Щоб зробити це більш простим, ви могли обчислити співвідношення між довжиною відрізка на одній стороні та відстані між початковою та кінцевою точками. Це не так точно, але швидко обчислити. І ваше уявлення про використання кола дозволило б більш точний розрахунок прямолінійності.
Ігор Брейц

3

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

Це має бути дійсно простим у виконанні рішенням.


Оновлення: Як правильно помітив Майк, це дорівнювало б Синусоті .

введіть тут опис зображення


Тільки що мені прийшло в голову після прочитання відповіді Рекса :)
Ігор Брейц

4
в основному зворотна синусовість
Майк Т

точно :) ....
underdark

2
Ви маєте рацію, що це було б легко здійснити, оскільки оновлення довжини під час пошуку відповідних сегментів для позначення мітки просте, як додавання та віднімання довжин між послідовними вершинами. Однак синусоїдальність фактично не охоплює сенсу, в якому крива може відступати від лінійності. Наприклад, порівняйте півколо діаметром 100 з лінійною послідовністю півколів діаметром 1 : обидві криві мають однакову похиту, але бічне відхилення першої сторони в 100 разів більше, ніж другого (що було б непогано підставою для етикетки).
whuber

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

1

Шукаючи "кривизну" та "полілінію", я отримав цю інформацію Як я можу знайти кривизну полілінії? . Там він запропонував використати повернутися до визначення кривизни - K= DF/Ds. Тут Fвін має на увазі phiабо Tу позначенні вікіпедії тут ( http://en.wikipedia.org/wiki/Curvature ).

Скажімо, у вас є послідовність у трьох точках, p0, p1 та p2. обчислити відстань sміж p0 та p1, яка є дельтою s ( Ds), якщо точки, близькі одна до одної. Тоді вам потрібна дельта T ( DT), яка є зміною одиничного тангенціального вектора між p0 і p1. Можливо, існує складний спосіб, але неочищеним методом я можу придумати, щоб взяти два вектори p0-> p1, p1-> p2, нормалізувати кожен, щоб мати довжину одиниці, а потім взяти векторне віднімання цих двох, а потім визначити величину. Тобто DT. Відділення дають кривизну K0_1. схопити p1, p2 та p3 для обчислення K1_2тощо.

Мені цікаво, хоча, якщо ви будете влаштовувати контур як полілінію, а не як виведені пікселі. Ви сказали 100 пікселів, щоб змусити мене трохи хвилюватися.


Дякую за посилання, мені доведеться вивчити математику за ним. Я згадав 100px просто тому, що відредагований текст мітки має певну ширину (у пікселях), 100px був лише прикладом.
Ігор Брейц

Мислення кривизни - це приємна ідея. Викривлення на сильно згладжених контурних ділянках достатньої довжини може бути доречним, але сама кривизна ні: ні один маленький зигзаг мав би надзвичайно високу кривизну, наприклад, але був би несуттєвим у цілому. Таким чином, ви фактично використовуєте деякий статистичний підсумок відхилення від лінійності по ділянках полілінії. Серед ймовірних кандидатів кривизна була б одним із більш складних обчислень.
whuber
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.