Asim Arshad
Published

Facial Detection Security System

A system which upon detecting motion turns on the camera and looks for intruders.

IntermediateFull instructions provided3 hours1,011
Facial Detection Security System

Things used in this project

Hardware components

Raspberry Pi 3 Model B
Raspberry Pi 3 Model B
×1
PIR Motion Sensor (generic)
PIR Motion Sensor (generic)
×1
LED (generic)
LED (generic)
×1
Buzzer
Buzzer
×1
Webcam, Logitech® HD Pro
Webcam, Logitech® HD Pro
×1

Software apps and online services

Raspbian
Raspberry Pi Raspbian

Story

Read more

Schematics

Motion Sensor to raspberry pi

Connect the motion sensor to the raspberry pi as per the image

Connect Buzzer and LED as per the image.

Make sure that the long ends of both are connected to GPIO pins and short ends to the ground

Code

Security.py

Python
Copy and paste the ResidentDetails and Trainner.yml file in the raspberry pi and run this code in it.
NOTE: Make sure it's all in the same working directory.
import tkinter as tk ##importing all the libraries needed for the project
from tkinter import *
import cv2
import csv
import os
import numpy as np
from PIL import Image,ImageTk
import pandas as pd
import datetime
import time
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
import RPi.GPIO as GPIO
from time import sleep
##initiating the LED Buzzer and motion sensor
GPIO.setwarnings(False) 
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.IN)
buzzer = 13
GPIO.setup(buzzer, GPIO.OUT)
LED = 15
GPIO.setup(LED, GPIO.OUT)
GPIO.output(buzzer, False)
GPIO.output(LED, False)
## Function to send the mail of the intruder.
def SendMail(ImgFileName):
    img_data = open(ImgFileName, 'rb').read()
    msg = MIMEMultipart()
    msg['Subject'] = 'Intruder Detected'
    msg['From'] = '[email protected]'
    msg['To'] = '[email protected]'

    text = MIMEText("test")
    msg.attach(text)
    image = MIMEImage(img_data, name=os.path.basename(ImgFileName))
    msg.attach(image)

    s = smtplib.SMTP('smtp.gmail.com',587)
    s.ehlo()
    s.starttls()
    s.ehlo()
    s.login('your_email', 'your_password')
    s.sendmail('your_email', 'reciever_email', msg.as_string())
    s.quit()


import sys
def Trackimages():
    now = time.time()  ###For calculate seconds of video
    future = now + 15  
    recognizer = cv2.face.LBPHFaceRecognizer_create() ##using open cv's face module
    recognizer.read("Trainner.yml")
    haarcascade = "haarcascade_frontalface_default.xml" 
    faceCascade = cv2.CascadeClassifier(haarcascade)
    df =pd.read_csv("ResidentDetails.csv") ## reading the csv files which has the details of the residents
    cam = cv2.VideoCapture(0) ##turning on the camera
    font = cv2.FONT_HERSHEY_SIMPLEX
    while True: 
        ret, im = cam.read()
        gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) ##converting feed to grayscale
        
        faces = faceCascade.detectMultiScale(gray, 1.2, 5)
        for (x, y, w, h) in faces:
            Id, conf = recognizer.predict(gray[y:y+h, x:x+w]) ##predicting the similarity
            print(conf)
            if (conf<90):
                aa = df.loc[df['Id']==Id]['Name'].values ##getting the name and ID for that specific resident. 
                tt = str(Id)+"-"+aa
                cv2.rectangle(im, (x, y), (x + w, y + h), (0, 260, 255), 7)
                cv2.putText(im,str(tt),(x+h,y),font,1,(0,25,255,),4) ##displaying name+ID on the screen and putting a rectangle around the face
            else:
                Id= 'Unknown' ###if person is not known give them "Unknown ID"
                tt = str(Id)
                print(Id)
                cv2.rectangle(im, (x, y), (x + w, y + h), (0, 25, 255), 7)
                cv2.putText(im,str(tt),(x+h,y),font,1,(0,25,255),4)
                cv2.imwrite("UnknownPerson.jpg",im) ##Capture their image
                SendMail("UnknownPerson.jpg") ##sending the image in the email
                GPIO.output(LED, True) ##turning on LED and Buzzer
                GPIO.output(buzzer, True)
                time.sleep(3)
                GPIO.output(LED, False) ##turning them off after 3 seconds
                GPIO.output(buzzer, False)
                time.sleep(1)
        if time.time()>future:  ##braeking the loop when time reaches the value of future variable i.e.15
            break
        cv2.imshow('Frame',im)  ##showing the camera feed to screen
        key = cv2.waitKey(2) & 0xff
        if key == ord('q'): ##break if pressed q
            break
    cam.release()
    cv2.destroyAllWindows()
while True:
    i = GPIO.input(11) ##assinging i to value recieved by motion sensor
    if i == 0: ##if no motion print the following
        print("No motion detcted")
        sleep(0.3)
    elif i == 1: ## if motion detected run the trackimage function
        print("Motion detected")
        Trackimages()
        
 

GUI.py

