For this we need
- downloaded neural network facenet
- a computer
- keras
- opencv
From the beginning we import dependencies
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'
A function that formats a picture and drives it through a neural network
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
A function that, when a button is pressed for the first time, saves a person’s face that has passed through a neural network, and a second time already, having driven a new face through the network, compares it with the saved face
Spoiler heading
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
Well and maine. It all starts with arduino when the letter B is fed through the wart, which means that the button is pressed. Next, a command is sent to the arduino to open the box and the function for recognizing and saving the face is launched. Then, if the command to press the button again came from the arduino, we again start the recognition function and if the faces converge, then open the box.
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()
The video is attached.
How to distinguish a person’s face from a photograph of a person’s face - I have not yet thought.
Link to github where the script lies