Mastering OpenCV with Practical Computer Vision Projects / Опановуюємо OpenCV через практичні проекти комп'ютерного зору: Розділ 7. Оцінка 3D пози голови за допомогою AAM та POSIT
| Английский оригинал | Перевод на украинский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Якісний алгоритм комп'ютерного зору не може обійтися без корисних та надійних можливостей, узагальненості та твердої математичної основи. Всі ці особливості описані в праці Тіма Кута під назвою "Моделі активного вигляду" (Active Appearance Models, AAM). Цей розділ навчить вас створювати власну модель за допомогою бібліотеки OpenCV, а також використовувати її для пошуку найближчого положення на заданому кадрі. Крім цього, ви зрозумієте, як застосувати алгоритм POSIT та як розмістити тривимірну модель на зображенні зі встановленою позою. За допомогою цих інструментів ви зможете відслідкувати 3D модель на відео в реальному часу; хіба це не чудово? Хоча приклади фокусуються на позі голови, практично будь-яка модель з деформаціями може скористатися подібним підходом. Atronax 22.03.21 в 13:21 |
|
|
Читаючи подальший матеріал, ви познайомитесь з такими темами: Atronax 22.03.21 в 13:21 |
||
|
Наступний список пояснює терміни, які ми використаємо у розділі: Atronax 22.03.21 в 13:21 |
||
|
Аналіз головних компонент (Principal Component Analysis, PCA) - ортогональне лінійне перетворення, що трансформує дані в нову координатну систему, для якої найбільша дисперсія будь-якої проєкції даних лежить на першій координаті (що зветься першим головним компонентом), друга найбільша дисперсія - на другій координаті, і так далі. Цю процедуру часто називають зменшенням розмірності. Знижуючи це значення, ми зможемо створити більш швидкий алгоритм. Atronax 22.03.21 в 13:21 |
||
|
Триангуляція Делоне - це така триангуляція набору точок P на площині, для якої жодна точка P не лежить всередині кола, описаного навколо будь-якого трикутника триангуляції. Алгоритм не опрацьовує малі трикутники. Триангуляція необхідна для накладання текстури. Atronax 22.03.21 в 13:21 |
||
|
Огляд моделей активного вигляду Atronax 22.03.21 в 13:21 |
||
|
Коротко кажучи, моделі активного вигляду - це якісна модель, параметризована комбінацією текстури та форми, що пов'язана з ефективним алгоритмом пошуку, який може знайти точне положення та позу моделі на зображенні кадру. Для цього ми почнемо з огляду і побачимо, що вони тісно пов'язані з позиціями орієнтирів. Аналіз головних компонентів та досвід практики детальніше опишемо у наступних частинах. Тоді ж скористаємось допомогою функцій Делоне та дізнаємось дещо про триангуляцію. Далі, здобувши дані з текстури об'єкта, застосуємо пофрагментні афінні викривлення у частині про перетворення текстурних трикутників. Atronax 22.03.21 в 13:22 |
||
|
Здобувши достатню кількість даних для побудови якісної моделі, можна погратися з техніками в частині інстанціювання моделі. Потім ми зможемо знайти рішення зворотньої проблеми за рахунок пошуку AAM та розміщення 3D моделі. Atronax 22.03.21 в 13:22 |
||
|
Це вже досить корисні алгоритми для 2D або навіть 3D співпадінь зображень. Але коли вдасться змусити їх працювати, чому б не удосконалити їх за рахунок POSIT, ще одного потужного алгоритму для розміщення моделі? Занурившись в матеріали частини POSIT, дізнаємось про особливості роботи з ним в OpenCV, а потім розглянемо, як приєднати до неї модель голови. Таким чином ми зможемо розмістити 3D модель на знайденому 2D кадрі. А якщо зацікавлений читач хоче дізнатися, куди це приведе нас, об'єднавши AAM та POSIT для послідовних кадрів, ми зможемо отримати 3D відслідковування моделей з деформаціями в режимі реального часу! Деталі пояснимо у частині про процедуру обробки даних з камери чи файлу. Atronax 22.03.21 в 13:22 |
||
|
Кажуть, що одне зображення варте тисячі слів; уявіть, що ми маємо N кадрів. Пояснений раніше процес можна побачити на наступній ілюстрації: Atronax 22.03.21 в 13:22 |
||
|
Огляд алгоритмів розділу. Маючи зображення (у верхній лівій частині попереднього малюнка), можемо застосувати алгоритм пошуку активного вигляду для розпізнавання двовимірної пози людської голови. Ілюстрація у верхній правій частині скріншоту зображає заздалегідь натреновану модель активного вигляду, що використовується алгоритмом пошуку. Коли буде знайдено 2D позу, POSIT можна пристосувати для розширення результатів на 3D. Якщо процедуру виконати для послідовності відеокадрів, в результаті отримаємо 3D розпізнавання. Atronax 22.03.21 в 13:22 |
||
|
Моделі активних форм Atronax 22.03.21 в 13:22 |
||
|
Як зазначено раніше, AAM потребує модель активної форми (Active Shape Model, ASM). У наступних частинах ми створимо ASM, що є статистичною моделлю варіативності форм. Модель генерується на основі комбінації різних форм. Для цього потрібен тренувальний набір анотованих зображень, описаний у статті "Active Shape Models - Their Training and Application" Тімоті Кута. Щоб побудувати модель форми обличчя, декілька зображень з точками, визначеними на ключових позиціях, мають вказувати на головні характеристики. Наступний скріншот показує такий приклад: Atronax 22.03.21 в 13:22 |
||
|
Існує 76 орієнтирів обличчя, завантажених з набору даних MUCT. Вони, звичайно, відмічені вручну та описують декілька характеристик, наприклад контур рота, ніс, очі, брови та форму обличчя, оскільки їх легше відслідкувати. Atronax 22.03.21 в 13:22 |
||
|
Примітка Atronax 22.03.21 в 13:22 |
||
|
Аналіз Прокруста - це вид статистичного аналізу форми, що використовується для вивчення розподілу набору форм. У результаті отримаємо оптимальні значення перенесення, повороту та масштабування об'єктів. Atronax 22.03.21 в 13:23 |
||
|
Маючи попередньо вказаний набір зображень, можемо згенерувати статистичну модель варіативності форм. Оскільки позначені точки на об'єкті описують форму, спершу маємо вирівняти всі набори точок в певні рамки координат за допомогою аналізу Прокруста та представити кожну з форм у вигляді вектора x. Далі застосуємо аналіз головних компонентів (Principal Component Analysis, PCA) до даних. Потім апроксимуємо будь-який приклад такою формулою: Atronax 22.03.21 в 13:23 |
||
|
У попередній формулі, x - це середня форма, Ps - набір ортогональних режимів варіативності, а bs - набір параметрів форми. Щоб зрозуміти це краще, створимо простий застосунок у подальшому матеріалі частини, що дозволить працювати з PCA та моделями форми. Atronax 22.03.21 в 13:23 |
||
|
Навіщо взагалі використовувати PCA? Він дуже важливий, коли потрібно зменшити кількість параметрів моделі. Пізніше у розділі ми також побачимо користь цього процесу для пошуку на заданому зображенні. Детальніше з темою можна ознайомитися на ресурсі http://en.wikipedia.org/wiki/Principal_component_analysis : Atronax 22.03.21 в 13:23 |
||
|
PCA дозволяє представити користувачу зображення меншої розмірності, своєрідну "тінь" об'єкта, якщо подивитися на нього з найбільш інформативної точки зору. Це робиться лише за рахунок перших декількох головних компоненів для того, щоб зменшити розмірність трансформованих даних. Atronax 22.03.21 в 13:23 |
||
|
Все стає зрозумілим, якщо розглянути таке зображення: Atronax 22.03.21 в 13:23 |
||
|
Попередній скріншот зображає PCA багатовимірного розподілу Гауса з центром у позиції (2,3). Показалі вектори - це власні вектори матриці коваріації, зміщені таким чином, що їхні хвости мають середнє значення. Тобто, якщо ми бажаємо представити модель єдиним параметром, варто взяти напрямок з власного вектора, що вказує на верхню праву частину зображення. Крім цього, дещо змінюючи параметр, можемо екстраполювати дані та отримати значення, подібні до розшукуваних. Atronax 22.03.21 в 13:23 |
||
|
Перші кроки з PCA Atronax 22.03.21 в 13:23 |
||
|
Щоб відчути, як PCA здатне допомогти нам з моделлю обличчя, почнемо з активної моделі форми та протестуємо декілька параметрів. Atronax 22.03.21 в 13:24 |
||
|
Оскільки нам потрібна параметризація в термінах декількох скалярних значень, частіше використовуватимемо метод backproject. Він дає на основі координат головних компонентів проєктованих векторів та реконструює початкові. Ми можемо отримати початкові, якщо здобудемо усі компоненти, але різниця буде надто малою, якщо врахуємо лише декілька компонентів; це одна із причин використання PCA. Оскільки потрібна певна варіативність оригінальних векторів, наші параметризовані скаляри зможуть екстраполювати початкові дані. Atronax 22.03.21 в 13:24 |
||
|
Крім того, клас PCA здатний здійснювати перетворення векторів між початковою та новою системами координат, що визначені базисами. Згідно з документацією, математично це означає, що ми обчислюємо проєкцію вектора на підпростір, сформований декількома власними векторами, які відповідають домінантним власним значенням матриці коваріації. Atronax 22.03.21 в 13:24 |
||
|
У нашому підході анотуватимемо зображення обличчя орієнтирами, необхідними для моделі розподілення точок (Point Distribution Model, PDM). Якщо ми маємо k вирівнених орієнтирів у двох розмірностях, описа форми набуває такого вигляду: Atronax 22.03.21 в 13:24 |
||
|
Варто зауважити, що для цього потрібні стабільні анотування на всіх примірниках. Наприклад, якщо ліва частина рота відмічена орієнтиром 3 на першому кадрі, це ж значення має бути використано для решти зображень. Atronax 22.03.21 в 13:24 |
||
|
Такі послідовності орієнтирів формують контури форми, яку можна визначити у вигляді вектора. Припустимо, що їх значення мають розподіл Гауса у цьому просторі, і ми можемо застосувати PCA для обчислення нормованих власних векторів та власних значень матриці коваріації для всіх тренувальних форм. Використавши верхні центральні власні вектори, створимо матрицю розмірності 2k * m, яку назвемо P. Таким чином кожен вектор описує головний режим змін вздовж набору. Atronax 22.03.21 в 13:24 |
||
|
Тепер можна визначити нову форму таким рівнянням: Atronax 22.03.21 в 13:24 |
||
|
Наступний скріншот зображає анотовані орієнтири рота для трьох різних кадрів: Atronax 22.03.21 в 13:25 |
||
|
Наступні дані позначають екземпляр цього файлу, отриманий шляхом анотування трох зображень з бази даних IMM, значення k обрано рівним 5: Atronax 22.03.21 в 13:25 |
||
|
Маючи анотовані зображення, перетворимо ці дані в модель форми. Спочатку завантажимо їх у матрицю. Це можна зробити за рахунок функції loadPCA. Далі покажемо фрагмент коду, який її використовує: Atronax 22.03.21 в 13:25 |
||
|
PCA loadPCA(char* fileName, int& rows, int& cols,Mat& pcaset){ Atronax 22.03.21 в 13:27 |
||
|
Зауважте, ми створюємо матрицю у стрічці pcaset = Mat::eye(rows,cols,CV_64F), виділивши достатньо місця для 2*k значень. Після двох циклів for, що формують матрицю, викличемо конструктор PCA з даними, які за необхідності можуть бути заздалегідь обчисленими середніми векторами. Ми також вказуємо, що вектори збережені у вигляді рядів матриці, і що ми бажаємо зберегти ту ж їх кількість, скільки маємо компонентів, хоч і використаємо лише декілька. Atronax 22.03.21 в 13:27 |
||
|
Заповнивши об'єкт PCA тренувальними даними, матимемо все, що потрібно для зворотньої проєкції форми згідно із заданими параметрами. Це можна зробити за рахунок виклику функції PCA.backproject, передавши у першому з них вектор ряду та отримавши спроєктований результат у другому. Atronax 22.03.21 в 13:27 |
||
|
Два попередні скріншоти показують різні конфігурації форми залежно від обраних значень параметрів. Жовті та зелені відповідають даним, а червоні - формі зі вказаними характеристиками. Atronax 22.03.21 в 13:27 |
||
|
Прикладом програми можна скористатися для експериментів з моделями активних форм, адже він дозволяє користувачу змінювати різні параметри моделі. Справедливо зазначити, що регулювання лише перших двох скалярів (які відповідають першому та другому режимам дисперсії) дозволяє отримати форму, дуже близьку до натренованих. Така варіативність допоможе нам у процесі побудови моделі AAM, оскільки дає змогу отримати інтерпольовані форми. Далі ми обговоримо триангуляцію, текстурування, AAM та пошук AAM. Atronax 22.03.21 в 13:27 |
||
|
Триангуляція Atronax 22.03.21 в 13:27 |
||
|
Оскільки спостережена форма може бути викривлена (наприклад, відкритий рот), потрібно повторно відобразити нормовану текстуру на середню форму та застосувати PCA до неї. Для цього необхідна триангуляція. Концепція дуже проста: ми створимо трикутники, що міститимуть анотовані точки, а потім відобразимо один трикутник на інший. Бібліотека OpenCV постачається зі зручною функцією cvCreateSubdivDelaunay2D, яка формує пусту триангуляцію Делоне. Це доволі ефективний алгоритм, що не враховуватиме малі трикутники. Atronax 22.03.21 в 13:28 |
||
|
Примітка Atronax 22.03.21 в 13:28 |
||
|
В математиці та обчислювальній геометрії триангуляція Делоне для набору P точок на площині - це така триангуляція DT(P), для якої жодна точка P не лежить всередині кола, описаного навколо кожного трикутника DT(P). Триангуляції Делоне максимізують мінімальне значення серед усіх кутів; вони не діють на малі трикутники. Алгоритм названо за ім'ям Бориса Делоне у праці 1934 року. Atronax 22.03.21 в 13:28 |
||
|
Після налаштування сітки Делоне можна скористатися функцією cvSubdivDelaunay2DInsert для вміщення точок. Подальший фрагмент коду вкаже, яким саме чином можна застосувати триангуляцію: Atronax 22.03.21 в 13:28 |
||
|
CvMemStorage* storage; Atronax 22.03.21 в 13:28 |
||
|
Враховуйте, що наші точки лежатимуть всередині прямокутної зони, що передається у вигляді параметра функції cvCreateSubdivDelaunay2D. Щоб сформувати сітку, маємо створити та налаштувати структуру для зберігання даних у пам'яті. Це показано в перших п'ятьох стрічках попереднього фрагмента коду. Потім, щоб створити триангуляцію, додамо точки за допомогою функції cvSubdivDelaunay2DInsert. Це відбувається у циклі for. Точки вже повинні бути налаштовані, оскільки саме вони відіграють роль вхідних даних. Наступний малюнок ілюструє, якою може бути триангуляція: Atronax 22.03.21 в 13:28 |
||
|
Цей знімок є результатом виводу попереднього коду для набору точок, що формують триангуляцію за допомогою алгоритму Делоне. Хоча створювати сітку методами OpenCV дуже зручно, ітерувати по трикутникам не так легко. Далі покажемо код, який ітерує по ребрам сітки: Atronax 22.03.21 в 13:29 |
||
|
void iterate(CvSubdiv2D* subdiv, CvNextEdgeType triangleDirection){ Atronax 22.03.21 в 13:29 |
||
|
Маючи сітку, викличемо функцію cvStartReadSeq для налаштування об'єкта для зчитування ребер. Згідно з документацією OpenCV ми маємо таке визначення: Atronax 22.03.21 в 13:29 |
||
|
До альтернативних способів отримати наступний елемент відносять використання макросу CV_NEXT_SEQ_ELEM(elem_size, reader), це кращий вибір, якщо елементи послідовності мають великі розміри. У даному випадку використаємо CvQuadEdge2D* edge = (CvQuadEdge2D*) reader.ptr, щоб перетворити вказівник зчитування у вказівник на об'єкт типу CvQuadEdge2D. Макрос CV_IS_SET_ELEM перевіряє лише, встановлені окремі ребра чи ні. Маючи ребро, відшукаємо вихідну точку шляхом виклику функції cvSubdiv2DEdgeOrg. Щоб обробити регіони навколо трикутника, повторно викличемо cvSubdiv2DGetEdge та передамо напрям, наприклад CV_NEXT_AROUND_LEFT чи CV_NEXT_AROUND_RIGHT. Atronax 22.03.21 в 13:29 |
||
|
Викривлення текстури трикутника Atronax 22.03.21 в 13:29 |
