Mohamed Ali Bedair
Published © Apache-2.0

Smart Lock using Face Recognition

This project presents a Smart Lock that uses ML to detect Authorized faces. This ML Model runs on the Edge with no need for backend server.

IntermediateShowcase (no instructions)Over 1 day138
Smart Lock using Face Recognition

Things used in this project

Hardware components

RT-Thread Vision Board
×1
DC Lock
×1

Software apps and online services

RT-Thread IoT OS
RT-Thread IoT OS
Edge Impulse Studio
Edge Impulse Studio
OpenMV

Story

Read more

Schematics

System Block Diagram

Code

Machine Learning Inferencing

MicroPython
This code will run on the Vision Board and will be used Recognize the valid Face
"""
    Project  Name : Smart Lock
    Auther : Mohamed Bedair
    Description : This project recognize valid faces and open DC Lock when detected
   
"""

import sensor, image, time, os, tf, uos, gc
from machine import LED
DC_LOCK = LED("DC_LOCK")

sensor.reset()                         # Reset and initialize the sensor.
sensor.set_pixformat(sensor.RGB565)    # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA)      # Set frame size to QVGA (320x240)
sensor.set_windowing((240, 240))       # Set 240x240 window.
sensor.skip_frames(time=2000)          # Let the camera adjust.

net = None
labels = None

try:
    # load the model, alloc the model file on the heap if we have at least 64K free after loading
    net = tf.load("trained.tflite", load_to_fb=uos.stat('trained.tflite')[6] > (gc.mem_free() - (64*1024)))
except Exception as e:
    print(e)
    raise Exception('Failed to load "trained.tflite", did you copy the .tflite and labels.txt file onto the mass-storage device? (' + str(e) + ')')

try:
    labels = [line.rstrip('\n') for line in open("labels.txt")]
except Exception as e:
    raise Exception('Failed to load "labels.txt", did you copy the .tflite and labels.txt file onto the mass-storage device? (' + str(e) + ')')

clock = time.clock()
while(True):
    clock.tick()

    img = sensor.snapshot()

    # default settings just do one detection... change them to search the image...
    for obj in net.classify(img, min_scale=1.0, scale_mul=0.8, x_overlap=0.5, y_overlap=0.5):
        print("**********\nPredictions at [x=%d,y=%d,w=%d,h=%d]" % obj.rect())
        img.draw_rectangle(obj.rect())
        # This combines the labels and confidence values into a list of tuples
        predictions_list = list(zip(labels, obj.output()))

        for i in range(len(predictions_list)):
            print("%s = %f" % (predictions_list[i][0], predictions_list[i][1]))

    #print(clock.fps(), "fps")
    if predictions_list[1][1] > 0.6:
        print("Valid Face Detected")
        DC_LOCK.on()
        time.sleep_ms(5000)
        DC_LOCK.off()

Build Dataset

Python
This part was intended to run on a PC , to capture images that will form part of the training set (Hundreds of images)
import cv2 as cv
import time
import os

# Image directory
Dataset_Dir = r'D:\workspace\Contests\RT-Thread Design Contest\Dataset'

counter = 0

face_classifier = cv.CascadeClassifier(
    cv.data.haarcascades + "haarcascade_frontalface_default.xml"
)


def Detect_And_Save_Faces(frame):
    global counter
    gray_image = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    faces = face_classifier.detectMultiScale(gray_image, 1.1, 5, minSize=(40, 40))
    for (x, y, w, h) in faces:
        crop_img = frame[x-30:y + h + 40 + 20, y-50:x + w + 20]
        filename = "Img_" + str(counter) + ".jpg"
        cv.imwrite(os.path.join(Dataset_Dir , filename), crop_img)
        counter += 1

        cv.rectangle(frame, (x-30, y-50), (x + w + 20 , y + h + 40), (0, 255, 0), 4)

# Create video captuer instance and configure the camera options 
cap = cv.VideoCapture(cv.CAP_DSHOW)
cap.set(cv.CAP_PROP_FRAME_WIDTH, 500)
cap.set(cv.CAP_PROP_FRAME_HEIGHT, 500)
cap.set(cv.CAP_PROP_FPS, 60)


while True:
    ret, frame = cap.read()

    if not ret:
        print("Invaild Input")
        break
    
    Detect_And_Save_Faces(frame) 

    cv.imshow("Window", frame)

    time.sleep(0.5)

    key = cv.waitKey(1)
    if key == ord('q'):
        break


cap.release()
cv.destroyAllWindows()

Define the Pin that Connects the DC_Lock

C/C++
We define the pin and port number for the pin that controls the DC_Lock P001 in file(mpconfigboard.h)
#define MICROPY_HW_LED1             (0x0A07)    // R
#define MICROPY_HW_LED2             (0x0106)    // G
#define MICROPY_HW_LED3             (0x0102)    // B
#define MICROPY_HW_DC_LOCK          (0x0001)

Add DC_Lock pin to the list of pins we have

C/C++
static const machine_pin_obj_t g_bsp_prv_leds[] =
{
    {.base = {&pyb_led_type}, .name = "LED_BLUE", .pin = MICROPY_HW_LED1, .pin_isr_cb = NULL },
    {.base = {&pyb_led_type}, .name = "LED_GREEN", .pin = MICROPY_HW_LED2, .pin_isr_cb = NULL },
    {.base = {&pyb_led_type}, .name = "LED_RED", .pin = MICROPY_HW_LED3, .pin_isr_cb = NULL },
    {.base = {&pyb_led_type}, .name = "DC_LOCK", .pin = MICROPY_HW_DC_LOCK, .pin_isr_cb = NULL },

};

Credits

Mohamed Ali Bedair

Mohamed Ali Bedair

6 projects • 4 followers
Engineer/Maker

Comments