Mastering OpenCV with Practical Computer Vision Projects / Опановуюємо OpenCV через практичні проекти комп'ютерного зору: Розділ 8. Розпізнавання обличчя за методами Eigenfaces та Fisherfaces
| Английский оригинал | Перевод на украинский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Етап 2. Попередня обробка обличчя Atronax 22.03.21 в 14:37 |
|
|
Етап 2. Попередня обробка обличчя Atronax 22.03.21 в 14:37 |
||
|
Пошук ока Atronax 22.03.21 в 14:37 |
||
|
Пошук ока може виявитися корисним етапом попередньої обробки обличчя, тому що для фронтальних зображень облич можемо припустити, що очі людини розміщені горизонтально та симетрично відносно середини та повинні мати достатньо стандартні позиції та розміри відповідних фрагментів на зображенні, не зважаючи на зміни виразів обличчя, умови освітлення, властивості камери, відстань до неї і так далі. Також корисно відкидати хибні появи, коли детектор знаходить обличчя, але насправді отриманий об'єкт ним не є. Дуже рідко детектор обличчя та два детектори ока, діючи одночасно, формують неправильні результати, тому якщо ви обробляєте лише зображення з обличчям та двома очами, хибних появ буде не так багато (але в цьому разі матимемо менше об'єктів для обробки, бо детектор ока знаходить результат не так часто, як детектор обличчя). Atronax 22.03.21 в 14:37 |
||
|
Деякі із заздалегідь натренованих детекторів, що постачаються разом з бібліотекою OpenCV v2.4, можуть розпізнавати і відкриті, і закриті очі, у той час як інші - тільки закриті. Atronax 22.03.21 в 14:37 |
||
|
Детектори першого типу зберігаються у таких файлах: Atronax 22.03.21 в 14:37 |
||
|
Примітка Atronax 22.03.21 в 14:38 |
||
|
Детектор haarcascade_eye_tree_eyeglasses.xml здатний розпізнати очі, якщо людина носить окуляри, але не дуже надійний, якщо це не так. Atronax 22.03.21 в 14:38 |
||
|
Зони пошуку ока Atronax 22.03.21 в 14:38 |
||
|
У процесі розпізнавання важливим кроком є виокремлення фрагмента з приблизним положенням ока, для цього потрібно відшукати обличчя та вирізати невеликий прямокутник з лівим або правим оком залежно від застосованого детектора. Якщо ви виконаєте розпізнавання ока на усьому обличчі чи фотографії, страждатиме швидкість та надійність. Різні детектори ока краще працюють для певних фрагментів обличчя, наприклад haarcascade_eye.xml формує якісніші результати для дуже малих прямокутників навколо самого ока, а детектори haarcascade_mcs_lefteye.xml та haarcascade_lefteye_2splits.xml діють краще для великих фрагментів. Atronax 22.03.21 в 14:38 |
||
|
У таблиці перелічено непогані регіони пошуку обличчя для різних детекторів ока (з використанням алгоритму розпізнавання LBP), з такими відносними координатами у межах знайденого прямокутника: Atronax 22.03.21 в 14:38 |
||
|
Далі вкажемо код для вирізання фрагментів з лівим та правим оком зі знайденого обличчя: Atronax 22.03.21 в 14:39 |
||
|
Наступний малюнок зображає ідеальні регіони пошуку для різних детекторів ока. Бачимо, що haarcascade_eye.xml та haarcascade_eye_tree_eyeglasses.xml краще підходять для невеликих, а haarcascade_mcs_*eye.xml та haarcascade_*eye_2splits.xml - для великих. Також показано знайдений прямокутник обличчя, щоб проілюструвати, наскільки великі зони пошуку ока порівняно з ним. Atronax 22.03.21 в 14:39 |
||
|
Ось приблизні значення параметрів розпізнавання для різних детекторів ока: Atronax 22.03.21 в 14:39 |
||
|
Каскадний класифікатор Надійність* Швидкість** Тип знайденого ока Діє для окулярів Atronax 22.03.21 в 14:39 |
||
|
* Значення надійності вказує на те, наскільки часто обидва ока будуть знайдені за допомогою алгоритму розпізнавання фронтального обличчя LBP, якщо особа не носить окуляри, а очі відкриті. Якщо ж вони закриті, або окуляри мають певні дефекти, надійність і швидкість може знизитися. Atronax 22.03.21 в 14:39 |
||
|
** Значення швидкості вказані в мілісекундах для зображень, масштабованих до розмірів 320х240 пікселів на процесі Intel Core i7 2.2 GHz (середнє серед тисячі фотографій). Зазвичай швидкість більша, коли очі знаходяться, ніж у протилежному випадку, бо для цього може знадобитися просканувати все зображення, але навіть у такому разі детектор haarcascade_mcs_lefteye.xml все ще повільніший за інші. Atronax 22.03.21 в 14:39 |
||
|
Наприклад, ви маєте зменшити розміри фотографії до 320х240 пікселів, здійснити вирівнювання гістограми, скористатися детектором фронтальних облич LBP, виокремити регіони лівого та правого ока за допомогою значень haarcascade_mcs_lefteye.xml, потім виконати вирівнювання гістограми для кожного з них. Якщо використовуєте детектор haarcascade_mcs_lefteye.xml для лівого ока (у верхній правій частині зображення) та haarcascade_mcs_righteye.xml для правого (у верхньому лівому куті), кожен детектор ока має діяти для 90 відсотків фотографій зі знайденими фронтальними обличчями LBP. Тому, якщо потрібно розпізнати обидва ока, складений алгоритм повертатиме результат для близько 80 відсотків зображень знайдених облич. Atronax 22.03.21 в 14:39 |
||
|
Хоча й рекомендовано вирізати відповідний фрагмент кадру камери перед пошуком обличчя, очі потрібно розпізнавати на оригінальному зображенні. Вочевидь, вони значно менші за обличчя, тому роздільна здатність має бути якомога більшою. Atronax 22.03.21 в 14:39 |
||
|
Примітка Atronax 22.03.21 в 14:40 |
||
|
Але у процесі розпізнавання обличчя людина видаватиметься дещо іншою, якщо її очі закриті, тому спочатку варто скористатися простим детектором haarcascade_eye, а потім - здійснити пошук за допомогою haarcascade_eye_tree_eyeglasses. Atronax 22.03.21 в 14:41 |
||
|
Можна скористатися тією ж функцією detectLargestObject(), що й на етапі розпізнавання обличчя для пошуку очей, але замість вирізання фрагментів зображень перед етапом пошуку визначаємо ширину регіону повного ока, щоб отримати кращі результати для процесу. Ліве око легко знайти за допомогою одного детектора, а якщо він не поверне результати, можна спробувати інший (той же процес повторимо й для правого). Розпізнавання ока реалізоване таким чином: Atronax 22.03.21 в 14:41 |
||
|
CascadeClassifier eyeDetector1("haarcascade_eye.xml"); Atronax 22.03.21 в 14:42 |
||
|
Маючи розпізнані обличчя та очі, здійснимо такі етапи попередньої обробки зображення: Atronax 22.03.21 в 14:44 |
||
|
Окреме вирівнювання гістограм для лівого та правого боків. На цьому етапі стандартизуємо яскравість та контраст для обох частин зображення обличчя незалежно одна від одної. Atronax 22.03.21 в 14:44 |
||
|
Еліптична маска. Видаляє волосся та фон із зображення. Atronax 22.03.21 в 14:45 |
||
|
Наступний малюнок ілюструє етапи 1-4 попередньої обробки знайденого фрагмента обличчя. Результат має однакові показники яскравості та контрасту на обох боках обличчя, у той час як оригінальні зображення - ні. Atronax 22.03.21 в 14:45 |
||
|
Геометричні перетворення Atronax 22.03.21 в 14:45 |
||
|
Важливо мати вирівнені між собою обличчя, інакше алгоритм розпізнавання може порівнювати частину носа з оком тощо. Показаний результат має вирівнені обличчя, але не досить точні (тобто прямокутник не завжди починається у тій же точці лоба). Atronax 22.03.21 в 14:45 |
||
|
Щоб отримати кращі результати для вирівнювання, розпізнаємо очі та розмістимо їх чітко у бажаних позиціях. Геометричні перетворення здійснимо за допомогою функції warpAffine(), простої операції, яка робить чотири речі: Atronax 22.03.21 в 14:45 |
||
|
Масштабує обличчя, щоб відстань між очима не змінювалася. Atronax 22.03.21 в 14:45 |
||
|
Афінні викривлення діють на матрицю, що переносить положення двох знайдених очей у бажані позиції, а потім виконує певні операції, щоб отримати бажані розміри та позицію. Щоб згенерувати афінну матрицю, знайдемо центральну точку між очима, обчислимо кут та відстань між ними: Atronax 22.03.21 в 14:45 |
||
|
// знайдемо центральну точку між очима Atronax 22.03.21 в 14:46 |
||
|
// встановлюємо фіксовані бажані розміри обличчя Atronax 22.03.21 в 14:47 |
||
|
// зміщуємо центральні точки очей у бажаний центр Atronax 22.03.21 в 14:47 |
||
|
Окремі вирівнювання гістограм для лівого та правого боків Atronax 22.03.21 в 14:47 |
||
|
В реальних умовах часто один бік обличчя освітлений сильніше за інший. Це має величезний вплив на алгоритм розпізнавання обличчя, оскільки лівий та правий бік того ж обличчя видаватимуться як належні різним людям. Тому здійснимо вирівнювання гістограми окремо для лівої та правої половини обличчя, щоб стандартизувати яскравість та контраст для кожного боку. Atronax 22.03.21 в 14:48 |
||
|
Якщо ми просто застосуємо вирівнювання гістограми для лівого боку, а потім знову для правого, сформується чітка межа, бо середня яскравість очевидно відрізнятиметься для обох частин. Щоб її видалити, вирівнювання гістограми виконуватимемо поступово з лівого чи правого боків до центра та змішаємо їх з повною гістограмою обличчя, щоб правий бік використовував вирівнену праву гістограму, а центр - згладжену суміш лівого, правого та значення для гістограми повного обличчя. Atronax 22.03.21 в 14:48 |
||
|
Наступний малюнок ілюструє, як змішати між собою зображення з відрегульованими значеннями зліва, справа та повного кадру: Atronax 22.03.21 в 14:48 |
||
|
Для цього потрібні копії відрегульованих фрагментів зображення, які можна отримати таким чином: Atronax 22.03.21 в 14:48 |
||
|
Тепер комбінуємо три зображення. Оскільки вони малі, можна легко отримати доступ до пікселів напряму за допомогою функції image.at<uchar>(y,x), навіть якщо вона повільна; тому поєднаємо три кадри, сформувавши вихідні пікселі з відповідників на цих зображеннях: Atronax 22.03.21 в 14:48 |
||
|
for (int y=0; y<h; y++) { Atronax 22.03.21 в 14:49 |
||
|
Подібна процедура окремого вирівнення гістограм повинна значно знизити ефект різного освітлення з лівого та правого боків обличчя, але не повністю, оскільки обличчя - це складна тривимірна форма з багатьма тінями. Atronax 22.03.21 в 14:50 |
||
|
Згладжування Atronax 22.03.21 в 14:50 |
||
|
Щоб зменшити ефект піксельного шуму, застосуємо двопрохідний фільтр, адже він досить добре згладжує зображення, залишаючи межі гострими. Вирівнювання гістограми може суттєво підвищити зашумленість, тому підвищимо силу фільтру до 20, щоб видалити шум, але встановимо значення два в якості кількості сусідів, оскільки ми бажаємо згладити лише крихітні острівці піксельного шуму, а не величезні регіони зображень: Atronax 22.03.21 в 14:50 |
||
|
Mat filtered = Mat(warped.size(), CV_8U); Atronax 22.03.21 в 14:50 |
||
|
Еліптична маска Atronax 22.03.21 в 14:50 |
||
|
Хоча ми вже видалили більшу частину фону зображення, лоб та волосся, коли здійснювали геометричні перетворення, варто скористатися еліптичною маскою, щоб запобігти появі кутових фрагментів, наприклад шиї з тінню від обличчя, особливо якщо погляд не спрямований чітко на камеру. Щоб створити маску, намалюємо заповнений чорним кольором еліпс на білому фоні. Вона може мати горизонтальний радіус 0.5 (ідеально покриває ширину обличчя) і вертикальний 0.8 (оскільки обличчя звичайно мають більшу висоту), та мати центральну точку з координатами (0.5, 0.4). Далі показано, як за допомогою еліптичної маски видалено небажані кути обличчя: Atronax 22.03.21 в 14:50 |
||
|
Скористатися маскою можна за допомогою функції cv::setTo(), яка зазвичай встановлює всі пікселі зображення у певне значення, але якщо на вхід подати маску, відповідний показник встановиться лише для певних його частин. Atronax 22.03.21 в 14:50 |
||
|
// малюємо заповнений чорним кольором еліпс посередині зображення Atronax 22.03.21 в 14:51 |
