Про поиск лиц на фото или в видеопотоке мы уже писали. Теперь давайте займемся распознаванием с помощью библиотеки OpenCV.
Данна задача делиться на две части:
- Создание базы лица для обучения.
- Обучение распознавания лиц с помощью OpenCV Recognizer.
База данных.
Что бы распознать лицо надо собрать базу этого лица и обучить алгоритм. Для простоты эксперимента мы напишем код который будет искать лицо в видеопотоке с веб-камеры и сохранять его в папку /face
. Скажем наберем 30 штук для начала:
import cv2
import os
cam = cv2.VideoCapture(0)
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# Вводим id лица которое добавляется в имя и потом будет использовать в распознавание.
face_id = input('\n enter user id end press ==> ')
print("\n [INFO] Initializing face capture. Look the camera and wait …")
count = 0
while(True):
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_detector.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)
count += 1
# Сохраняем лицо
cv2.imwrite('face/user.' + str(face_id) + '.' + str(count) + '.jpg', gray[y:y+h,x:x+w])
cv2.imshow('image', img) k = cv2.waitKey(100) & 0xff # 'ESC'
if k == 27:
break
elif count >= 30: # Если сохранили 30 изображений выход.
break
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()
Обучение…
На этом этапе мы должны взять все данные из нашего набора и передать тренеру. OpenCV Recognizer это делает напрямую с помощью функции OpenCV. Результатом будет файл .yml
, который сохраним.
Создаем объект FaceRecognizer . Алгоритм обучения LBPH ( Histograms Local Binary Patterns ). Если честно я не очень разобрался что это за алгоритм и т.д. Документация OpenCV очень муторная. Если есть у кого хорошая ссылка пишите в комментах )))
import cv2
import numpy as np
import os
recognizer = cv2.face.LBPHFaceRecognizer_create()
Теперь мы открываем все картинки и передаем их в тренер:
def getImagesAndLabels(path): # Создаем список файлов в папке patch imagePaths = [os.path.join(path,f) for f in os.listdir(path)] face=[] # Тут храним масив картинок ids = [] # Храним id лица for imagePath in imagePaths: img = cv2.imread(imagePath) # Переводим изображение в серый, тренер понимает только одноканальное изображение img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) face.append(img) # Получаем id из названия id = int(os.path.split(imagePath)[-1].split(".")[1]) ids.append(id) return face,ids
faces,ids = getImagesAndLabels(path) # Тренируем train(данные, id)recognizer.train(faces, np.array(ids))
# Сохраняем результатrecognizer.write('face.yml')
Если вы хотите обучить из фотографий с человеком , то вам сначала надо будет найти лицо, вырезать и только после этого добавить в данные. Но мы это сделали заранее.
Итог…
Все вроде готов, давайте распознавать. Алгоритм тут достаточно просто : Ищем лицо — распознаем — рисуем рамку и пишем id или unknown.
С начало нам надо загрузить наш файл индификации, как с признаками для поиска лица :
recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read('face/face.yml')
Для распознания используем метод predict(массив картинки)
который вернет два параметра: идентификатор и степень достоверности. Обратите внимание, что степень достоверности вернет «zero», если будет достигнут идеальный результат.
import cv2 import numpy as np import osrecognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read('face/face.yml'
) cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2.CascadeClassifier(cascadePath); # Тип шрифта font = cv2.FONT_HERSHEY_SIMPLEX # iniciate id counter id = 0 # Список имен для id names = ['None', 'Keanu Reeves'] cam = cv2.VideoCapture(0) cam.set(3, 640) # set video width cam.set(4, 480) # set video height while True: ret, img = cam.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=5, minSize=(10, 10), ) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
# Проверяем что лицо распознано if (confidence < 100): id = names[id] confidence = " {0}%".format(round(100 - confidence)) else: id = "unknown" confidence = " {0}%".format(round(100 - confidence)) cv2.putText(img, str(id), (x + 5, y - 5), font, 1, (255, 255, 255), 2) cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (255, 255, 0), 1) cv2.imshow('camera', img) k = cv2.waitKey(10) & 0xff # 'ESC' для Выхода if k == 27: break cam.release() cv2.destroyAllWindows()

