Этот проект был выполнен с помощью этой фантастической Библиотеки компьютерного зрения с открытым исходным кодом, OpenCV. В этом руководстве мы сосредоточимся на Raspberry Pi (то есть Raspbian в качестве ОС) и Python, но я также протестировал код в своих окнах, и он также отлично работает. OpenCV был разработан для вычислительной эффективности и с упором на приложения реального времени. Таким образом, он идеально подходит для распознавания лиц в реальном времени с помощью камеры.
Чтобы создать законченный проект по распознаванию лиц, мы должны работать над 3 очень разными фазами:
- Обнаружение лиц и сбор данных
- Обучить распознаватель
- Распознавание лица
После того, как вы установили OpenCV в вашей системе, давайте проверим, что ваша камера работает правильно.
Я предполагаю, что в вашей системе уже установлена веб-камера.
Приступим к первому этапу нашего проекта. То, что мы будем делать здесь, начинается с последнего шага (Обнаружение лиц), мы просто создадим набор данных, где мы будем хранить для каждого идентификатора группу фотографий серого цвета с той частью, которая использовалась для обнаружения лица.
Приступим к первому этапу нашего проекта. То, что мы будем делать здесь, начинается с последнего шага (Обнаружение лиц), мы просто создадим набор данных, где мы будем хранить для каждого идентификатора группу фотографий серого цвета с той частью, которая использовалась для обнаружения лица.
Шаг 1. Сбор данных
Приступим к первому этапу нашего проекта. То, что мы будем делать здесь, начинается с последнего шага (Обнаружение лиц), мы просто создадим набор данных, где мы будем хранить для каждого идентификатора группу фотографий серого цвета с той частью, которая использовалась для обнаружения лица.
Создайте подкаталог, в котором мы будем хранить образцы наших лиц, и назовите его «набор данных»:
import cv2 import os cam = cv2.VideoCapture(0) cam.set(3, 640) # set video width cam.set(4, 480) # set video height face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # For each person, enter one numeric face id face_id = input('\n enter user id end press <return> ==> ') print("\n [INFO] Initializing face capture. Look the camera and wait ...") # Initialize individual sampling face count count = 0 while(True): ret, img = cam.read() img = cv2.flip(img, -1) # flip video image vertically 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 # Save the captured image into the datasets folder cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w]) cv2.imshow('image', img) k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting video if k == 27: break elif count >= 30: # Take 30 face sample and stop video break # Do a bit of cleanup print("\n [INFO] Exiting Program and cleanup stuff") cam.release() cv2.destroyAllWindows()
Код очень похож на код, который мы видели для распознавания лиц. Мы добавили «команду ввода» для захвата идентификатора пользователя, который должен быть целым числом (1, 2, 3 и т. Д.).
face_id = input('\n enter user id end press ==> ')
И для каждого из захваченных кадров мы должны сохранить его как файл в каталоге «набора данных»:
cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])
Например, для пользователя с face_id = 1 четвертый образец файла в каталоге dataset / будет выглядеть примерно так:
User.1.4.jpg
Вы должны запускать сценарий каждый раз, когда хотите объединить нового пользователя (или изменить фотографии для уже существующего).
Шаг 2: Создание Trainer.yml
Мы должны взять все пользовательские данные из нашего набора данных и «обучить» OpenCV Recognizer. Это делается напрямую с помощью конкретной функции OpenCV. Результатом будет файл .yml, который будет сохранен в каталоге «trainer /».
import cv2 import numpy as np from PIL import Image import os # Path for face image database path = 'dataset' recognizer = cv2.face.LBPHFaceRecognizer_create() detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml"); # function to get the images and label data def getImagesAndLabels(path): imagePaths = [os.path.join(path,f) for f in os.listdir(path)] faceSamples=[] ids = [] for imagePath in imagePaths: PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale img_numpy = np.array(PIL_img,'uint8') id = int(os.path.split(imagePath)[-1].split(".")[1]) faces = detector.detectMultiScale(img_numpy) for (x,y,w,h) in faces: faceSamples.append(img_numpy[y:y+h,x:x+w]) ids.append(id) return faceSamples,ids print ("\n [INFO] Training faces. It will take a few seconds. Wait ...") faces,ids = getImagesAndLabels(path) recognizer.train(faces, np.array(ids)) # Save the model into trainer/trainer.yml recognizer.write('trainer/trainer.yml') # recognizer.save() worked on Mac, but not on Pi # Print the numer of faces trained and end program print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))
В качестве распознавателя мы будем использовать распознаватель лиц LBPH (LOCAL BINARY PATTERNS HISTOGRAMS), включенный в пакет OpenCV. Делаем это в следующей строке:
recognizer = cv2.face.LBPHFaceRecognizer_create()
Функция getImagesAndLabels (path) возьмет все фотографии в каталоге: «dataset /», вернув 2 массива: «Ids» и «faces». Используя эти массивы в качестве входных данных, мы «обучим наш распознаватель».
В результате файл с именем «trainer.yml» будет сохранен в каталоге трейнера, который был ранее создан нами.
Шаг 3: распознаватель
Мы снимем свежее лицо на нашу камеру, и если лицо этого человека было запечатлено и обучено ранее, наш распознаватель сделает «прогноз», возвращая его идентификатор и индекс, показывающий, насколько он уверен в этом совпадении.
import cv2 import numpy as np import os recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read('trainer/trainer.yml') cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2.CascadeClassifier(cascadePath); font = cv2.FONT_HERSHEY_SIMPLEX #iniciate id counter id = 0 # names related to ids: example ==> Marcelo: id=1, etc names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z', 'W'] # Initialize and start realtime video capture cam = cv2.VideoCapture(0) cam.set(3, 640) # set video widht cam.set(4, 480) # set video height # Define min window size to be recognized as a face minW = 0.1*cam.get(3) minH = 0.1*cam.get(4) while True: ret, img =cam.read() img = cv2.flip(img, -1) # Flip vertically gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale( gray, scaleFactor = 1.2, minNeighbors = 5, minSize = (int(minW), int(minH)), ) 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]) # Check if confidence is less them 100 ==> "0" is match 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 # Press 'ESC' for exiting video if k == 27: break # Do a bit of cleanup print("\n [INFO] Exiting Program and cleanup stuff") cam.release() cv2.destroyAllWindows()
Мы включаем сюда новый массив, поэтому мы будем отображать «имена» вместо пронумерованных идентификаторов:
names = ['None', 'Devi', 'Gopinath', 'Jayalalitha', 'Z', 'W']
Так, например: Devi будет пользователем с id = 1; Гопинатх: id = 2 и т. Д.
Затем мы обнаружим лицо, как мы делали это раньше с классификатором haarCascade. Обнаружив лицо, мы можем вызвать самую важную функцию в приведенном выше коде:
id, confidence = recognizer.predict(gray portion of the face)
Распознаватель.predict () примет в качестве параметра захваченную часть лица для анализа и вернет его вероятного владельца, указав его идентификатор и степень уверенности распознавателя в отношении этого совпадения.
Обратите внимание, что индекс достоверности вернет «ноль», если он будет сочтен идеальным совпадением
И, наконец, если распознаватель мог предсказать лицо, мы помещаем текст поверх изображения с вероятным идентификатором и какой «вероятностью» в% того, что совпадение будет правильным («вероятность» = 100 - индекс достоверности). В противном случае на лицо ставится метка «неизвестно».
Для получения подробной информации и окончательного кода посетите мой репозиторий GitHub: www.github.com/@gopinath2018
Спасибо за чтение.
Гопинатх С