Start Writing Python Program
A Python program is just a text file.
Use your favorite text editor to create an empty file “main.py” in the Program Folder.
I personally use Notepad++ (link below) but there are so many options you can choose from. https://notepad-plus-plus.org/downloads/
The Program Structure
Program in high-level can be devided into 5 parts:
- Initial Preparation & Definition
- Function Blocks
- Final Preparation
- Main Loop
- Program Shutdown
The Program Mode
It is also worth noting that I used the “mode” concept to make the program behave differently using the same set of buttons.
- Detecting – Default mode which device is looking for a face
- Recording – Capturing faces to update the face recognition model
- Predicting – Assessing if the captured face already has a name
- Naming – When a user is entering a new name
- Saving – Saving a new name and the face recognition model
- Updating – Updating the face recognition model with the existing name
- Ending – While in the program shutdown sequence
We will now start writing a program in the empty “main.py” file.
Initial Preparation & Definition
The first part of the program has couple of user configurations and script to make LCD screen working.
#!/usr/bin/env python3.7
#####################################################################
## Author: Taka@FunIncomplete
## Updated: Apr-2020
## Visit: www.FunIncomplete.com
#####################################################################
### User configurations
Reset = False
endProgramAfter = 10
### Preparing LCD screen
import I2C_LCD_driver
lcd = I2C_LCD_driver.lcd()
### Importing other libraries
lcd.lcd_display_string('Importing Libs..'.ljust(16), 1, 0)
print('[INFO] Importing Libs...')
Line 10: Flag “False” to delete database and custom trained model
Line 11: Device shutdown countdown from 10
Line 14 & 15: Prepare LCD screen driver
Line 18: Displaying text “Importing Libs..” on the LCD screen
The next part imports required libraries for this program.
#Importing Libraries
import cv2
import sqlite3
import RPi.GPIO as GPIO
from numpy import array as np_array
from subprocess import call
from os import getcwd
from os import remove
from time import sleep
from pathlib import Path
from datetime import date, datetime
Line 2: OpenCV for face detection & recognition
Line 3: SQLite for database
Line 4: GPIO control to detect button input
Line 5: Numpy array to pass image labels to OpenCV
Line 6: Subprocess to call Pico to speech
Line 7: “getcwd” command to get programme location
Line 8: “remove” command to delete file
Line 9: “sleep” command to pause program
Line 10: “Path” command to check file
Line 11: “datetime” command to show date & time on LCD screen
Prepare global variables.
### Initialising Variables
lcd.lcd_display_string('Init Variables'.ljust(16), 1, 0)
print('[INFO] Init Variables...')
ScriptLocation = getcwd()
newTrainer = True
newDB = True
NameCursorBlink = True
endProgramCount = 0
mode = 'Detecting'
trainingImg = []
predictedIDset = set()
predictedID = -1
predictedName = '...'
name = ''
msg1 = ''
msg2 = ''
NewSpeech = ''
OldSpeech = ''
indicator = '>'
alphabet_index = 1
alphabet = ['','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
WeekDay = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]
Line 2: Show “Init Variables” on LCD
Line 5: Get program location
Line 10: The program start from “Detecting” mode
Line 24: Prepare a letter array for entring name
Line 25: prepare weekday array to convert week number to name
Then delete 3 files that automatically created by program if “Reset” flag is “True”.
### Reset program
if Reset:
lcd.lcd_display_string('Resetting Data'.ljust(16), 1, 0)
if Path(ScriptLocation + '/face_recogniser.db').is_file():
remove(ScriptLocation + '/face_recogniser.db')
if Path(ScriptLocation + '/face_recogniser.yml').is_file():
remove(ScriptLocation + '/face_recogniser.yml')
if Path(ScriptLocation + '/voice.wav').is_file():
remove(ScriptLocation + '/voice.wav')
Line 2: If Reset flag is True
Line 3: Show “Resetting Data” on LCD
Line 4 & 5: Delete database if exist
Line 6 & 7: Delete trained face recognition model if exist
Line 8 & 9: Delete temporary voice file if exist
Prepare buttons to be detected.
### Initialising buttons
lcd.lcd_display_string('Init Buttons...'.ljust(16), 1, 0)
print('[INFO] Init Buttons...')
Button_1 = 17
Button_2 = 23
Button_3 = 24
Button_4 = 22
Button_5 = 27
GPIO.setmode(GPIO.BCM)
GPIO.setup(Button_1, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(Button_2, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(Button_3, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(Button_4, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(Button_5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
Line 2: Show “Init Buttons…” on LCD
Line 4 – 8: Name buttons attached to GPIO
Line 10: Use GPIO numbering instead of BOARD numbering
Line 11-15: Setup GPIO pins to detect when it is connected to ground pin.
Prepare the general face detector.
### Initialising face detector & recogniser
lcd.lcd_display_string('Init Detector'.ljust(16), 1, 0)
print('[INFO] Init Detector...')
face_cascade = cv2.CascadeClassifier(ScriptLocation + '/haarcascade_frontalface_default.xml')
Line 2: Show “Init Detector” on LCD
Line 4: Tell OpenCV to use “haarcascade_frontalface_default.xml” to classify image
Prepare the database to record names.
### Initialising SQLite database
lcd.lcd_display_string('Preparing SQLite'.ljust(16), 1, 0)
print('[INFO] Preparing SQLite...')
if Path(ScriptLocation + '/face_recogniser.db').is_file():
newDB = False
conn = sqlite3.connect(ScriptLocation + '/face_recogniser.db')
c = conn.cursor()
if newDB:
sql = '''CREATE TABLE 'people' ( 'name' TEXT, 'date_created' TEXT )'''
c.execute(sql)
Line 2: Show “Preparing SQLite” on LCD
Line 5 & 6: Check if the database exists and flag accordingly
Line 8 & 9: Connect/Create database
Line 11 – 13: Prepare the database table if it is a new database
Prepare face recogniser.
### Initialising face recogniser
lcd.lcd_display_string('Init Recogniser'.ljust(16), 1, 0)
print('[INFO] Init Recogniser...')
recogniser = cv2.face.LBPHFaceRecognizer_create()
if Path(ScriptLocation + '/face_recogniser.yml').is_file():
recogniser.read(ScriptLocation + '/face_recogniser.yml')
newTrainer = False
Line 2: Show “Init Recogniser” on LCD
Line 4: Initialise face recogniser
Line 5-7: Read face trained data if exist, and set the flag accordingly
What’s Next?
The Initial Preparation is done. The next part “Function Blocks” will be continued in the next post.