- Обнаружение объектов с помощью SIFT
- Обнаружение объектов с помощью ORB
- Гистограмма ориентированных градиентов (HOG's)
- Гистограмма ориентированных градиентов (HOG), шаг за шагом:
- Каскадные классификаторы HAAR
- Обнаружение лица и глаз
- Живое обнаружение лица и глаз
- Настройка каскадных классификаторов
- Обнаружение автомобилей и пешеходов в видео
Мы начали с установки Python OpenCV в Windows и до сих пор выполняли базовую обработку изображений, сегментацию изображений и обнаружение объектов с помощью Python, которые описаны в следующих руководствах:
- Начало работы с Python OpenCV: установка и базовая обработка изображений
- Манипуляции с изображениями в Python OpenCV (часть 1)
- Манипуляции с изображениями в OpenCV (Часть 2)
- Сегментация изображений с использованием OpenCV - извлечение определенных областей изображения
Мы также узнали о различных методах и алгоритмах обнаружения объектов, где некоторые ключевые точки были определены для каждого объекта с использованием разных алгоритмов. В этом уроке мы собираемся использовать эти алгоритмы для обнаружения реальных объектов, здесь мы будем использовать SIFT и ORB для обнаружения.
Обнаружение объектов с помощью SIFT
Здесь обнаружение объекта будет выполняться с использованием потока веб-камеры в реальном времени, поэтому, если он распознает объект, он будет упоминать найденный объект. В коде основную роль играет функция, которая называется детектором SIFT, большая часть обработки выполняется этой функцией.
А в другой половине кода мы начинаем с открытия потока веб-камеры, затем загружаем шаблон изображения, то есть эталонное изображение, то есть программа фактически просматривает поток веб-камеры.
Далее, мы непрерывно захватывать изображения из потока веб - камеры с помощью бесконечного в то время цикла, а затем захватить соответствующую высоту и ширину веб - кадра, а после того, как затем определить параметры интересующей области (ROI), коробка, в которой наш объект может поместиться, взяв соответствующую высоту и ширину кадра веб-камеры. Затем мы рисуем прямоугольник из параметров ROI, которые мы определили выше. Затем, наконец, вырежьте прямоугольник и вставьте его в часть кода детектора SWIFT.
Теперь детектор SIFT в основном имеет два входа: один - это обрезанное изображение, а другой - шаблон изображения, который мы определили ранее, а затем он дает нам некоторые совпадения, поэтому совпадения в основном - это количество объектов или ключевых точек, которые похожи на обрезанное изображение. и целевое изображение. Затем мы определяем пороговое значение для совпадений, если значение совпадений больше порогового значения, мы помещаем найденное изображение на наш экран с зеленым цветом прямоугольника ROI.
Теперь вернемся к основной части кода, функции, которая называется детектором SIFT, она принимает входные данные в виде двух изображений, одно - это изображение, на котором он ищет объект, а другое - это объект, который мы пытаемся сопоставить. в (шаблон изображения). Затем сделайте шкалу серого для первого изображения и определите шаблон изображения как второе изображение. Затем мы создаем объект детектора SIFT и запускаем функцию обнаружения и вычисления OpenCV SIFT, чтобы обнаруживать ключевые точки и вычислять дескрипторы, дескрипторы - это в основном векторы, которые хранят информацию о ключевых точках, и это действительно важно, поскольку мы выполняем сопоставление между дескрипторами изображений.
А затем определите сопоставление на основе FLANN, мы не будем вдаваться в математическую теорию сопоставления, лежащую в основе этого, но вы можете легко найти это в Google. Сначала определите индекс kdtree равным нулю, а затем мы устанавливаем параметры индекса и поиска в формате словаря, мы просто определяем алгоритм, который мы собираемся использовать, это KDTREE, и количество деревьев, которые мы собираемся использовать, тем больше дерева мы используем более сложный и медленный. А в параметре поиска укажите количество проверок, то есть количество совпадений, которые он собирается выполнить.
А затем создайте наш объект сопоставления на основе FLANN, загрузив параметр, который мы ранее определили, который является параметрами индекса и параметрами поиска, и на основе этого создайте сопоставитель на основе FLANN, который является сопоставителем KNN, где KNN - это K-ближайшие соседи, в основном это способ, где мы ищем ближайшие сопоставители и дескрипторы и делаем сопоставление с константой инициализации k. Теперь этот сопоставитель на основе FLANN возвращает количество найденных совпадений.
Сопоставление на основе FLANN - это просто приближение, поэтому для повышения точности сопоставления на основе FLANN мы выполняем тест отношения Лоу, и он ищет совпадения из сопоставителя на основе knn flann и определяет некоторые матричные параметры, которые здесь являются расстоянием, для которого расстояние является функцией numpy, и, как только оно соответствует критериям, добавляет совпадения к хорошим совпадениям и возвращает найденные хорошие совпадения, и поэтому поток видео в реальном времени сообщает количество совпадений, найденных в углу экрана.
Теперь посмотрим на код для приведенного выше описания:
import cv2 import numpy as np def sift_detector (new_image, image_template): # Функция, которая сравнивает входное изображение с шаблоном # Затем возвращает количество совпадений SIFT между ними image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) 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.detect (sift.detect) None) # Определите параметры для нашего Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (алгоритм = FLANN_INDEX_KDTREE, tree = 3) search_params = ДИКТ (чеки = 100) # Создание объекта Фланна Сличитель Flann = cv2.FlannBasedMatcher (index_params, search_params) # Получить матчи с помощью K-ближайшего соседа Метод # результирующие «вышлет» это число подобных совпадений найдено в обоих изображениях матчей = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Сохранение хороших совпадений с помощью теста отношения Лоу good_matches = for m, n в совпадениях: if 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) while True: # Получить изображения с веб-камеры ret, frame = cap.read () # Получить высоту и ширину кадра веб-камеры height, 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) # Обрезать окно наблюдения, которое мы определили выше cropped = frame # Отразить ориентацию кадра по горизонтали frame = cv2.flip (frame, 1) # Получить количество совпадений SIFT совпадений = sift_detector (cropped, image_template) # Отображение строки состояния, показывающей текущий номер. of match cv2.putText (frame, str (match), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Наш порог для обозначения обнаружения объекта # Мы используем 10, так как детектор SIFT возвращает немного ложных положений threshold = 10 # Если совпадения превышают наш порог, то объект был обнаружен, если совпадения> threshold: 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 ('Object Detector using SIFT', frame) if cv2.waitKey (1) == 13: # 13 - это прерывание клавиши Enter cap.release () cv2.destroyAllWindows ()
Обнаружение объектов с помощью ORB
Обнаружение объектов с использованием SIFT - это довольно круто и точно, поскольку оно генерирует очень точное количество совпадений на основе ключевых точек, однако оно запатентовано и затрудняет его использование в коммерческих приложениях, другим выходом для этого является алгоритм ORB. для обнаружения объекта.
Подобно методу обнаружения объектов с помощью SIFT, в котором мы разделили программу на две части, здесь будет то же самое.
Во-первых, мы определяем функцию ORB_detector, которая принимает два входа: один - это изображение в реальном времени, поступающее с веб-камеры, а другой - шаблон изображения, на основе которого мы собираемся сопоставить наше изображение. Затем мы масштабируем наше изображение веб-камеры в оттенки серого, а затем инициализируем наш детектор ORB, и мы устанавливаем его здесь на 1000 ключевых точек и параметры масштабирования 1,2. вы можете легко поиграть с этими параметрами, затем определить ключевые точки (kp) и дескрипторы (des) как для изображений, так и для второго параметра, который мы определяем в detectAND. Функция вычисления NONE, она запрашивает использование маски изображения или нет и мы отрицаем это здесь.
Затем перейдите к детектору, ранее мы использовали сопоставитель на основе FLANN, но здесь мы будем использовать BFMatcher, а внутри BFMatcher мы определяем два параметра: один - NORM_HAMMING, а другой - crossCheck, значение которого TRUE.
Затем вычислите совпадения совпадений между этими двумя изображениями, используя описанные выше дескрипторы, что в целом возвращает количество совпадений, поскольку эти совпадения не являются приближением и, следовательно, нет необходимости выполнять тест соотношения Лоу, вместо этого мы сортируем совпадения на основе расстояния, по крайней мере, чем расстояние больше совпадение, тем лучше (здесь расстояние означает расстояние между точками), и в конце мы возвращаем количество совпадений, используя функцию длины.
А в основной функции мы устанавливаем порог на гораздо более высокое значение, поскольку детектор сфер генерирует много шума.
Теперь давайте посмотрим на код для обнаружения на основе ORB.
import cv2 import numpy as np def ORB_detector (new_image, image_template): # Функция, которая сравнивает входное изображение с шаблоном # Затем возвращает количество совпадений ORB между ними image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Создать детектор ORB с 1000 ключевых точек с коэффициентом пирамиды масштабирования 1,2 orb = cv2.ORB_create (1000, 1.2) # Определение ключевых точек исходного изображения (kp1, des1) = orb.detectAndCompute (image1, None) # Определение ключевых точек повернутого изображения (kp2, des2) = orb.detectAndCompute (image_template, None) # Создать сопоставление # Обратите внимание, что мы больше не используем сопоставление на основе Flann bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Соответствие совпадениям = bf.match (des1, des2) # Сортировать совпадения по расстоянию. Наименьшее расстояние # лучше соответствует = sorted (соответствует, key = lambda val: val.distance) return len ( matches ) 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 (обратите внимание, что некоторые из этих вещей должны быть вне цикла) 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) # Обрезка окна наблюдения, которое мы определили выше cropped = frame # Отразить ориентацию кадра по горизонтали frame = cv2.flip (frame, 1) # Получить количество совпадений ORB = ORB_detector (cropped, image_template) # Показать строку состояния, показывающую текущий номер. совпадений output_string = "Matches =" + str (соответствует) cv2.putText (кадр, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Наш порог для индикации обнаружения объекта # Для новых изображений или условий освещения вам может потребоваться немного поэкспериментировать # Примечание: детектор ORB для получения первых 1000 совпадений, 350 - это минимальный порог совпадения 35% = 250 # Если совпадения превышают наши threshold, то объект был обнаружен, если соответствует> threshold: 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 ('Детектор объектов с использованием ORB', фрейм), если cv2.waitKey (1) == 13: # 13 - это ограничение разрыва клавиши Enter .release () cv2.destroyAllWindows ()
Гистограмма ориентированных градиентов (HOG's)
Теперь давайте поговорим о другом дескрипторе, которым является гистограмма ориентированных градиентов (HOG).
HOG - это в значительной степени классные и полезные дескрипторы, и они широко и успешно используются для обнаружения объектов, как было показано ранее, дескрипторы изображений, такие как SIFT и ORB, где мы должны вычислять ключевые точки, а затем должны вычислять дескрипторы из этих ключевых точек, HOG делают этот процесс по-другому. Он представляет объекты как единый вектор признаков, а не набор векторов признаков, каждый из которых представляет собой сегмент изображения. Это означает, что у нас есть единая векторная функция для всего изображения.
Он вычисляется детектором скользящего окна по изображению, где дескриптор HOG вычисляется для каждой позиции. А затем каждая позиция объединяется для одного вектора признаков.
Как и в SIFT, масштаб изображения регулируется пирамидингом.
Раньше мы использовали сопоставители, такие как FLANN и BFMatcher, но HOG делают это по-другому с помощью классификаторов SVM (поддержка векторной машины), где каждый вычисленный дескриптор HOG подается в классификатор SVM, чтобы определить, был ли объект найден или нет.
Вот ссылка на Большой доклад Далала и Триггса об использовании HOG для обнаружения человека:
Гистограмма ориентированных градиентов (HOG), шаг за шагом:
Понимание HOG может быть довольно сложным, но здесь мы собираемся иметь дело только с теорией HOG, не углубляясь в математику, связанную с ней.
Итак, давайте возьмем этот снимок, он немного пикселизирован, и в верхнем углу находится прямоугольник 8x8 пикселей, поэтому в этом поле мы вычисляем вектор градиента или ориентацию краев в каждом пикселе. Таким образом, это означает, что в этом поле мы вычисляем вектор градиента изображения пикселей внутри поля (они представляют собой своего рода направление или поток самой интенсивности изображения), и это генерирует 64 (8 x 8) вектора градиента, которые затем представляются в виде гистограммы.. Итак, представьте гистограмму, которая представляет каждый вектор градиента. Итак, если все точки или интенсивности лежат в одном направлении, гистограмма для этого направления, скажем, 45 градусов, гистограмма будет иметь пик на 45 градусов.
Итак, что мы делаем сейчас, мы разбиваем каждую ячейку на угловые ячейки, где каждая ячейка соответствует направлению градиента (например, x, y). В работе Далала и Триггса они использовали 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 ячеек, при этом учитываются соседние блоки, поэтому нормализуйте, принимая во внимание более крупные сегменты изображения.
Теперь посмотрим на код
import numpy as np import cv2 import matplotlib.pyplot as plt # Загрузить изображение, затем в оттенках серого image = cv2.imread ('elephant.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Показать исходное изображение cv2.imshow (' Input Image ', image) cv2.waitKey (0) # определение параметров, размера ячейки и размера блока # hxw в пикселях cell_size = (8, 8) # hxw в ячейках block_size = (2, 2) # количество бинов ориентации nbins = 9 # Использование дескриптора HOG OpenCV # winSize - это размер изображения, обрезанного до кратного размера ячейки hog = cv2.HOGDescriptor (_winSize = (gray.shape // cell_size * cell_size, gray.shape // cell_size * cell_size), _blockSize = (block_size * cell_size, block_size * cell_size), _blockStride = (cell_size, cell_size), _cellSize = (cell_size, cell_size), _nbins = nbins) # Создаем форму, которую мы используем numpy для создания hog_features n_cells = (gray.shape // cell_size, gray.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 для хранения градиентов ориентации gradient = 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): gradient - 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 # Средние градиенты градиентов / = cell_count # Построение HOG с использованием Matplotlib # угол равен 360 / nbins * direction color_bins = 5 plt.pcolor (градиенты) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('равно', Adjust = 'box') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Изображение показывает, как входное изображение представлено как представление HOG.
Каскадные классификаторы HAAR
Как обсуждалось ранее, мы можем извлекать элементы из изображения и использовать эти функции для классификации или обнаружения объектов.
Что такое каскадные классификаторы HAAR?
Метод обнаружения объектов, который вводит характеристики Хаара в серию классификаторов (каскад) для идентификации объектов на изображении. Они обучены определять один тип объектов, однако мы можем использовать несколько из них параллельно, например, обнаруживать глаза и лица вместе.
Объяснение классификаторов HAAR:
Классификаторы HAAR обучаются с использованием множества положительных изображений (т.е. изображений с присутствующим объектом) и
отрицательных изображений (т.е. изображений без объекта).
Когда у нас есть эти изображения, мы извлекаем объекты, используя скользящие окна прямоугольных блоков. Эти функции (функции HAAR) являются однозначными и рассчитываются путем вычитания суммы интенсивностей пикселей под белыми прямоугольниками из черных прямоугольников.
Однако это смехотворное количество вычислений даже для базового окна 24 x 24 пикселя (сгенерировано 180 000 функций).
Поэтому исследователи разработали метод под названием Integral Images, который вычисляет это с четырьмя ссылками на массивы. Однако у них все еще было 180 000 функций, и большинство из них не добавляли реальной ценности.
Затем для определения наиболее информативных функций использовалось усиление с помощью AdaBoost от Freund & Schapire, которое обнаружило наиболее информативные функции в изображении. Усиление - это процесс, с помощью которого мы используем слабые классификаторы для создания сильных классификаторов, просто назначаем более тяжелые взвешенные штрафы за неправильные классификации. Сокращение 180000 функций до 6000, что по-прежнему довольно мало.
Из этих 6000 функций некоторые будут более информативными, чем другие. Итак, если бы мы использовали наиболее информативные функции, чтобы сначала проверить, может ли область потенциально иметь лицо (ложные срабатывания не будут иметь большого значения). Это избавляет от необходимости рассчитывать все 6000 функций одновременно. Эта концепция называется Каскадом классификаторов - для распознавания лиц в методе Виолы Джонса использовалось 38 этапов.
Обнаружение лица и глаз
Итак, после получения некоторых теоретических знаний о каскадах HAAR, мы собираемся, наконец, реализовать его, чтобы прояснить ситуацию, мы будем разбивать уроки по частям: сначала мы обнаружим фронтальное лицо, затем мы перейдем к обнаружению фронтального лица с помощью глаза и, наконец, мы сделаем живое обнаружение лица и глаз через веб-камеру.
Поэтому для этого мы собираемся использовать предварительно обученные классификаторы, которые были предоставлены OpenCV в виде файлов.xml, xml - это расширяемый язык разметки, этот язык используется для хранения огромного количества данных, вы даже можете создать на нем базу данных.
Вы можете получить доступ к этим классификаторам по этой ссылке .
Распознавание лиц
Попробуем фронтальное распознавание лица, здесь вы можете получить доступ к каскаду фронтального детектора лица. Просто распакуйте zip-файл, чтобы получить xml-файл.
import numpy as np import cv2 # Мы указываем функции OpenCV CascadeClassifier, где хранится наш # классификатор (формат файла XML), не забудьте сохранить код и классификатор в одной папке face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Загрузить наше изображение затем преобразует его в оттенки серого image = cv2.imread ('Trump.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Наш классификатор возвращает ROI обнаруженного лица в виде кортежа # Он сохраняет верхний левый координаты и нижние правые координаты # возвращает список списков, в которых указаны местоположения различных обнаруженных лиц. Faces = face_cascade.detectMultiScale (серый, 1.3, 5) # Когда лица не обнаружены, face_classifier возвращает пустой кортеж, если faces is (): print ("Лица не обнаружены") # Мы перебираем наш массив лиц и рисуем прямоугольник # над каждым лицом в лицах для (x, y, w, h) в лицах: cv2.rectangle (image, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Распознавание лиц', изображение) cv2.waitKey (0) cv2.destroyAllWindows ()
Теперь давайте объединим обнаружение лица и глаза вместе, вы можете получить доступ к каскаду детектора глаз в одном и том же zip-файле.
импортировать numpy как np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpgc') серый, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) # Если лица не обнаружены, face_classifier возвращает пустой кортеж, если лиц равно (): print («Лицо не найдено») для (x, y, w, h) в лицах: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = серый roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) для (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)
Таким образом, этот код такой же, как и код для обнаружения лица, но здесь мы добавили каскады глаз и метод их обнаружения, как вы можете видеть, мы выбрали версию лица со шкалой серого в качестве параметра для detectMultiScale для глаза, что приводит нас к сокращению вычислений, поскольку мы собираемся обнаруживать глаза только в этой области.
Живое обнаружение лица и глаз
Итак, до сих пор мы делали обнаружение лиц и глаз, теперь давайте реализуем то же самое с потоком видео в реальном времени с веб-камеры. Здесь мы сделаем то же самое распознавание лица и глаз, но на этот раз мы сделаем это для прямой трансляции с веб-камеры. В большинстве приложений вы обнаружите, что ваше лицо выделено рамкой вокруг него, но здесь мы сделали что-то иначе, вы бы обнаружили, что ваше лицо обрезано, и глаза будут идентифицироваться только в нем.
Итак, здесь мы импортируем классификатор лица и глаз и определили функцию для выполнения всей обработки для обнаружения лица и глаз. А после этого запустил поток веб-камеры и вызвал функцию детектора лица для определения лица и глаз. Параметр, который мы определяем внутри функции детектора лица, - это непрерывные изображения из потока веб-камеры в реальном времени.
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): # Преобразовать изображение в серый цвет (img, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) if faces is (): вернуть img для (x, y, w, h) в лицах: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2. rectangle (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = серый roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) для (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)) if cv2.waitKey (1) == 13: # 13 - это разрыв клавиши Enter cap.release () cv2.destroyAllWindows ()
Настройка каскадных классификаторов
Параметры, определенные внутри detectMultiScale, кроме входного изображения, имеют следующее значение
нашКлассификатор. detectMultiScale (входное изображение, коэффициент масштабирования, минимальное количество соседей)
- Коэффициент масштабирования Указывает, насколько мы уменьшаем размер изображения при каждом масштабировании. Например, при распознавании лиц мы обычно используем 1.3. Это означает, что мы уменьшаем изображение на 30% при каждом масштабировании. Меньшие значения, такие как 1.05, требуют больше времени для вычисления, но увеличивают скорость обнаружения.
- Min Neighbours Определяет количество соседей, которое должно иметь каждое потенциальное окно, чтобы его можно было считать положительным. Обычно устанавливается от 3 до 6. Он действует как настройка чувствительности, низкие значения иногда позволяют обнаруживать несколько лиц на одном лице. Высокие значения гарантируют меньше ложных срабатываний, но вы можете пропустить некоторые лица.
Обнаружение автомобилей и пешеходов в видео
Теперь мы будем обнаруживать пешеходов и автомобили на видео с помощью каскадов HAAR, но в случае, если видео не загружается и код компилируется без ошибок, вам необходимо выполнить следующие шаги:
Если после запуска кода видео не загружается, вам может потребоваться скопировать наш opencv_ffmpeg.dl из : opencv \ sources \ 3rdparty \ ffmpeg, чтобы вставить его туда, где установлен ваш python, например, 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 print (sys.executable)
Теперь, если вы успешно выполнили эти шаги, перейдем к коду для обнаружения пешеходов, Вы можете получить каскад для обнаружения пешеходов из прикрепленного сюда zip-файла.
import cv2 import numpy as np # Создайте наш классификатор тела body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Начните захват видео для видеофайла, здесь мы используем видеофайл, в котором будут обнаружены пешеходы cap = cv2.VideoCapture ('walking.avi') # Цикл после успешной загрузки видео, пока cap.isOpened (): # Чтение каждого кадра видео ret, frame = cap.read () # здесь мы изменяем размер кадра до половины его размера, мы делаем для ускорения классификации #, так как большие изображения имеют гораздо больше окон, которые можно перемещать, поэтому в целом мы уменьшаем разрешение # видео вдвое, это то, что указывает 0,5, и мы также используем более быстрый метод интерполяции, который #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) gray = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Передать кадр нашему классификатору тела body = body_classifier.detectMultiScale (gray, 1.2, 3) # Извлечь ограничивающие рамки для любых тел, определенных для (x, y, w, h) в body : cv2. rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Pedestrians', frame), если cv2.waitKey (1) == 13: # 13 - это разрыв клавиши Enter cap.release () cv2.destroyAllWindows ()
После успешного обнаружения пешехода на видео перейдем к коду для обнаружения автомобилей. Отсюда вы можете получить каскад для обнаружения пешеходов.
import cv2 import time import numpy as np # Создаем наш классификатор тела car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Инициируем захват видео для видеофайла cap = cv2.VideoCapture ('cars.avi') # Повторяем после успешного видео загружается, пока cap.isOpened (): time.sleep (.05) # Прочитать первый кадр ret, frame = cap.read () gray = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Передать кадр нашему автомобильному классификатору cars = car_classifier.detectMultiScale (gray, 1.4, 2) # Извлечь ограничивающие рамки для любых тел, определенных для (x, y, w, h) в автомобилях: cv2.rectangle (frame, (x, y), (x + w, y + h)), (0, 255, 255), 2) cv2.imshow ('Cars', frame) if cv2.waitKey (1) == 13: # 13 - это разрыв клавиши Enter. cap.release () cv2.destroyAllWindows ()
Вы заметили, что мы добавили time.sleep (.05) , это просто задержка частоты кадров, чтобы вы могли убедиться, что все автомобили правильно идентифицированы, или вы можете легко удалить ее, просто добавив к ней метку комментария.
Эта статья ссылается на курс Master Computer Vision ™ OpenCV4 в Python с курсом глубокого обучения по Udemy, созданный Радживом Ратаном, подпишитесь на него, чтобы узнать больше о компьютерном зрении и Python.