- Виявлення об'єктів за допомогою SIFT
- Виявлення об'єктів за допомогою ORB
- Гістограма орієнтованих градієнтів (HOG)
- Гістограма орієнтованих градієнтів (HOG), крок за кроком:
- Каскадні класифікатори HAAR
- Виявлення обличчя та очей
- Розпізнавання обличчя та очей у режимі реального часу
- Налаштування каскадних класифікаторів
- Виявлення автомобілів та пішоходів у відео
Ми розпочали з встановлення python OpenCV у вікнах і до цього часу виконали деякі базові процеси обробки зображень, сегментації зображень та виявлення об'єктів за допомогою Python, про які йдеться в підручниках нижче:
- Початок роботи з Python OpenCV: Встановлення та основна обробка зображень
- Маніпуляції із зображеннями в Python OpenCV (частина 1)
- Маніпуляції із зображеннями в OpenCV (Частина 2)
- Сегментація зображення за допомогою OpenCV - Вилучення певних областей зображення
Ми також дізналися про різні методи та алгоритми виявлення об'єктів, де для кожного об'єкта були визначені деякі ключові моменти за допомогою різних алгоритмів. У цьому підручнику ми збираємось використовувати ці алгоритми для виявлення реальних об’єктів життя, тут ми використовували б SIFT та ORB для виявлення.
Виявлення об'єктів за допомогою SIFT
Тут виявлення об’єктів буде здійснюватися за допомогою потоку веб-камери в реальному часі, тому, якщо він розпізнає об’єкт, він згадає про знайдене objet. У коді основну роль відіграє функція, яка називається детектором SIFT, більша частина обробки виконується цією функцією.
А в другій половині коду ми починаємо з відкриття потоку веб-камери, потім завантажуємо шаблон зображення, тобто еталонне зображення, тобто програма фактично переглядає потік веб-камери.
Далі, ми безперервно захоплювати зображення з потоку веб - камери за допомогою нескінченного в той час циклу, а потім захопити відповідну висоту і ширину веб - кадру, а після того, як потім визначити параметри, що цікавить (ROI), коробка, в якій наш об’єкт може поміститися, взявши відповідну висоту та ширину рамки веб-камери. А потім ми малюємо прямокутник із параметрів ROI, які ми визначили вище. Потім нарешті обріжте прямокутник і подайте його в частину коду SWIFT-детектора.
Тепер детектор SIFT в основному має два входи, один - це обрізане зображення, а інший - шаблон зображення, який ми раніше визначили, а потім він дає нам деякі збіги, тому збіги - це в основному кількість об’єктів або точок, схожих на обрізаному зображенні і цільове зображення. Потім визначаємо порогове значення для збігів, якщо значення збігів більше порогового, ми розміщуємо зображення, знайдене на нашому екрані із зеленим кольором прямокутника ROI.
Тепер повернімось до основної частини коду, функції, яка називається SIFT-детектором; вона приймає вхідні дані як два зображення, одне - це зображення, де він шукає об'єкт, а інше - об'єкт, якому ми намагаємося зіставити до (шаблон зображення). Потім масштабуйте перше зображення у сірому кольорі та визначайте шаблон зображення як друге. Потім ми створюємо об'єкт детектора SIFT і запускаємо функцію виявлення і обчислення OpenCV SIFT, щоб виявити ключові точки і обчислити дескриптори, дескриптори в основному є векторами, які зберігають інформацію про ключові точки, і це дуже важливо, оскільки ми робимо відповідність між дескрипторами зображень.
А потім визначимо збіг, заснований на FLANN, ми не будемо вникати в математичну теорію відповідності за ним, але ви можете легко прогуглити про це. По-перше, визначте індекс kdtree нулем, а потім ми встановимо параметри індексу та пошуку у форматі словника, ми просто визначимо алгоритм, який ми будемо використовувати, який є KDTREE, і кількість дерев, які ми будемо використовувати, тим більше дерева ми використовуємо, чим складніше воно стає і повільніше. А в параметрі пошуку визначте кількість перевірок, яка в основному є кількістю збігів, які вона збирається виконати.
А потім створіть наш об’єкт збігу на основі FLANN, завантаживши раніше визначений нами параметр, який є параметрами індексу та параметрами пошуку, і на основі цього створіть наш збіг на основі FLANN, який є збігом KNN, де KNN є K-найближчими сусідами, в основному це спосіб, де ми шукаємо найближчі збіги та дескриптори і робимо узгодження з константою ініціалізації k. Тепер цей збіг на основі FLANN повертає кількість збігів, які ми отримуємо.
Збіг на основі FLANN - це лише наближення, тому для підвищення точності збігу на основі FLANN ми проводимо тест коефіцієнта Лоу, і що він робить, це шукає збіги з збігу на основі knn flann і визначає деякі матричні параметри, які відстань, для якої відстань є функцією numpy, і як тільки вона відповідає критеріям, додайте збіги до хороших збігів і повертає знайдені хороші збіги, і таким чином прямий відеопотік повідомляє кількість збігів, знайдених у куті екрана.
Тепер давайте розглянемо код для наведеного вище опису:
import cv2 import numpy як np def sift_detector (new_image, image_template): # Функція, яка порівнює вхідне зображення зі шаблоном # Потім повертає кількість збігів SIFT між ними image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GREY) image2 = image_template # Create Об'єкт детектора SIFT #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Отримати ключові точки та дескриптори за допомогою SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2 = sift.detete2A. Немає) # Визначте параметри для нашого Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (алгоритм = FLANN_INDEX_KDTREE, дерева = 3) search_params = dict (перевірки = 100) # Створіть об'єкт Flann Matcher flann = cv2.FlannBasedMatcher (index_params, search_params) # Отримати збіги за допомогою K-найближчого методу сусідів # результат 'matchs' - це кількість схожих збігів, знайдених в обох збігах = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Зберігайте хороші збіги, використовуючи тест коефіцієнта Лоу good_matches = для m, n у збігах : якщо m.distance <0,7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Завантажте шаблон нашого зображення, це наше посилальне зображення image_template = cv2.imread ('phone.jpg', 0), поки True: # Отримати зображення веб-камери ret, frame = cap.read () # Отримати висоту та ширину висоти кадру веб-камери , width = frame.shape # Визначити розміри поля ROI top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # Намалюйте прямокутне вікно для нашої цікавої області cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Вікно обрізання спостереження, яке ми визначили вище обрізане = кадр # Перевернути орієнтацію кадру горизонтально frame = cv2.flip (frame, 1) # Отримати кількість відповідностей SIFT збігів = sift_detector (обрізаний, image_template) # Відобразити рядок стану, що відображає поточний номер. збігів cv2.putText (кадр, str (збіги), (450 450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Наш поріг для позначення виявлення об'єкта # Ми використовуємо 10, оскільки детектор SIFT повертає мало помилкових позицій порог = 10 # Якщо збіги перевищують наш поріг, то об'єкт виявлено, якщо збіги> поріг: cv2.rectangle (кадр, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (кадр, 'Об'єкт знайдений', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Об'єкт-детектор за допомогою SIFT', кадр), якщо cv2.waitKey (1) == 13: # 13 - Enter Break break cap.release () cv2.destroyAllWindows ()
Виявлення об'єктів за допомогою ORB
Виявлення об'єктів за допомогою SIFT є набагато крутішим і точнішим, оскільки воно генерує набагато точнішу кількість збігів на основі ключових точок, проте запатентовано, і це ускладнює його використання для комерційних додатків, іншим виходом для цього є алгоритм ORB для виявлення об'єкта.
Подібно до методу виявлення об'єктів за допомогою SIFT, в якому ми розділили програму на дві частини, тут буде дотримуватися того самого.
По-перше, ми визначаємо функцію ORB_detector, яка приймає два входи: один - це зображення потокової трансляції, що надходить з веб-камери, а інше - шаблон зображення, на основі якого ми збираємося відповідати нашому зображенню. Потім ми масштабуємо зображення нашого веб-камери у градаціях сірого, а потім ініціалізуємо наш детектор ORB, і встановлюємо його тут на 1000 ключових точок та параметри масштабування 1,2. ви можете легко пограти з цими параметрами, потім виявити ключові точки (kp) і дескриптори (des) як для зображень, так і для другого параметра, який ми визначаємо у функції виявлення ANDCompute, НІЧЕ , він вимагає використання маски зображення чи ні, і ми заперечуємо це тут.
Потім перейдіть до детектора, раніше ми використовували збіг на основі FLANN, але тут ми будемо використовувати BFMatcher, а всередині BFMatcher визначимо два параметри, один - NORM_HAMMING, а інший - перехресна перевірка, значення якого TRUE.
Потім обчисліть збіги збігів між цими двома зображеннями, використовуючи дескриптори, визначені вище, що у всіх повертає кількість збігів, оскільки ці збіги не є апроксимацією, і тому немає необхідності робити тест коефіцієнта Лоу, натомість ми сортуємо збіги на основі відстані, принаймні відстань більше збігу краще (тут відстань означає відстань між точками), і в кінці ми повертаємо кількість збігів за допомогою функції length.
І в основній функції ми встановлюємо поріг набагато вищого значення, оскільки детектор кулі генерує значну кількість шуму.
Тепер давайте розглянемо код для виявлення на основі ORB
import cv2 import numpy як np def ORB_detector (new_image, image_template): # Функція, яка порівнює вхідне зображення зі шаблоном # Потім повертає кількість збігів ORB між ними image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GREY) # Створити детектор ORB за допомогою 1000 ключових точок з коефіцієнтом піраміди масштабування 1,2 orb = cv2.ORB_create (1000, 1.2) # Виявлення ключових точок оригінального зображення (kp1, des1) = orb.detectAndCompute (image1, None) # Виявлення точок повернення зображення (kp2, des2) = orb.detectAndCompute (image_template, None) # Створити збіг # Зверніть увагу, що ми більше не використовуємо Flannbassed bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Зробити відповідні збіги = bf.match (des1, des2) # Сортувати збіги на основі відстані. Найменша відстань # найкраще збігається = сортується (збіги, ключ = лямбда-вал: val.distance) return len (збіги) cap = cv2.VideoCapture (0) # Завантажте наш шаблон зображення, це наше довідкове зображення image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) while True: # Отримати зображення веб-камери ret, frame = cap.read () # Отримати висоту та ширину висоти кадру веб-камери , width = frame.shape # Визначте розміри ROI Box (Зверніть увагу, що деякі з цих речей не повинні знаходитися в циклі) top_left_x = int (width / 3) top_left_y = int ((висота / 2) + (висота / 4)) bottom_right_x = int ((ширина / 3) * 2) bottom_right_y = int ((висота / 2) - (висота / 4)) # Намалюйте прямокутне вікно для нашого область інтересу cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Вирізане вікно спостереження, яке ми визначили вище обрізане = кадр # Перевернути орієнтацію кадру горизонтально frame = cv2.flip (кадр, 1) # Отримати кількість збігів ORB збігів = ORB_detector (обрізаний, шаблон_образу) # Відобразити рядок стану, що відображає поточний номер. збігів output_string = "Matches =" + str ( match) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Наш поріг для позначення виявлення об’єкта # Для нових зображень чи умов освітлення вам може знадобитися трохи поекспериментувати # Примітка: ORB-детектор, щоб отримати 1000 найкращих збігів, 350 - це, по суті, мінімальний поріг збігу 35% = 250 # Якщо збіги перевищують наші поріг, тоді об'єкт виявлено, якщо збігається> поріг: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Object Found', (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow (Об'єкт Detector з допомогою ORB ', рамка), якщо cv2.waitKey (1) == 13: # 13 введення ключа розриву ковпачок.release () cv2.destroyAllWindows ()
Гістограма орієнтованих градієнтів (HOG)
Тепер поговоримо про інший дескриптор, який є гістограмою орієнтованих градієнтів (HOG).
HOG - це в значній мірі прохолодні та корисні дескриптори, і вони широко та успішно використовуються для виявлення об'єктів, як це вже бачили дескриптори зображень, такі як SIFT та ORB, де нам потрібно обчислювати ключові точки, а потім обчислювати дескриптори з цих ключових точок, HOG роблять цей процес по-різному. Він представляє об'єкти як єдиний вектор об'єктів на відміну від набору векторів об'єктів, де кожен представляє сегмент зображення. Це означає, що ми маємо одновекторну функцію для всього зображення.
Він обчислюється за допомогою розсувного віконного детектора над зображенням, де дескриптор HOG обчислюється для кожної позиції. А потім кожна позиція поєднується для одного вектора ознак.
Як і SIFT, масштаб зображення регулюється за допомогою піраміди.
Раніше ми використовували збіги, такі як FLANN та BFMatcher, але HOG роблять це по-різному за допомогою класифікаторів SVM (машина з підтримкою векторів), де кожен обчислюваний дескриптор HOG подається в класифікатор SVM, щоб визначити, був знайдений об'єкт чи ні.
Ось посилання на великий документ від Dalal & Triggs про використання HOG для виявлення людини:
Гістограма орієнтованих градієнтів (HOG), крок за кроком:
Розуміння HOG може бути досить складним, але тут ми будемо мати справу лише з теорією HOG, не заглиблюючись в математику, пов’язану з нею.
Отже, давайте зробимо цей знімок, він трохи піксельований, і у верхньому куті тут знаходиться поле розміром 8x8 пікселів, тому в цьому полі ми обчислюємо вектор градієнта або орієнтації країв на кожному пікселі. Отже, це означає, що в цьому вікні ми обчислюємо вектор градієнта зображення пікселів усередині вікна (вони є своєрідним напрямком або потоком самої інтенсивності зображення), і це генерує 64 (8 х 8) векторів градієнта, які потім представляються у вигляді гістограми. Тож уявіть собі гістограму, яка представляє кожен вектор градієнта. Отже, якби всі точки або інтенсивності лежали в одному напрямку, гістограма для цього напрямку, скажімо, 45 градусів, гістограма мала б пік у 45 градусів.
Отже, що ми робимо зараз, ми розділяємо кожну клітинку на кутові бункери, де кожна бін відповідає напрямку градієнта (наприклад, x, y). У роботі Dalal і Triggs вони використовували 9 контейнерів 0-180 ° (по 20 ° кожен бункер). Це ефективно зменшує 64 вектори лише до 9 значень. Отже, те, що ми зробили, зменшило розмір, але зберегло всю необхідну ключову інформацію.
Наступним кроком при розрахунку свиней є нормалізація, ми нормалізуємо градієнти, щоб забезпечити незмінність до змін освітленості, тобто яскравість і контраст.
На цьому зображенні значення інтенсивності відображаються у квадраті відповідно до відповідного напрямку і мають різницю між собою 50
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Ми ділимо вектори на величини градієнта, отримуємо 0,707 для всіх, це нормалізація.
Подібним чином, якщо ми змінимо інтенсивність або змінимо контраст, ми отримаємо наступні значення.
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707; ∆ H = 100, ∆ v = 100; │∆│ = √100 2 +100 = 141,42, 141,42 / 100 = 1,41
Нормалізація не відбувається на рівні комірки, натомість вона відбувається на рівні блоку, тому тут блоки в основному являють собою групу з 4 комірок, це враховує сусідні блоки, тому нормалізуйте, беручи до уваги більші сегменти зображення.
А тепер давайте розглянемо код
імпортувати numpy як np імпортувати cv2 імпортувати matplotlib.pyplot як plt # Завантажити зображення, потім відтінки сірого image = cv2.imread ('elephant.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GREY) # Показати оригінальне зображення cv2.imshow (' Вхідне зображення ', зображення) cv2.waitKey (0) #визначення параметрів, розміру комірки та розміру блоку # hxw у пікселях cell_size = (8, 8) # hxw у комірках block_size = (2, 2) # кількість орієнтаційних бункерів nbins = 9 # Використання HOG Descriptor # winSize - це розмір зображення, обрізаного до кратного розміру комірки hog = cv2.HOGDescriptor (_winSize = (grey.shape // cell_size * cell_size, grey.shape // cell_size * cell_size), _blockSize = (block_size * size_size, block_size * cell_size), _blockStride = (cell_size, cell_size), _cellSize = (cell_size, cell_size), _nbins = nbins) # Створюємо числовий масив створити hog_features n_cells = (gray.shape // size_size, grey.shape // cell_size) # Спочатку ми індексуємо блоки за рядками. # hog_feats тепер містить амплітуди градієнта для кожного напрямку, # для кожної комірки своєї групи для кожної групи. Індексація відбувається за рядками, а потім за стовпцями. hog_feats = hog.compute (сірий).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Створіть наш масив градієнтів з розмірами nbin для зберігання градієнтних орієнтацій gradients = np.zeros ((n_cells, n_cells, nbins)) # Створіть масив розмірів cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Нормалізація блоку для off_y в діапазоні (block_size): для off_x в діапазоні (block_size): градієнти - block_size + off_y + 1, off_x: n_cells - block_size + off_x + 1] + = \ hog_feats cell_count - block_size + off_y + 1, off_x: n_cells - block_size + off_x + 1] + = 1 # Середні градієнти градієнтів / = count_count # Графік HOGs з використанням Matplotlib # кут 360 / nbins * напрямок color_bins = 5 plt.pcolor (градієнти) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('дорівнює', регулюється = 'коробка') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Зображення показує, як вхідне зображення представляється як представлення HOG.
Каскадні класифікатори HAAR
Як вже обговорювалося раніше, ми можемо витягувати ознаки із зображення та використовувати ці ознаки для класифікації або виявлення об'єктів.
Що таке каскадні класифікатори HAAR?
Метод виявлення об'єктів, який вводить характеристики Хаара в ряд класифікаторів (каскад) для ідентифікації об'єктів на зображенні. Вони навчені ідентифікувати один тип об’єкта, однак ми можемо використовувати кілька з них паралельно, наприклад, виявляючи очі та обличчя разом.
Пояснення щодо класифікаторів HAAR:
Класифікатори HAAR навчаються з використанням безлічі позитивних зображень (тобто зображень із наявним об’єктом) та
негативних зображень (тобто зображень без присутності об’єкта).
Отримавши ці зображення, ми витягуємо функції за допомогою розсувних вікон прямокутних блоків. Ці ознаки (особливості HAAR) мають одну оцінку і обчислюються шляхом віднімання суми інтенсивності пікселів під білими прямокутниками з чорних прямокутників.
Однак це безглузда кількість обчислень, навіть для базового вікна 24 х 24 пікселів (180 000 створених функцій).
Тож дослідники розробили метод під назвою Integral Images, який обчислював це за допомогою чотирьох посилань на масив. Однак вони все ще мали 180 000 функцій, і більшість із них не додавали реальної вартості.
Підвищуючи потім був використаний для визначення найбільш інформативних ознак, з Фрейнда & Schapire в AdaBoost і він знайшов найбільш інформативних ознак на зображенні. Підвищення - це процес, за допомогою якого ми використовуємо слабкі класифікатори для створення сильних класифікаторів, просто призначаючи більш важкі покарання за неправильні класифікації. Зменшення 180 000 функцій до 6000, що все ще досить мало можливостей.
У цих 6000 функціях деякі будуть більш інформативними, ніж інші. Отже, якщо ми використали найбільш інформативні функції, щоб спочатку перевірити, чи може регіон потенційно мати обличчя (помилкові спрацьовування не становитимуть великої праці). Це виключає необхідність обчислювати всі 6000 функцій одночасно. Ця концепція називається Каскадом класифікаторів - для виявлення обличчя метод Віоли Джонса використовував 38 етапів.
Виявлення обличчя та очей
Отже, отримавши деякі теоретичні знання про каскади HAAR, ми збираємось нарешті реалізувати їх, щоб зробити речі майже зрозумілими, ми розіб’ємо уроки по частинах, спочатку ми виявимо лобове обличчя, після чого перейдемо до виявлення лобового обличчя очі і, нарешті, ми зробили б виявлення обличчя та очей у реальному часі через веб-камеру.
Отже, для цього ми будемо використовувати заздалегідь підготовлені класифікатори, які OpenCV надав як файли.xml, xml означає розширювану мову розмітки, ця мова використовується для зберігання величезної кількості даних, на ній навіть можна створити базу даних.
Ви можете отримати доступ до цих класифікаторів за цим посиланням .
Розпізнавання обличчя
Давайте спробуємо виявити фронтальне обличчя, тут ви можете отримати доступ до каскаду фронтального детектора обличчя. Просто витягніть zip-файл, щоб отримати xml-файл.
import numpy як np import cv2 # Ми вказуємо на функцію CascadeClassifier OpenCV туди, де зберігається наш # класифікатор (формат файлу XML), не забудьте зберігати код і класифікатор в одній папці face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Завантажити наше зображення потім перетворює його у відтінки сірого image = cv2.imread ('Trump.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GREY) # Наш класифікатор повертає ROI виявленого обличчя у вигляді кортежу # Він зберігає лівий верхній кут координата і внизу праворуч координати # вона повертає список списків, де знаходяться різні виявлені грані. faces = face_cascade.detectMultiScale (сірий, 1.3, 5) # Коли граней не виявлено, повертається face_classifier і порожній кортеж, якщо face is (): print (" Граней не знайдено") # Ми перебираємо масив наших граней і малюємо прямокутник # над кожним гранями в гранях для (x, y, w, h) в гранях: cv2.rectangle (зображення, (x, y), (x + w, y + h), (127,0255), 2) cv2.imshow ('Виявлення обличчя', зображення) cv2.waitKey (0) cv2.destroyAllWindows ()
Тепер давайте поєднаємо виявлення обличчя та очей разом, ви зможете отримати доступ до каскаду детекторів очей у тому самому ZIP-файлі.
import numpy as np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') grey = cv2.c cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (сірий, 1.3, 5) # Коли граней не виявлено, повертається face_classifier і порожній кортеж, якщо face is (): print ("Face No Found") для (x, y, w, h) в гранях: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0255), 2) cv2.imshow ('img', img) roi_gray = grey roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) for (ex, ey, ew, eh) в очах: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (255,255,0), 2) cv2.imshow ('img', img) cv2.waitKey (0) cv2.destroyAllWindows () cv2.waitKey (0)
Отже, цей код такий самий, як і код для виявлення обличчя, але тут ми додали каскади очей та метод їх виявлення, як ви бачите, ми вибрали сіру версію обличчя в масштабі сірого як параметр для виявлення MultiScale для очі, що призводить до зменшення обчислень, оскільки ми збираємося виявляти очі лише в цій області.
Розпізнавання обличчя та очей у режимі реального часу
Отже, до цього часу ми робили виявлення обличчя та очей, а тепер давайте застосуємо те саме з потоковим відео з веб-камери. У цьому ми будемо робити те саме виявлення обличчя та очей, але цього разу ми будемо робити це для прямого ефіру з веб-камери. У більшості додатків ви знаходите своє обличчя, виділене коробкою навколо нього, але тут ми зробили щось інше, що ви виявите, що ваше обличчя обрізане, а очі ідентифікуються лише в цьому.
Отже, тут ми імпортуємо класифікатор обличчя та очей та визначили функцію для обробки всієї функції виявлення обличчя та очей. А після цього запустив потік веб-камери і викликав функцію детектора обличчя для виявлення обличчя та очей. Параметр, який ми визначаємо всередині функції детектора обличчя, - це безперервні зображення із потокового веб-камери
import cv2 import numpy as np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0.5): # Convertv imaget cvlor.ca (img, cv2.COLOR_BGR2GREY) грані = face_classifier.detectMultiScale (сірий, 1.3, 5), якщо грані є (): поверніть img для (x, y, w, h) в гранях: x = x - 50 w = w + 50 y = y - 50 год = h + 50 cv2.прямокутник (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = сірий roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) for (ex, ey, ew, eh) в очах: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) return roi_color cap = cv2.VideoCapture (0) while True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)), якщо cv2.waitKey (1) == 13: # 13 - клавіша Enter Enter break cap.release () cv2.destroyAllWindows ()
Налаштування каскадних класифікаторів
Параметри, визначені всередині виявленняMultiScale, крім вхідного зображення, мають таке значення
наш Класифікатор. deteMultiScale (вхідне зображення, коефіцієнт масштабу, мінімальний рівень сусідів)
- Фактор масштабу Вказує, наскільки ми зменшуємо розмір зображення кожного разу, коли масштабуємо. Наприклад, при виявленні обличчя ми зазвичай використовуємо 1.3. Це означає, що ми зменшуємо зображення на 30% кожного разу, коли воно масштабується. Для обчислення менших значень, таких як 1,05, знадобиться більше часу, але це збільшить швидкість виявлення.
- Мінімум сусідів Вказує кількість сусідів, яке має мати кожне потенційне вікно, щоб вважати це позитивним виявленням. Зазвичай встановлюється між 3-6. Він діє як налаштування чутливості, низькі значення іноді виявляють кілька граней на одному обличчі. Високі значення забезпечать менше помилкових спрацьовувань, але деякі обличчя ви можете пропустити.
Виявлення автомобілів та пішоходів у відео
Тепер ми будемо виявляти пішоходів та автомобілі у відеозаписах за допомогою каскадів HAAR, але у випадку, якщо жодне відео не завантажується, а код компілюється без помилок, вам потрібно виконати такі дії:
Якщо після запуску коду відео не завантажується, можливо, вам доведеться скопіювати наш opencv_ffmpeg.dl з : opencv \ sources \ 3rdparty \ ffmpeg, щоб вставити його там, де встановлено ваш пітон, наприклад C: \ Anaconda2
Після копіювання вам потрібно буде перейменувати файл відповідно до версії OpenCV, яку ви використовуєте. Наприклад, якщо ви використовуєте OpenCV 2.4.13, тоді перейменуйте файл як: opencv_ffmpeg2413_64.dll або opencv_ffmpeg2413.dll (якщо ви за допомогою машини X86) opencv_ffmpeg310_64.dll або opencv_ffmpeg310.dll (якщо ви використовуєте машину X86)
Щоб дізнатись, де встановлено python.exe, просто запустіть ці два рядки коду, він надрукує місце, де встановлено python.
імпортувати друк sys (sys.executable)
Тепер, якщо ви успішно виконали ці кроки, перейдемо до коду для виявлення пішоходів, Ви можете замовити каскад для виявлення пішоходів та із закріпленого тут zip-файлу.
import cv2 import numpy as np # Створіть наш класифікатор тіла body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Ініціюйте відеозйомку для відеофайлу, тут ми використовуємо відеофайл, в якому буде виявлено пішоходів cap = cv2.VideoCapture ('walking.avi') # Цикл після успішного завантаження відео, поки cap.isOpened (): # Читання кожного кадру відеозйомки , frame = cap.read () # тут ми зменшуємо розмір кадру до половини його розміру, ми робимо це, щоб прискорити класифікацію #, оскільки більші зображення мають набагато більше вікон, щоб пересуватися, тому загалом ми зменшуємо роздільну здатність # відео вдвічі - це те, що вказує 0.5, і ми також використовуємо швидший метод інтерполяції, який є #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) grey = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Передати кадр до нашого класифікатора тіл body = body_classifier.detectMultiScale (сірий, 1.2, 3) # Витягнути обмежувальні поля для будь-яких тіл, визначених для (x, y, w, h) у тілах: cv2. прямокутник (кадр, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Пішоходи', кадр), якщо cv2.waitKey (1) == 13 # 13 є Enter Key перерву cap.release () cv2.destroyAllWindows ()
Після успішного виявлення пішохода у відео, перейдемо до коду для виявлення автомобіля. Ви можете вибрати каскад для виявлення пішоходів звідси.
імпорт cv2 час імпорту імпорт numpy як np # Створіть наш класифікатор тіла car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Ініціювати зйомку відео для відеофайлу cap = cv2.VideoCapture ('cars.avi') # Цикл після успішного завершення відео завантажується в той час як cap.isOpened (): time.sleep (.05) # Прочитати перший кадр ret, frame = cap.read () grey = cv2.cvtColor (frame, cv2.COLOR_BGR2GREY) # Передати кадр до нашого класифікатора автомобілів cars = car_classifier.detectMultiScale (сірий, 1.4, 2) # Витягнути обмежувальні рамки для будь-яких тіл, визначених для (x, y, w, h) у автомобілях: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Автомобілі', кадр), якщо cv2.waitKey (1) == 13: # 13 - це клавіша розбиття клавіш cap.release () cv2.destroyAllWindows ()
Ви помітили, що ми додали time.sleep (.05) , це просто затримка частоти кадрів, щоб ви могли підтвердити, що всі машини визначені правильно, або ви можете легко видалити його, просто додавши до нього ярлик коментаря.
Ця стаття посилається на Master Computer Vision ™ OpenCV4 на Python з курсом глибокого навчання на Udemy, створений Раджеєвим Ратаном. Підпишіться, щоб дізнатись більше про Computer Vision та Python.