FaceCore - Raspberry Pi AI Face Recognition Access System

by ArlanArmanuly in Design > Software

28 Views, 0 Favorites, 0 Comments

FaceCore - Raspberry Pi AI Face Recognition Access System

meow1.png

FaceCore is a prototype access-control system that uses artificial intelligence to analyse a person standing in front of a camera. The system can distinguish between an acceptable face, glasses, an invalid face position and a possible picture attack.

If the face is valid, it proceeds to log in, or to a registration of the user.

The project combines a Raspberry Pi, a camera, a YOLO object-detection model, distance sensing, status indicators, a display and a custom laser-cut wooden enclosure. A web dashboard is also used to display the camera result, system status and access logs.

This Instructable explains the complete process, from collecting data and training the AI model to wiring the hardware and assembling the final enclosure.

Supplies

Снимок экрана 2026-06-18 120849.png

Electronic components

  1. Raspberry Pi
  2. Raspberry Pi power supply
  3. Camera or USB webcam
  4. 16x2 character LCD
  5. Ultrasonic distance sensor
  6. Push buttons
  7. Status LEDs
  8. Passive buzzer
  9. Breadboard or GPIO extension board
  10. Wires

Enclosure materials

  1. 4 mm plywood
  2. Tape
  3. Screws, glue or other mounting materials
  4. Cable ties where necessary

Software

  1. Python
  2. Ultralytics YOLO
  3. Roboflow
  4. OpenCV
  5. Gradio
  6. PostgreSQL
  7. Docker
  8. Inkscape
  9. Boxes.py
  10. Visual Studio Code
  11. Git and GitHub

Tools

  1. Laser cutter
  2. Computer for model training( can be done via roboflow with a subscription)
  3. Soldering equipment(optional)
  4. Measuring tools

Total cost: ~180-200€

Plan the System

Before building FaceCore, I divided the system into the following parts:

  1. Distance and presence detection
  2. Camera image capture
  3. YOLO image verification
  4. Face embedding extraction
  5. User registration and identity matching
  6. Access decision
  7. Physical feedback
  8. Web dashboard
  9. Database logging


The ultrasonic sensor first measures whether someone is standing in front of the device. The system becomes active when the measured distance is 90 cm or less.

After activation, and further action, the camera captures an image. The image is first processed by the custom YOLO model, which can detect four classes:

  1. access
  2. glasses
  3. no_access
  4. picture_attack


YOLO is not used to determine the identity of the person. It acts as a verification and filtering stage before face recognition.

Identity recognition is only started when:

  1. YOLO detects the access class
  2. the YOLO confidence is above the required threshold
  3. no picture attack is detected
  4. no invalid face condition is detected
  5. no glasses condition is detected

When these conditions are satisfied, the face-recognition module extracts a face embedding from the image. This embedding is compared with the embeddings of registered users stored in the PostgreSQL database.

If the closest matching embedding is within the accepted distance threshold, the system recognises the person and grants access. Otherwise, the person is treated as a guest and access is denied.

The final result is displayed through the LCD, RGB LED, buzzer and Gradio dashboard. The decision event is also logged.



Collect and Annotate the Dataset

WhatsApp Image 2026-06-18 at 01.34.49.jpeg

The AI model requires labelled images before it can recognise the different situations.

I recorded short videos and extracted images showing:

  1. A normal visible face (access)
  2. A face wearing glasses (glasses)
  3. Invalid positions, such as closed eyes, covered/closed eyes or an extreme side angle (no_access)
  4. A face displayed on a phone (picture_attack)

The images were uploaded to Roboflow and labelled using bounding boxes. Every bounding box was assigned to one of the four project classes.


It is vital to collect photos of different people, in various environment, lighting, angles..


The dataset was divided into training, validation and test sets at a 80/10/10 proportion. Augmentations were used carefully to add variation. A total of 700 images were collected, 1700 including augmentation.

Train the YOLO Model

fvdffdfdfd.png

The model was trained using Ultralytics YOLO26. A nano-sized model was selected because the final system has to run on limited hardware.

The main training settings were:

  1. Image size: 960 pixels
  2. Model size: nano
  3. Type: object detection
  4. Training device: NVIDIA GPU

Example training command:

from ultralytics import YOLO

model = YOLO("yolo_model.pt")

model.train(
data="data.yaml",
epochs=100,
imgsz=960,
device=0,
batch=6,
patience=10,
plots=True,
save=True
)