Python
This is a GUI in which there are two functions. One to capture 100 images of the person you don't want to recognize as an intruder and the other to train the model for that person. You'll be giving every resident a unique ID + name in the GUI. Once this is done, just update the resident details and Trainner.yml file in the raspberry pi.
import tkinter as tk
from tkinter import *
import cv2
import csv
import os
import numpy as np
from PIL import Image,ImageTk
import pandas as pd
import datetime
import time
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

# #####Window is our Main frame of system
window = tk.Tk()
window.title("Facial Detection Security System")

window.geometry('1280x720')
window.configure(background='khaki')

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        pass
    try:
        import unicodedata
        unicodedata.numeric(s)
        return True
    except(TypeError, ValueError):
        pass
    return False


###For taking images for datasets
def take_img():
    ID = IDtxt.get()
    name = Nametxt.get()
    if(is_number(ID)and name.isalpha()):
            cam = cv2.VideoCapture(0)
            detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
            sampleNum = 0
            while (sampleNum<=100): #capture 100 images
                ret, img = cam.read()
                gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
                faces = detector.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)
                    # incrementing sample number
                    sampleNum = sampleNum + 1
                    # saving the captured face in the dataset folder
                    cv2.imwrite("TrainingImages\ " + name + "." + ID + '.' + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w])
                    cv2.imshow('frame', img)
                # wait for 100 miliseconds
                if cv2.waitKey(100) & 0xFF == ord('q'):
                    break
            cam.release()
            cv2.destroyAllWindows()
            res = "Images Saved for: "+ name
            ts = time.time()
            row = [ID, name]
            with open('ResidentDetails\ResidentDetails.csv', 'a+') as csvFile:
                writer = csv.writer(csvFile, delimiter=',')
                writer.writerow(row)
                csvFile.close()

            message2.configure(text = res)

###For train the model
def TrainImages():
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    faces, Id = getImagesAndLabels("TrainingImages")
    recognizer.train(faces, np.array(Id))
    recognizer.save("TrainingImageLabel\Trainner.yml")
    res = "Images Trained. \nYou can now transfer to raspberry pi"
    message2.configure(text = res)

def getImagesAndLabels(path):
    imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
    # create empth face list
    faceSamples = []
    # create empty ID list
    Ids = []
    detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
    # now looping through all the image paths and loading the Ids and the images
    for imagePath in imagePaths:
        # loading the image and converting it to gray scale
        pilImage = Image.open(imagePath).convert('L')
        # Now we are converting the PIL image into numpy array
        imageNp = np.array(pilImage, 'uint8')
        # getting the Id from the image

        Id = int(os.path.split(imagePath)[-1].split(".")[1])
        # extract the face from the training image sample
        faces = detector.detectMultiScale(imageNp)
        # If a face is there then append that in the list as well as Id of it
        for (x, y, w, h) in faces:
            faceSamples.append(imageNp[y:y + h, x:x + w])
            Ids.append(Id)
    return faceSamples, Ids

# creating GUI
window.grid_rowconfigure(0, weight=1) 
window.grid_columnconfigure(0, weight=1)

message = tk.Label(window, text="Facial Detection Security System", bg = "lavender", fg = "dark slate gray", width = 38,height=3,font=('Comic Sans',24))
message.place(x= 250, y=18)
message2 = tk.Label(window, text="", bg = "lavender", fg = "dark slate gray", width = 38,height=2,font=('Comic Sans',24))
message2.place(x= 250, y=550)
IDlabel = tk.Label(window, text="Enter ID", width=20, height=2, fg="black", bg="deepskyblue2", font=('Comic Sans', 15, ' bold '))
IDlabel.place(x=200, y=200)

def testVal(inStr,acttyp):
    if acttyp == '1': #insert
        if not inStr.isdigit():
            return False
    return True

IDtxt = tk.Entry(window, validate="key", width=20, bg="floral white", fg="red", font=('times', 25, ' bold '))
IDtxt['validatecommand'] = (IDtxt.register(testVal),'%P','%d')
IDtxt.place(x=550, y=210)

Namelabel = tk.Label(window, text="Enter Name", width=20, fg="black", bg="deepskyblue2", height=2, font=('Comic Sans', 15, ' bold '))
Namelabel.place(x=200, y=300)

Nametxt = tk.Entry(window, width=20, bg="floral white", fg="red", font=('times', 25, ' bold '))
Nametxt.place(x=550, y=310)

takeImg = tk.Button(window, text="Take Images",command=take_img,fg="black"  ,bg="Floral white"  ,width=20  ,height=3,font=('Comic Sans', 15, ' bold '))
takeImg.place(x=90, y=450)

trainImg = tk.Button(window, text="Train Images",command=TrainImages,fg="black"  ,bg="Floral white"  ,width=20  ,height=3,font=('Comic Sans', 15, ' bold '))
trainImg.place(x=550, y=450)

Quit = tk.Button(window, text="Quit",command=window.destroy,fg="black"  ,bg="Floral white"  ,width=20  ,height=3,font=('Comic Sans', 15, ' bold '))
Quit.place(x=990, y=450)
window.mainloop()

Credits

Asim Arshad
1 project • 0 followers

Comments