Differences

This shows you the differences between two versions of the page.

Link to this comparison view

iothings:proiecte:2022:dor_bell [2023/01/19 22:34]
adriana.boncu [Implementation of the solution]
iothings:proiecte:2022:dor_bell [2023/01/20 11:31] (current)
adriana.boncu [Demo Video]
Line 41: Line 41:
 System}} System}}
  
-As can be seen in Figure 1, the stepper motor driver is connected to pins D13,​D12,​D14,​D27 (IN1,​IN2,​IN3,​IN4-stepper driver pins in order), the button is connected to the pin D34, and the buzzer is connected to pin D32.+As can be seen in figure, the stepper motor driver is connected to pins D13,​D12,​D14,​D27 (IN1,​IN2,​IN3,​IN4-stepper driver pins in order), the button is connected to the pin D34, and the buzzer is connected to pin D32.
  
  
Line 61: Line 61:
 **Secure Connection **Secure Connection
 ** **
 +
 In order to have a secure connection, we followed the example discussed in [[https://​indjst.org/​articles/​combining-tcp-and-udp-for-secure-data-transfer|this paper]] that combines two communication protocols TCP and UDP, creating 5 layers of security for sending the command. These layers are: Encryption, Compression,​ Key generation, Browsing data and Combination of UDP and TCP In order to have a secure connection, we followed the example discussed in [[https://​indjst.org/​articles/​combining-tcp-and-udp-for-secure-data-transfer|this paper]] that combines two communication protocols TCP and UDP, creating 5 layers of security for sending the command. These layers are: Encryption, Compression,​ Key generation, Browsing data and Combination of UDP and TCP
  
Line 538: Line 539:
 **2. Video Capturing System **2. Video Capturing System
 ** **
 +
 +First of all, after we have a functional Linux Raspberry Pi image, we must make sure that we have the necessary environment,​ for this we install the following with the help of a terminal:
 +
 +<code C>
 +
 +$ sudo apt install python3.8
 +$ sudo apt-get -y install python3-pip
 +$ pip3 install opencv
 +$ pip3 install face_recognition
 +
 +</​code>​
 +
 +The software implementation on the Raspberry Pi was made in python and consists of two scripts.
 +
 +1. Face recognition
 +
 +In this script, the following is done: camera preview, face detection and calling the function to send the opening command to the ESP32.
 + 
 +
 +<code python>
 +
 +#​!/​usr/​bin/​python3
 +import face_recognition
 +import cv2
 +import numpy as np
 +import os
 +import glob
 +from transmisie import *
 +
 +
 +# Get a reference to webcam #0 (the default one)
 +video_capture = cv2.VideoCapture(0)
 +
 +#make array of sample pictures with encodings
 +known_face_encodings = []
 +known_face_names = []
 +dirname = os.path.dirname(__file__)
 +path = os.path.join(dirname,​ '​known_people/'​)
 +
 +#make an array of all the saved jpg files' paths
 +list_of_files = [f for f in glob.glob(path+'​*.jpg'​)]
 +#find number of known faces
 +number_files = len(list_of_files)
 +
 +names = list_of_files.copy()
 +
 +for i in range(number_files):​
 +    globals()['​image_{}'​.format(i)] = face_recognition.load_image_file(list_of_files[i])
 +    globals()['​image_encoding_{}'​.format(i)] = face_recognition.face_encodings(globals()['​image_{}'​.format(i)])[0]
 +    known_face_encodings.append(globals()['​image_encoding_{}'​.format(i)])
 +
 +    # Create array of known names
 +    names[i] = names[i].replace("​known_people/",​ ""​)  ​
 +    known_face_names.append(names[i])
 +
 +# Initialize some variables
 +face_locations = []
 +face_encodings = []
 +face_names = []
 +process_this_frame = True
 +
 +while True:
 +    # Grab a single frame of video
 +    ret, frame = video_capture.read()
 +
 +    # Resize frame of video to 1/4 size for faster face recognition processing
 +    small_frame = cv2.resize(frame,​ (0, 0), fx=0.25, fy=0.25)
 +
 +    # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
 +    rgb_small_frame = small_frame[:,​ :, ::-1]
 +
 +    # Only process every other frame of video to save time
 +    if process_this_frame:​
 +        # Find all the faces and face encodings in the current frame of video
 +        face_locations = face_recognition.face_locations(rgb_small_frame)
 +        face_encodings = face_recognition.face_encodings(rgb_small_frame,​ face_locations)
 +
 +        face_names = []
 +        for face_encoding in face_encodings:​
 +            # See if the face is a match for the known face(s)
 +            matches = face_recognition.compare_faces(known_face_encodings,​ face_encoding)
 +            name = "​Unknown"​
 +
 +            # # If a match was found in known_face_encodings,​ just use the first one.
 +            # if True in matches:
 +            #     ​first_match_index = matches.index(True)
 +            #     name = known_face_names[first_match_index]
 +
 +            # Or instead, use the known face with the smallest distance to the new face
 +            face_distances = face_recognition.face_distance(known_face_encodings,​ face_encoding)
 +            best_match_index = np.argmin(face_distances)
 +            if matches[best_match_index]:​
 +                name = known_face_names[best_match_index]
 +
 +            face_names.append(name)
 +
 +    process_this_frame = not process_this_frame
 +
 +
 +    # Display the results
 +    for (top, right, bottom, left), name in zip(face_locations,​ face_names):​
 +        # Scale back up face locations since the frame we detected in was scaled to 1/4 size
 +        top *= 4
 +        right *= 4
 +        bottom *= 4
 +        left *= 4
 +
 +        # Draw a box around the face
 +        cv2.rectangle(frame,​ (left, top), (right, bottom), (0, 0, 255), 2)
 +
 +        # Draw a label with a name below the face
 +        cv2.rectangle(frame,​ (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
 +        font = cv2.FONT_HERSHEY_DUPLEX
 +        cv2.putText(frame,​ name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
 +        if name != "​Unknown":​
 +            print("​Known face detected!"​)
 +            trimite_comanda()
 +
 +    # Display the resulting image
 +    cv2.imshow('​Video',​ frame)
 +
 +    # Hit '​q'​ on the keyboard to quit!
 +    if cv2.waitKey(1) & 0xFF == ord('​q'​):​
 +        break
 +
 +# Release handle to the webcam
 +video_capture.release()
 +cv2.destroyAllWindows()
 +
 +</​code>​
 +
 +2. The opening command
 +
 +When the door opening function is called in the facial recognition script, the 5 layers of security are applied and the command is sent to the ESP32.
 +
 +<code python>
 +
 +import socket
 +import random ​
 +import numpy as np
 +import math
 +import time
 +
 +# criptare cu cifrul Caesar
 +def encrypt(text,​s):​
 +    result = ""​
 +    for i in range(len(text)):​
 +        char = text[i]
 +        if (char.isupper()):​
 +            result+=chr((ord(char) + s-65) % 26 + 65)
 +        else:
 +            result+=chr((ord(char) + s - 97) % 26 + 97)
 +    return result
 +    ​
 +def obtine_cheie_TCP():​
 +
 +    HOST = '​192.168.43.5' ​ # Adresa IP server
 +    PORT = 80               # Port server
 +     
 +    C_cunoscut = 23
 +    S_cunoscut = 9
 +
 +    print('​Valoarea aleasa de client cunoscuta este :​%d'​%(C_cunoscut))
 +    print('​Valoarea aleasa de server cunoscuta este :​%d'​%(S_cunoscut))
 +
 +    C_secret = random.randint(3,​ 15)
 +
 +    # gets the generated key
 +    x_client = int(pow(S_cunoscut,​C_secret,​C_cunoscut)) ​
 +    x_client_byte=bytes([x_client])
 +
 +    print(x_client_byte)
 +    with socket.socket(socket.AF_INET,​ socket.SOCK_STREAM) as s:
 +        s.connect((HOST,​ PORT))
 +        s.sendall(x_client_byte)
 +        data = s.recv(1024) ​      
 +    # print('​S-a primit',​ data)
 +    x_server=int.from_bytes(data,​ "​big"​)
 +    k_secreta_client = int(pow(x_server,​C_secret,​C_cunoscut))
 +    print('​Cheia secreta pentru client este: %d'​%(k_secreta_client))
 +    ​
 +    return k_secreta_client
 +    ​
 +def generare_medie(x):​
 +    medie = []
 +    medie_com = []
 +    for i in x:
 +        if i < 0:
 +            medie.append(str(bin(i)[3:​]))
 +            aux = str(medie[len(medie) - 1])
 +            ​
 +            for k in range(1,​7-len(medie[len(medie) - 1])):
 +                if k==7-len(medie[len(medie) - 1])-1:
 +                    aux = str(1) + aux
 +                else:
 +                    aux = str(0) + aux
 +
 +            medie_com.append(aux)
 +        else:
 +            medie.append((str(bin(i))[2:​]))
 +            aux = str(medie[len(medie) - 1])
 +
 +            for k in range(1,​7-len(medie[len(medie) - 1])):
 +                aux = str(0) + aux
 +            medie_com.append(aux)
 +   # print(medie)
 +   # print(medie_com)
 +    string_medie=str(medie_com[0])+str(medie_com[1])+str(medie_com[2])+str(medie_com[3])
 +    return string_medie
 +    ​
 +def generare_cheie(k_secreta_client): ​  
 +    comanda='​deschide'​
 +    start_time_enc = time.time()
 +    string=encrypt(comanda,​k_secreta_client)
 +    print("​--- Timp criptare: %.4f seconds ---" % (time.time() - start_time_enc))
 +
 +    start_time_compresie = time.time()
 +    i=0
 +    # "​deschide"​ este scris in cod ascii
 +    valori_ascii=[]
 +    for fiecare in string:
 +        valori_ascii.append(ord(fiecare)-97)
 +        i=i+1
 +
 +   # print(f"​valori_ascii = {valori_ascii}"​)
 + 
 +    x = [] # stochez media 
 +    diff = [] # stochez diferenta
 +    even_nos = [num for num in range(len(valori_ascii)) if num % 2 == 0]
 +
 +    for l in even_nos:
 +        x.append(math.ceil(0.5*(valori_ascii[l]+valori_ascii[l+1])))
 +        diff.append(valori_ascii[l]-valori_ascii[l+1])
 +    ​
 +   # print(f"​medie = {x}")
 +   # print(f"​diff = {diff}"​)
 +
 +    diff_b = []
 +    aux = str()
 +    diff_b_com = []
 +
 +    # adug totul la forma dorita
 +    for i in diff: 
 +        if i < 0:
 +            diff_b.append(str(bin(i)[3:​]))
 +            aux = str(diff_b[len(diff_b) - 1])
 +
 +            for k in range(1,​7-len(diff_b[len(diff_b) - 1])):
 +                if k==7-len(diff_b[len(diff_b) - 1])-1:
 +                    aux = str(1) + aux
 +                else:
 +                    aux = str(0) + aux
 +
 +            diff_b_com.append(aux)
 +        else:
 +            diff_b.append((str(bin(i))[2:​]))
 +            aux = str(diff_b[len(diff_b) - 1])
 +
 +            for k in range(1,​7-len(diff_b[len(diff_b) - 1])):
 +                aux = str(0) + aux
 +            diff_b_com.append(aux)
 +    ​
 +    ​
 +   # print(diff_b)
 +   # print(diff_b_com)
 +    ​
 +    string_medie = generare_medie(x) # generez media corespunzator
 +    print("​--- Timp compresie: %.4f seconds ---" % (time.time() - start_time_compresie))
 + 
 +    start_time_gen_cheie = time.time()
 +    # declar chei pentru integrare in cheia mare si le procesez
 +    ak = (bin(1))[2:​]
 +    bk = (bin(7))[2:​]
 +
 +    for i in range(1,​6-len(ak)):​
 +        ak = str(0)+ak
 +
 +    for i in range(1,​6-len(bk)):​
 +        bk = str(0)+bk ​
 +
 +    key = ak+bk
 +    seg1 = key[:4]
 +    seg2 = key[4:8]
 +    seg3 = key[8:]
 +    key = str(diff_b_com[0])+seg1+str(diff_b_com[1])+seg2+str(diff_b_com[2])+seg3+str(diff_b_com[3])
 +    print("​--- Timp generare cheie: %.4f seconds ---" % (time.time() - start_time_gen_cheie))
 +    return key, string_medie # returnez key si media
 +
 +# Converitre lista in string
 +def listToString(s): ​    
 +    # initializez string gol
 +    str1 = "" ​    
 +    # parcurg stringul
 +    for ele in s: 
 +        str1 += ele     
 +    # returnez string  ​
 +    return str1 
 +
 +# realizez parcurgerea orizontala
 +def vertical(key,​string_medie):​
 +    array = []
 +    row1=[]
 +    row2=[]
 +    for i in range(len(key)):​
 +        if i%2 == 0:
 +            row1.append(key[i])
 +        else:
 +            row2.append(key[i])
 +    array.append(row1)
 +    array.append(row2)
 +    row_1 = listToString(row1)
 +    row_2 = listToString(row2)
 +    string = str(str(row_1)+str(row_2)+str(string_medie))
 +    return string
 +    ​
 +def UDP_trimite_cheie(string):​
 +    UDP_IP = '​192.168.43.5'​
 +    UDP_PORT = 1234
 +    MESSAGE = string
 +
 +   # print("​UDP ​ IP: %s" % UDP_IP)
 +   # print("​UDP ​ port: %s" % UDP_PORT)
 +   # print("​Mesaj:​ %s" % MESSAGE)
 +
 +    sock = socket.socket(socket.AF_INET,​ # Internet
 +                         ​socket.SOCK_DGRAM) # UDP
 +    sock.sendto(MESSAGE.encode(),​ (UDP_IP, UDP_PORT))
 +
 +def trimite_comanda():​
 +    start_time_TCP = time.time()
 +    k_secreta_client = obtine_cheie_TCP()
 +    print("​--- Timp TCP: %.4f seconds ---" % (time.time() - start_time_TCP))
 +    key, string_medie = generare_cheie(k_secreta_client)
 +    start_time_parcurgere = time.time()
 +    string = vertical(key,​ string_medie)
 +    print("​--- Timp parcurgere: %.4f seconds ---" % (time.time() - start_time_parcurgere))
 +    start_time_UDP = time.time()
 +    UDP_trimite_cheie(string)
 +    print("​--- Timp UDP: %.4f seconds ---" % (time.time() - start_time_UDP))
 +
 +if __name__ == '​__main__':​
 +    print("​Main"​)
 +
 +
 +</​code>​
 +
 +====== Results obtained ======
 +
 +**1. Door Opening System
 +**
 +
 +{{ :​iothings:​proiecte:​2022:​boncu_rez_esp32.png | ESP32
 +Results System}}
 +
 +
 +**2. Video Capturing System
 +**
 +
 +{{ :​iothings:​proiecte:​2022:​boncu_rez_rpi.jpeg?​500x400 | RPI
 +Results System}}
 +
 +
 +
 +====== Demo Video ======
  
  
iothings/proiecte/2022/dor_bell.1674160471.txt.gz · Last modified: 2023/01/19 22:34 by adriana.boncu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0