python

Пишем программу для камеры хранения с функцией распознавания лица

  • вторник, 29 октября 2019 г. в 00:27:24
https://habr.com/ru/post/473510/
  • Python
  • GitHub
  • Машинное обучение
  • Прототипирование
  • Искусственный интеллект


Распознавания лиц уже захватило весь мир. Во всех крупных странах уже пользуются этой полезной фишкой. Почему не сделать жизнь людей еще удобнее и не встроить распознавание лиц в камеру хранения?

image

Для этого нам потребуется

  • скачанная нейронная сеть facenet
  • компьютер
  • keras
  • opencv

С начало импортируем зависимости

from keras.models import load_model
import numpy as np
from keras.utils import plot_model
import math
import glob
import os
import cv2
import serial

Затем загружаем сетку и указываем путь для детектора лиц
model_path = 'facenet_keras.h5'
model = load_model(model_path)
cascade_path = 'haarcascade_frontalface_alt2.xml'

Функция, которая форматирует картинку и прогоняет ее через нейросеть

def calc_embs(imgs, margin, batch_size):
    fram1e = cv2.resize(imgs,(160,160))
    ofg2 = np.array(fram1e)
    aligned_images = prewhiten(ofg2)
    pd = []
    x_train = np.array([aligned_images])
    embs1 = model.predict_on_batch(x_train)
    embs1.reshape(1,-1)
    embs = l2_normalize(np.concatenate(embs1))
    
    return embs   

Функция, которая при нажатии кнопки в первый раз сохраняет лицо человека, прошедшее через нейросеть, а во второй раз уже, прогнав через сеть новое лицо, сравнивает его с сохраненным

Заголовок спойлера
def reco_face(frame, i):

    #frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    img = frame
    #i = 0
    h = 0
    v = 0
    u = 0
    name_out = 'я тебя незнаю'
    #print(ofg.shape)
    #img = search_face(img, frame, face_cascade)
    #frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    faces = face_cascade.detectMultiScale(frame, 1.3, 5)
    print(faces)
    if faces == ():
        v = 5
    # Loop through all the faces detected and determine whether or not they are in the database
    identities = []
    for (x, y, w, h) in faces:
        x1 = x-PADDING
        y1 = y-PADDING
        x2 = x+w+PADDING
        y2 = y+h+PADDING

        frame = cv2.rectangle(frame,(x1, y1),(x2, y2),(255,0,0),2)
        height, width, channels = frame.shape
        # The padding is necessary since the OpenCV face detector creates the bounding box around the face and not the head
        part_image = frame[max(0, y1):min(height, y2), max(0, x1):min(width, x2)]
        if i == 1:
            pre[0:] = calc_embs(part_image,10,1)
            while u!=1:

                u = ser.write( b'P') 
            u=0  
        else: ofg = calc_embs(part_image,10,1)
        #print(ofg)
        #i = i + 1
        if i > 1:
            for m in pre:
                dot = np.sum(np.multiply(m, ofg), axis=0)
                norm = np.linalg.norm(m, axis=0) * np.linalg.norm(ofg, axis=0)
                similarity = dot / norm
                dist1 = np.arccos(similarity) / math.pi
                if dist1<0.32:
                    print(dist1)
                    h = 1
    return h,v



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

ser = serial.Serial('COM3', 9600, write_timeout=1, timeout=0.1)  
print(ser.name)         # check which port was really used
##sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))
#ser.close()
cap = cv2.VideoCapture(0)
zz = 0
while(True):
# Capture frame-by-frame
    ret, frame = cap.read()
    frame1 = search_face(frame)
    cv2.imshow('ffff', frame1)
    ff=ser.read(1)
    if(ff == b'B'):
        print("press_button")
        ff = b'u'
        zz = zz + 1
        mmm, f = reco_face(frame, zz)
        if f == 5:
            zz = 0
        print(mmm)
        if mmm == 1:
            print("otkrivaio")    
            while u!=1:

                u = ser.write( b'P') 
            u=0  
            h = 0  
            zz = 0     
    if cv2.waitKey(33) == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

Видео прилагается.

Как отличить лицо человека от фотографии лица человека — я еще пока не думал.