After training, I reviewed:

  1. Precision
  2. Recall
  3. mAP
  4. Confusion matrix
  5. Validation images
  6. Detection behaviour with the live camera

The best.pt weight file was selected for the final application.


Develop the Software and Dashboard

The FaceCore software is written mainly in Python and is divided into several modules.

The main processing pipeline performs the following tasks:

  1. Reads the distance from the ultrasonic sensor
  2. Captures an image from the camera
  3. Runs the custom YOLO model
  4. Reads the detected class and confidence
  5. Decides whether identity recognition is allowed
  6. Extracts a face embedding
  7. Loads registered users from the database
  8. Finds the closest matching identity
  9. Makes the final access decision
  10. Updates the hardware and dashboard
  11. Stores the event in the database

YOLO verification

The YOLO model is loaded from the trained best.pt file. Images are processed at an inference size of 960 pixels.

The model returns:

  1. detected class
  2. confidence score
  3. number of detections
  4. bounding boxes
  5. verification decision

The identity recognition stage is skipped when:

  1. a picture attack is detected
  2. the class is no_access
  3. glasses are detected
  4. no valid access class is detected
  5. the confidence is below the minimum threshold

This prevents a low quality or suspicious camera image from being used for identity matching.

Face recognition

After the YOLO verification succeeds, FaceCore searches for a face in the image and creates a numerical face embedding.

When the face_recognition Python library is available, the system uses its HOG-based face detector and face-encoding model.

If the library is unavailable, the application can use a simpler OpenCV fallback. The fallback detects the face with a Haar cascade, converts it to grayscale, resizes it and creates a normalised numerical vector.

The face embedding is compared with the embeddings of registered users. The application calculates the distance between the new embedding and every compatible stored embedding.

The user with the smallest distance is selected as the best candidate. The match is accepted only when the distance is below the configured threshold.

Dashboard

The Gradio dashboard shows:

  1. live or captured camera image
  2. YOLO bounding box
  3. detected YOLO class
  4. YOLO confidence (debug)
  5. recognised user name
  6. distance-sensor reading
  7. API status
  8. database status
  9. hardware status
  10. final access decision
  11. access logs

Possible final states include:

  1. Access granted to a recognised user
  2. Guest user
  3. Glasses detected
  4. Invalid face
  5. Picture attack detected
  6. No face found
  7. Person outside the active distance -> Idle
  8. Database or API error


Connect the Hardware

The electronic components were first tested separately before being combined.

The final system includes:

  1. USB camera for image capture
  2. HC-SR04 ultrasonic sensor for distance measurement
  3. 16x2 LCD for instructions and decisions
  4. RGB LED for visual status
  5. Metal push buttons for manual input
  6. Passive buzzer for sound feedback
  7. GPIO breakout board
  8. Breadboard
  9. Jumper wires

Each component was first tested with a small standalone Python script. After the individual tests worked, the hardware controls were integrated into the main application.

Extra care is required when connecting the HC-SR04 echo pin to a Raspberry Pi. Raspberry Pi GPIO pins use 3.3 V logic, while the echo output of the sensor can be 5 V.


Design and Enclosure

bpy.png
lcut.png

The enclosure protects the electronic components and gives the project a clean, finished appearance. I made my enclosure from 4 mm plywood using a laser cutter. However, the design could also be adapted for 3D printing or another method.

Generate the basic enclosure

I used the Console2 template from boxes.py as the starting point. This template creates an enclosure with a sloped front panel, which was suitable for mounting the display, camera, buttons and sensors.

Before downloading the design, I adjusted the template settings to match the material and the available laser cutter:

  1. Material thickness: 4 mm
  2. Sheet size: 450 × 600 mm
  3. Burn correction: 0 mm
  4. Inner corners: corner

It can also be modified to have removable parts if required.

Modify the SVG file

I opened the generated SVG in Inkscape and modified the panels to fit the FaceCore components.

I added or adjusted openings for all the sensors: Camera, LCD, LED, Buttons, Proximity Sensor, Power Supply.

I also removed the automatically generated panel labels and checked that all cutting lines used the correct stroke settings.

Laser cut the parts

I imported the finished SVG file into the laser-cutter software and positioned the panel inside the available sheet area.

The design was then cut from 4 mm plywood. After cutting, I removed the parts and checked the finger joints, openings and overall dimensions.

Test-fit and assemble the enclosure

