Распознавание и обнаружение лиц с использованием Python OpenCV
Распознавание лиц - это современная технология. И сегодня мы собираемся изучить распознавание и обнаружение лиц с помощью библиотеки Python OpenCV.
Лица на фотографиях и в фильмах. Наш мозг, конечно, быстро распознает человека на фотографиях и видео.
Однако мы хотим, чтобы компьютеры или сотовые телефоны сами определяли эти элементы. Итак, давайте поговорим о двух способах обнаружения лиц на фотографиях.
Как работает распознавание лиц?
Самый популярный способ обнаружения лиц и объектов - использование классификаторов HOG.
HOG - это гистограмма ориентированных градиентов. Суть вопроса заключается в поиске подходящих дескрипторов признаков для изображения, будь то лица или другие объекты.
В 2005 году функции гистограммы ориентированных градиентов (HOG) были реализованы Навнитом Далалом и Биллом Триггсом.
Гистограмма ориентированных градиентов (HOG) - это дескриптор функции, используемый в основном для распознавания объектов при обработке изображений. Дескриптор функции - это представление изображения или фрагмента изображения, которое, извлекая из него ценную информацию, упрощает изображение.
Теория, лежащая в основе дескрипторной гистограммы направленных градиентов, заключается в том, что распределение градиентов интенсивности или направления краев будет определять внешний вид и форму локальных объектов в изображении.
Производные изображения по x и y (градиенты) полезны, потому что из-за внезапного изменения амплитуды величина градиентов высока по краям и углам, и мы знаем, что края и углы содержат намного больше деталей формы объекта, чем плоские области.
Поэтому гистограммы градиентных путей используются как свойства этого дескриптора:
Шаги по вычислению дескрипторов HOG для распознавания и обнаружения лиц
- Изображение делится на блоки 8х8 ячеек, и для каждого блока 8х8 ячеек измеряется гистограмма градиентов.
- Вектор из 9 сегментов (чисел), соответствующих углам от 0 до 180 градусов, в основном представляет собой гистограмму (с шагом 20 градусов).
- Значения этих 64 ячеек (8X8) объединяются в эти 9 сегментов и вставляются кумулятивно.
- Это в принципе ограничивает 64 значения 9 значениями.
Использование библиотеки face_recognition для обнаружения лиц
Существует библиотека face_recognition, в которой есть оптимизированный код для распознавания лиц.
pip install face_recognition
import PIL.Image
import PIL.ImageDraw
import face_recognition as fr
Затем я загрузил изображение из Интернета, на котором было много лиц:
Итак, теперь мы можем загрузить указанный выше файл:
img = fr.load_image_file("/content/boyband.jpg")
print(img)
Когда мы запускаем приведенный выше код, мы получаем такой вывод:
array([[[223, 218, 248], [223, 218, 248], [223, 218, 248], ..., [248, 248, 248], [248, 248, 248], [248, 248, 248]], [[223, 218, 248], [223, 218, 248], [223, 218, 248], ..., [248, 248, 248], [248, 248, 248], [248, 248, 248]], [[223, 218, 248], [223, 218, 248], [223, 218, 248], ..., [248, 248, 248], [248, 248, 248], [248, 248, 248]], ..., [[201, 28, 30], [205, 32, 34], [206, 32, 34], ..., [160, 14, 15], [179, 18, 23], [185, 18, 25]], [[201, 27, 29], [203, 29, 31], [204, 30, 32], ..., [152, 8, 8], [171, 12, 16], [181, 14, 21]], [[201, 27, 29], [201, 27, 29], [200, 27, 29], ..., [150, 8, 7], [167, 13, 15], [180, 15, 21]]], dtype=uint8)
Любое цветное изображение состоит из 3-х каналов: синего, зеленого и красного. Это три матрицы, представленные в приведенном выше массиве. Таким образом, цветное изображение 50 × 50 станет матрицей 50x50x3.
Мы можем получить количество лиц на фотографии, которое дает нам 10:
face_loc = fr.face_locations(img)
no_of_faces = len(face_loc)
print(no_of_faces)
Итак, у нас на фото 10 лиц. Нарисуем на этих гранях прямоугольники, а затем выведем в файл:
pil_image = PIL.Image.fromarray(img)
for face_location in face_locations:
top,right,bottom,left =face_location
draw_shape = PIL.ImageDraw.Draw(pil_image)
draw_shape.rectangle([left, top, right, bottom],outline="red")
pil_image.save("output.jpg")
дает нам:
Так что это довольно точно. Теперь поговорим о другом методе.
Использование Python OpenCV для обнаружения лиц
Python OpenCV, с другой стороны, использует каскады HAAR для обнаружения своих функций. Это немного медленнее, но очень точно!
import cv2
import matplotlib.pyplot as plt
Я сделал еще один снимок из интернета:
image2 = cv2.imread("/content/MET-GALA.jpg")
gray_img = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
plt.imshow(gray_img, cmap='gray')
дает нам:
Затем мы вводим каскадный классификатор для лица, который присутствует в OpenCV:
haar_face_cascade = cv2.CascadeClassifier('/content/haarcascade_frontalface_alt.xml')
faces = haar_face_cascade.detectMultiScale(gray_img)
print('Faces found: ', len(faces))
и это дает нам точно 8.
Итак, теперь давайте нарисуем вокруг лиц прямоугольник:
for (x, y, w, h) in faces:
cv2.rectangle(image2, (x, y), (x+w, y+h), (0, 255, 0), 2)
plt.imshow(image2)
дает нам:
И вуаля! На этом пока все.
Полный код для распознавания лиц на Python
Полный код вместе со всеми необходимыми файлами изображений и XML можно найти по адресу https://github.com/arkaprabha-majumdar/face_recog
1. Первая реализация с использованием библиотеки face_recognition
import PIL.Image
import PIL.ImageDraw
import face_recognition as fr
import matplotlib.pyplot as plt
image1 =fr.load_image_file("/content/boyband.jpg")
image2 =fr.load_image_file("/content/MET-GALA.jpg")
print(image1)
plt.imshow(image1)
pil_image = PIL.Image.fromarray(image2)
for face_location in face_loc:
top,right,bottom,left =face_location
draw_shape = PIL.ImageDraw.Draw(pil_image)
draw_shape.rectangle([left, top, right, bottom],outline="green")
pil_image.save("output.jpg")
2. Вторая реализация с использованием OpenCV
import cv2
import matplotlib.pyplot as plt
gray_img = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
plt.imshow(gray_img, cmap='gray')
haar_face_cascade = cv2.CascadeClassifier('/content/haarcascade_frontalface_alt.xml')
faces = haar_face_cascade.detectMultiScale(gray_img)
print('Faces found: ', len(faces))
for (x, y, w, h) in faces:
cv2.rectangle(image2, (x, y), (x+w, y+h), (0, 255, 0), 2)
plt.imshow(image2)
Убедитесь, что пути к файлам верны, чтобы вы могли получить точные результаты, как в наших примерах выше. Если вам нужна помощь, вы всегда можете обратиться к репозиторию Github, упомянутому выше.