Замок с распознаванием лиц на Orange Pi с OpenCV и Python

Требуется взять видео поток с камеры, идентифицировать человека по лицу, открыть замок если этому человеку предоставлен доступ. Видео поток будем брать с вебки, распознавать лицо с помощью OpenCV. Системник на дверь вешать не будем. Orange Pi вполне справиться.

Устанавливаем OpenCV на Orange Pi

Приведенные ниже инструкции, думаю, будут работать на Raspberry Pi, но в ответственный момент его под рукой не оказалось, поэтому все ниже описанное я тестировал на Orange Pi. Что касается программного обеспечения, мы будем использовать OpenCV, который представляет собой компьютерное зрение и компьютерное обучение в режиме реального времени. Это позволит нам захватывать изображения с веб-камеры, манипулировать ими и применять модели распознавания лиц.

Итак, следуйте инструкциям из учебника по установке OpenCV и установите компилятор и необходимые библиотеки.

sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

Затем получите OpenCV и дополнительные модули, содержащие библиотеки распознавания лиц:

wget -O opencv-3.3.0.zip https://github.com/opencv/opencv/archive/3.3.0.zip
git clone https://github.com/opencv/opencv_contrib.git
unzip opencv-3.3.0.zip
cd opencv-3.3.0

Создайте каталог сборки:

mkdir build
cd build

Команду для сборки, я брал из руководства для Raspberry Pi, к которой добавил вариант включения дополнительных модулей с функциями распознавания лиц:

cmake -D WITH_FFMPEG=OFF -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=<path to opencv_contrib/modules/> -D BUILD_NEW_PYTHON_SUPPORT=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON ..

компилируем

make -j4

Этот шаг, на моем устройстве, занял около 1 часа. Если вы получите какую-либо ошибку из дополнительных модулей, просто удалите их. Вам нужен только модуль лица. Далее ставим OpenCV:

sudo make install

Готово. Теперь у вас есть OpenCV в Python на Orange Pi с библиотеками распознавания лиц. Вы можете протестировать его, запустив Python и импортировав cv2.

Захват видео потока с веб-камеры и распознавание лиц

Сначала напишем сценарий Python для чтения и хранения изображений модели, лиц людей, которых необходимо распознать. На втором этапе мы поставим модель на тест и посмотрим, правильно ли он распознает нужного человека.

Чтобы прочитать поток веб-камеры и сохранить лица, соответствующие человеку, используйте приведенный ниже код. Убедитесь, что у вас есть каскадный файл обнаружения лица XML. Эти каскадные файлы XML обычно лежат в opencv /data/haarcascades/. Скопируйте нужный файл в ту же папку, что и скрипт, или поместите весь put в функцию cv2.CascadeClassifier().

import os
import numpy as np
import cv2
 
# create folder to save pictures of a person
name=raw_input('Enter your name:')
if not os.path.exists('faces'):
    os.mkdir('faces' )
os.mkdir('faces/'+name )
print name+' folder created!'
path='faces/'+name
 
# import face detection cascade
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
 
# create capture object
cap = cv2.VideoCapture(0)
 
# take 10 pictures
for i in range(1,11):
    print ('Take picture '+str(i) + ' and press space') 
    while(True):
        # capture frame-by-frame
        ret, img = cap.read()
 
        # convert image to grayscale
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
        # detect face
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
 
        # for each face draw a rectangle around and copy the face
        for (x,y,w,h) in faces:
            cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
            roi_color = img[y:y+h, x:x+w]
            roi_gray = gray[y:y+h, x:x+w]
 
        # display the resulting frame
        cv2.imshow('frame',img)   
 
        # when pressing space resize face image and save it
        if cv2.waitKey(1) & 0xFF == ord(' '):
            roi_gray=cv2.resize(roi_gray,(100,100))
            cv2.imwrite(path+'/'+str(i)+'.jpg',roi_gray)
            break
     
# when everything done, release the capture
cap.release()
cv2.destroyAllWindows()

Сохраните код выше в сценарии Python input.py. Подключите веб-камеру к Orange Pi и запустите сценарий. Введите свое имя и посмотрите на камеру, нажимая пробел каждый раз, когда вокруг вашего лица появляется прямоугольник. Вы должны сделать 10 снимков, которые будут сохранены в faces/folder.

Чтобы проверить модель, сохраните код ниже в файл output.py. Код создает список лиц (объектов изображений) и ярлыков, что и требует учебная модель. Это делается путем просмотра папок и файлов в каталоге faces/, созданных предыдущим скриптом. Затем мы обучаем модель.

import cv2
import numpy as np
import os
 
faces = []
labels = []
 
path_data='faces/'
 
names=os.listdir(path_data)
i=-1
 
# read each image in the faces folder
for root, dirs, files in os.walk(path_data):
    i=i+1
    # for the recognizer we need an array of images and corresponding labels
    for name in files:
        faces.append(cv2.imread(root+'/'+name,cv2.IMREAD_GRAYSCALE))
        labels.append(i)
 
# create our LBPH face recognizer 
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
 
# import face detection cascade
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
 
# train model
face_recognizer.train(faces, np.array(labels))
 
cap = cv2.VideoCapture(0)
while(True):
    # capture frame-by-frame
    ret, img = cap.read()
 
    # put a rectangle and a label for each recognized face
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.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)
        roi_color = img[y:y+h, x:x+w]
        roi_gray = gray[y:y+h, x:x+w]
        label= face_recognizer.predict(roi_gray)
        cv2.putText(img, names[label[0]-1]+' ts:'+str(label[1]), (x, y), cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0), 2)
    # display the resulting frame
    cv2.imshow('frame',img)   
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
     
# when everything done, release the capture
cap.release()
cv2.destroyAllWindows()

Чтобы закрыть поток, нажмите клавишу q

Вот и все. Осталось только отправить сигнал на реле для открывания замка.