Before using glue, I performed a dry fit to make sure that all the finger joints alligned correctly, as well as awhether my sensors fitted into the openings. if not - fix by tape or widen the opening manually.

After checking the fit, I assembled my electronics, fixed it, and only after that have i glued and fixed the parts, except for the roof which is used for maintenance.

Backend and Database

fastapi.png

The backend connects the AI models, PostgreSQL database, Gradio dashboard and Raspberry Pi hardware into one complete system. It is responsible for processing camera images, recognising registered users, making the final access decision and storing the result.

The FaceCore backend is written in Python using FastAPI. PostgreSQL stores registered users, access attempts and hardware status events. Docker Compose is used to run the backend services in a consistent environment.

The Gradio dashboard and hardware controller run directly on the Raspberry Pi. They read the camera and sensors and send images and measurements to the FastAPI backend.

System architecture

The Raspberry Pi stack is located in the RPi directory of the project.

It contains three main parts:

  1. Docker services:
  2. PostgreSQL
  3. pgAdmin
  4. FastAPI backend
  5. AI processing:
  6. Custom YOLO model
  7. Face embedding extraction
  8. Identity matching
  9. Raspberry Pi application:
  10. USB camera
  11. Ultrasonic sensor
  12. LCD
  13. RGB LED
  14. Buttons
  15. Buzzer
  16. Gradio dashboard

The overall communication flow is:

Camera and sensors
Raspberry Pi hardware application
FastAPI backend
YOLO verification
Face recognition
PostgreSQL database
Final decision
Dashboard, LCD, RGB LED and buzzer

The backend prevents face recognition from running when YOLO detects:

  1. picture_attack
  2. no_access
  3. glasses
  4. no valid access class
  5. confidence below the required threshold

This creates a two-stage verification process

Docker Compose services

The Docker configuration is stored in:

RPi/docker-compose.yml

It starts three services:

PostgreSQL

PostgreSQL stores the persistent project data.

The container uses postgres:16-alpine


Its files are stored in a Docker volume. Because of this, users and access logs remain available when the containers are restarted or recreated.

The database volume should not be deleted unless all stored data is no longer needed.

pgAdmin

pgAdmin provides a web interface for viewing the PostgreSQL database.

It can normally be opened at:

http://<raspberry-pi-ip>:5052

I used pgAdmin to inspect the registered users, access logs and status events

FastAPI

The API container is built using:

RPi/Dockerfile

It exposes the backend on port 8000.

The Docker image contains:

  1. FastAPI source code
  2. Backend Python dependencies
  3. YOLO model
  4. Face-recognition helper code
  5. Database storage code

The YOLO model is expected at:

/app/ai/best.pt

API endpoints

The FastAPI application provides several endpoints.

System Checks

GET /health

Checks whether the API is running and reports the active face-recognition backend.

GET /db-health

Checks whether PostgreSQL is available.

Users

GET /users
PATCH /users/{user_id}
DELETE /users/{user_id}

These endpoints list users, rename users and deactivate users

AI operations

POST /scan

Runs YOLO without performing identity matching.

POST /register

Runs YOLO and, when the image is accepted, creates a face embedding and registers a new user.

POST /verify

Runs YOLO and face recognition, then returns access granted or access denied.

Logs and Hardware status

GET /logs
GET /status-events
POST /status

These endpoints provide access history and store hardware events such as:

  1. READY
  2. STANDBY
  3. ANALYZING
  4. ACCESS_GRANTED
  5. ACCESS_DENIED
  6. ERROR

Database structure

The database tables are created automatically when the backend starts.

FaceCore uses three main tables.

users

The users table stores registered people.

Important fields include:

  1. User ID
  2. Name
  3. Face embedding
  4. Recognition backend
  5. Registration image path
  6. Creation and update timestamps

access_logs

The access_logs table stores scan, registration and verification attempts.

It can contain:

  1. Event type
  2. Human-readable decision
  3. Result status
  4. YOLO class
  5. YOLO confidence
  6. Recognised user
  7. Face-matching distance
  8. Proximity measurement
  9. Original image path
  10. Annotated image path
  11. Additional JSON details

status_events

The status_events table stores events produced by the Raspberry Pi hardware application.

These events can include:

  1. Current system state
  2. LCD text
  3. Component name
  4. YOLO confidence
  5. Proximity distance
  6. Additional technical information

Face-recognition backend

The application supports two face-recognition methods.

The preferred backend is:

face_recognition

It creates a 128-number face descriptor.