Real-Time system that allow to pass only authorized/invited people, using Face-Recognition or NFC cards.
Story
The principle of operation:
- Person approaches to the intercom
- Looks at the camera
- The system compare his face with authorized people
- If it finds it, then the door opens and a person can enter
- There is also another way to pass;
- The person with the pass card place it to the RFID location and the door opens if it finds the code of this card in its database
*This project is still in progress. I hope the final version will be more beautiful.
**Gonna get rid of RPi 1 and NFC in favor of fingerprint scanner connected to RPi3. Updates are coming…
Preparation
Relay connection
- Connect relay to RPI 3. In my case I used GPIO12 pin for data, 5v for power and you can choose any GND.
You can test the relay with shell script, just create a simple sh script:
nano open.sh
chmod +x open.sh
sh open.sh
Paste the code below and run it.
Script code:
#!/bin/bash
echo 12 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio12/direction
echo 0 > /sys/class/gpio/gpio12/value
ping -c 1 localhost
echo 12 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio12/direction
echo 1 > /sys/class/gpio/gpio12/value
Camera connection
- Connect camera module and enable it in raspi-config:
Open the raspi-config tool from the Terminal:
sudo raspi-config
Select Enable camera and hit Enter
, then go to Finish and you’ll be prompted to reboot.
To test that the system is installed and working, try the following command:
raspistill -v -o test.jpg
LED Connection
Connect your LED to any GPIO you want + GND. In my case I used GPIO16 for the green LED and GPIO26 for red. When you are done, test it:
Create 2 simple python scripts for the green and red LEDs with the following content:
- Green led.py
from gpiozero import LED
from time import sleep
led = LED(16)
while True:
led.on()
sleep(3)
led.off()
led.cleanup()
- Red led2.py
from gpiozero import LED
from time import sleep
led = LED(26)
while True:
led.on()
sleep(3)
led.off()
led.cleanup()
And then test it. If the LEDs are glowing, then everything works good.
python led.py
python led2.py
Face Recognition Script
Install this module from pypi using pip3
(or pip2
for Python 2):
pip3 install face_recognition
Create directory “pic” and “unknown” in Documents for example and place there some face pics of people you know. In my case it’s (“/home/pi/Documents/pic/”) and (“/home/pi/Documents/unknown/”).
Create a python script with following code:
import face_recognition
import picamera
import numpy as np
import os
camera = picamera.PiCamera()
camera.resolution = (320, 240)
output = np.empty((240, 320, 3), dtype=np.uint8)
print("Loading known face image(s)")
ep_image = face_recognition.load_image_file("/home/pi/Documents/pic/ep.jpg")
ep_face_encoding = face_recognition.face_encodings(ep_image)[0]
vl_image = face_recognition.load_image_file("/home/pi/Documents/pic/vl.jpg")
vl_face_encoding = face_recognition.face_encodings(vl_image)[0]
face_locations = []
face_encodings = []
while True:
print("Capturing image.")
camera.capture(output, format="rgb")
face_locations = face_recognition.face_locations(output)
print("Found {} faces in image.".format(len(face_locations)))
face_encodings = face_recognition.face_encodings(output, face_locations)
for face_encoding in face_encodings:
match = face_recognition.compare_faces([ep_face_encoding,vl_face_encoding], face_encoding)
name = "<Unknown Person>"
os.system("python /home/pi/led2.py &")
import time
date_string = time.strftime("%Y-%m-%d-%H:%M:%S")
camera.capture("/home/pi/Documents/unknown/image-" + date_string + ".jpg")
Test it.
python facerec.py
RFID Connection
Pins:
We need this to connect our RFID module to Raspberry Pi 1.
- Preparation:
$ sudo nano /etc/modprobe.d/raspi-blacklist.conf
#blacklist spi-bcm2708
$ sudo apt-get install python-dev
$ git clone https://github.com/lthiery/SPI-Py.git
$ cd SPI-Py
$ sudo python setup.py install
- When the script finds authorized card, it opens the user picture on the remote RPI 3 (runs LED scripts), then it opens the door.
import MFRC522
import signal
import os
continue_reading = True
MIFAREReader = MFRC522.MFRC522()
cardA = [46,44,187,26,163]
cardB = [176,203,130,124,133]
cardC = [20,38,121,207,132]
def end_read(signal, frame):
global continue_reading
continue_reading = False
print "Ctrl+C captured, ending read."
MIFAREReader.GPIO_CLEEN()
signal.signal(signal.SIGINT, end_read)
while continue_reading:
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
if status == MIFAREReader.MI_OK:
print "Card detected"
(status,backData) = MIFAREReader.MFRC522_Anticoll()
if status == MIFAREReader.MI_OK:
print "Card read UID: "+str(backData[0])+","+str(backData[1])+","+str(backData[2])+","+str(backData[3])+","+str(backData[4])
if backData == cardA:
print "Evghenii"
os.system("sshpass -p *password* ssh [email protected] fbi -T 1 -d /dev/fb1 -noverbose /home/pi/Documents/pic/ep.jpg")
os.system("sshpass -p *password* ssh [email protected] /home/pi/Documents/open.sh 2>/dev/null")
# os.system("sshpass -p *password* ssh [email protected] sleep 2")
os.system("sshpass -p *password* ssh [email protected] killall fbi")
elif backData == cardB:
print "Vlad"
os.system("sshpass -p *password* ssh [email protected] fbi -T 1 -d /dev/fb1 -noverbose /home/pi/Documents/pic/vl.jpg")
os.system("sshpass -p *password* ssh [email protected] /home/pi/Documents/open.sh 2>/dev/null")
# os.system("sshpass -p *password* ssh [email protected] sleep 2")
os.system("sshpass -p *password* ssh [email protected] killall fbi")
elif backData == cardC:
print "is Card C"
else:
print "wrong Card"
os.system("sshpass -p *password* ssh [email protected] /home/pi/led2.py 2>/dev/null")
- Using this example:
$ git clone https://github.com/rasplay/MFRC522-python.git
$ cd MFRC522-python
$ sudo python read.py
Button + Telegram
#!/usr/bin/python
import RPi.GPIO as GPIO
from subprocess import call
from datetime import datetime
import time
import os
shutdownPin = 29
shutdownMinSeconds = 5
# button debounce time in seconds
debounceSeconds = 0.01
GPIO.setmode(GPIO.BOARD)
GPIO.setup(shutdownPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
buttonPressedTime = None
def buttonStateChanged(pin):
global buttonPressedTime
if not (GPIO.input(pin)):
# button is down
if buttonPressedTime is None:
buttonPressedTime = datetime.now()
else:
# button is up
if buttonPressedTime is not None:
elapsed = (datetime.now() - buttonPressedTime).total_seconds()
buttonPressedTime = None
if elapsed >= shutdownMinSeconds:
call(['shutdown', '-r', 'now'], shell=True)
elif elapsed >= debounceSeconds:
os.system("bash /home/pi/timed.sh")
# subscribe to button presses
GPIO.add_event_detect(shutdownPin, GPIO.BOTH, callback=buttonStateChanged)
while True:
# sleep to reduce unnecessary CPU usage
time.sleep(5)
action.sh
#!/bin/bash
sshpass -p password ssh epogonii@ipadress -p1337 notify-send -i /usr/share/icons/gnome/32x32/actions/ring2.png Smart-Intercom Guest_at_the_door
DISPLAY=:0.0 XAUTHORITY=/home/pi/.Xauthority /usr/bin/feh --hide-pointer -x -q -D 5 -B black -F /home/pi/doorway.png &
sh /home/pi/Documents/open.sh > log.out 2> /dev/null
DISPLAY=:0.0 XAUTHORITY=/home/pi/.Xauthority xdotool key "x"
sh /home/pi/tgphoto.sh FaceRec /var/www/html/last.jpg > log.out 2> /dev/null
Added pushbutton to Smart Intercom. It sends you last photo to telegram bot and sends notification to Ubuntu Desktop PC.
In order to disable entrance in specific hours via push-button, i made the following bash script:
#!/bin/bash
H=$(date +%H)
if (( 7 <= 10#$H && 10#$H < 19 )); then
echo between 7AM and 19PM
sh /home/pi/action.sh
else
echo error
sh /home/pi/error.sh
fi
action.sh – opens the door between 7 am and 19 pm
error.sh – displays restriction image between 19 pm and 7 am error.sh script
#!/bin/bash
DISPLAY=:0.0 XAUTHORITY=/home/pi/.Xauthority /usr/bin/feh --hide-pointer -x -q -D 5 -B black -F /home/pi/error.png &
ping -c 4 localhost 2>/dev/null
DISPLAY=:0.0 XAUTHORITY=/home/pi/.Xauthority xdotool key "x"
P.S to run this script you will need to install xdotool
sudo apt install xdotool