changes
This commit is contained in:
parent
a49f009d43
commit
1d2865d361
@ -5,9 +5,9 @@ After=network.target
|
||||
[Service]
|
||||
Type=simple
|
||||
User={{USER}}
|
||||
WorkingDirectory=/home/valer/dp_prakticka/src
|
||||
EnvironmentFile=/home/valer/dp_prakticka/src/.env
|
||||
ExecStart=/home/valer/env_python_dp/bin/python3.10 /home/valer/dp_prakticka/src/face_rec_no_gui.py
|
||||
WorkingDirectory=/home/valer/recognition_system/src
|
||||
EnvironmentFile=/home/valer/recognition_system/src/.env
|
||||
ExecStart=/home/valer/recognition_system/src/biometric_system/bin/python3.10 /home/valer/recognition_system/src/face_rec_no_gui.py
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
|
@ -5,9 +5,11 @@ After=network.target
|
||||
[Service]
|
||||
Type=simple
|
||||
User={{USER}}
|
||||
WorkingDirectory=/home/valer/dp_prakticka/src
|
||||
EnvironmentFile=/home/valer/dp_prakticka/src/.env
|
||||
ExecStart=/home/valer/env_python_dp/bin/python3.10 /home/valer/dp_prakticka/src/app.py
|
||||
WorkingDirectory=/home/valer/recognition_system/src
|
||||
EnvironmentFile=/home/valer/recognition_system/src/.env
|
||||
ExecStart=/home/valer/recognition_system/src/biometric_system/bin/python3.10 /home/valer/recognition_system/src/app.py
|
||||
Environment="PATH=/home/valer/recognition_system/src/biometric_system/bin"
|
||||
Environment="PYTHONUNBUFFERED=1"
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
|
93
src/app.py
93
src/app.py
@ -5,11 +5,14 @@ import subprocess
|
||||
import pickle
|
||||
import dlib
|
||||
import face_recognition
|
||||
import subprocess
|
||||
import sys
|
||||
import numpy as np
|
||||
from flask import Flask, render_template, Response, request, redirect, url_for, session, flash
|
||||
from functools import wraps
|
||||
from db_connector import log_recognition, get_recognition_logs
|
||||
from config import FLASK_SECRET_KEY
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = FLASK_SECRET_KEY
|
||||
@ -58,13 +61,65 @@ def run_face():
|
||||
return redirect(url_for("add_face"))
|
||||
script = "enroll_no_gui.py"
|
||||
try:
|
||||
result = subprocess.run(["python3", script, face_name, "--auto"],
|
||||
venv_python = "./biometric_system/bin/python3.10"
|
||||
result = subprocess.run([venv_python, script, face_name, "--auto"],
|
||||
capture_output=True, text=True, timeout=300)
|
||||
output = result.stdout if result.stdout else result.stderr
|
||||
except Exception as e:
|
||||
output = str(e)
|
||||
return render_template("result.html", output=output)
|
||||
|
||||
@app.route("/run_face_live")
|
||||
@login_required
|
||||
def run_face_live():
|
||||
face_name = request.args.get("face_name", "")
|
||||
venv_python = "/home/valer/recognition_system/src/biometric_system/bin/python3.10"
|
||||
def generate():
|
||||
env = os.environ.copy()
|
||||
env["PYTHONUNBUFFERED"] = "1"
|
||||
|
||||
try:
|
||||
subprocess.run(["sudo", "systemctl", "stop", "face_rec"], check=True)
|
||||
print("✅ face_rec_service stopped")
|
||||
yield "data: [face_rec_service stopped]\n\n"
|
||||
except subprocess.CalledProcessError as e:
|
||||
error_msg = f"[ERROR] Could not stop service: {e}"
|
||||
print(error_msg)
|
||||
yield f"data: {error_msg}\n\n"
|
||||
yield "data: [Aborting enrollment.]\n\n"
|
||||
return
|
||||
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
[sys.executable, "enroll_no_gui.py", face_name, "--auto"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
bufsize=1,
|
||||
env=env
|
||||
)
|
||||
|
||||
for line in iter(process.stdout.readline, ''):
|
||||
print(line, end='')
|
||||
yield f"data: {line}\n\n"
|
||||
|
||||
process.stdout.close()
|
||||
process.wait()
|
||||
except Exception as e:
|
||||
yield f"data: [ERROR during enrollment: {e}]\n\n"
|
||||
print(f"[ERROR] during subprocess: {e}")
|
||||
|
||||
try:
|
||||
subprocess.run(["sudo", "systemctl", "start", "face_rec"], check=True)
|
||||
print("✅ face_rec_service started")
|
||||
yield "data: [face_rec_service started]\n\n"
|
||||
except subprocess.CalledProcessError as e:
|
||||
error_msg = f"[ERROR] Could not start service: {e}"
|
||||
print(error_msg)
|
||||
yield f"data: {error_msg}\n\n"
|
||||
|
||||
return Response(generate(), mimetype='text/event-stream')
|
||||
|
||||
@app.route("/delete_person")
|
||||
@login_required
|
||||
def delete_person():
|
||||
@ -79,7 +134,8 @@ def run_delete_person():
|
||||
return redirect(url_for("delete_person"))
|
||||
script = "remove_face.py"
|
||||
try:
|
||||
result = subprocess.run(["python3", script, person_name],
|
||||
venv_python = "./biometric_system/bin/python3.10"
|
||||
result = subprocess.run([venv_python, script, person_name],
|
||||
capture_output=True, text=True, timeout=60)
|
||||
output = result.stdout if result.stdout else result.stderr
|
||||
except Exception as e:
|
||||
@ -89,14 +145,30 @@ def run_delete_person():
|
||||
@app.route("/list_people")
|
||||
@login_required
|
||||
def list_people():
|
||||
|
||||
key = os.getenv("ENCODINGS_KEY")
|
||||
fernet = Fernet(key)
|
||||
|
||||
with open("encodings.pickle", "rb") as enc_file:
|
||||
encrypted_data = enc_file.read()
|
||||
|
||||
try:
|
||||
with open("encodings.pickle", "rb") as f:
|
||||
data = pickle.load(f)
|
||||
decrypted_data = fernet.decrypt(encrypted_data)
|
||||
data = pickle.loads(decrypted_data)
|
||||
names = data.get("names", [])
|
||||
unique_names = sorted(set(names))
|
||||
except Exception as e:
|
||||
print(f"[ERROR] {e}")
|
||||
print(f"[ERROR] Failed to decrypt or unpickle: {e}")
|
||||
names = []
|
||||
unique_names = sorted(set(names))
|
||||
#try:
|
||||
# with open("encodings.pickle", "rb") as f:
|
||||
# data = pickle.load(f)
|
||||
# names = data.get("names", [])
|
||||
#except Exception as e:
|
||||
# print(f"[ERROR] {e}")
|
||||
# names = []
|
||||
#unique_names = sorted(set(names))
|
||||
#print(unique_names)
|
||||
return render_template("list_people.html", people=unique_names)
|
||||
|
||||
@app.route("/logs")
|
||||
@ -110,10 +182,19 @@ def gen_frames_raw():
|
||||
if not cap.isOpened():
|
||||
print("Error: Could not open camera.")
|
||||
return
|
||||
|
||||
while True:
|
||||
ret, frame = cap.read()
|
||||
if not ret:
|
||||
continue
|
||||
|
||||
# OPTIONAL
|
||||
# rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
||||
# face_locations = face_recognition.face_locations(rgb_frame)
|
||||
|
||||
# for (top, right, bottom, left) in face_locations:
|
||||
# cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
|
||||
|
||||
ret, buffer = cv2.imencode('.jpg', frame)
|
||||
if not ret:
|
||||
continue
|
||||
|
@ -12,6 +12,6 @@ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
ENCODINGS_PATH = os.path.join(SCRIPT_DIR, "encodings.pickle")
|
||||
LANDMARKS_PATH = os.path.join(SCRIPT_DIR, "shape_predictor_68_face_landmarks.dat")
|
||||
|
||||
THRESHOLD = 0.4
|
||||
THRESHOLD = 0.3
|
||||
COOLDOWN = 15
|
||||
CV_SCALER = 4
|
||||
|
@ -8,12 +8,16 @@ import dlib
|
||||
from imutils import face_utils
|
||||
import pickle
|
||||
from cryptography.fernet import Fernet
|
||||
from dotenv import load_dotenv
|
||||
|
||||
if "ENCODINGS_KEY" not in os.environ:
|
||||
print("Please set the ENCODINGS_KEY environment variable with your encryption key.")
|
||||
exit(1)
|
||||
|
||||
key = os.environ.get("ENCODINGS_KEY").encode()
|
||||
#if "ENCODINGS_KEY" not in os.environ:
|
||||
# print("Please set the ENCODINGS_KEY environment variable with your encryption key.")
|
||||
# exit(1)
|
||||
|
||||
#key = os.environ.get("ENCODINGS_KEY").encode()
|
||||
load_dotenv()
|
||||
key = os.getenv("ENCODINGS_KEY")
|
||||
fernet = Fernet(key)
|
||||
|
||||
def encrypt_data(data):
|
||||
@ -102,7 +106,8 @@ def capture_photos(name, auto=False):
|
||||
print(f"Photo capture completed. {photo_count} photos saved for {name}.")
|
||||
|
||||
print("[INFO] Running model training script with encryption...")
|
||||
subprocess.run(["python", "model_training.py"])
|
||||
venv_python = "./biometric_system/bin/python3.10"
|
||||
subprocess.run([venv_python, "model_training.py"])
|
||||
print("[INFO] Model training complete. Exiting...")
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -5,15 +5,18 @@ import face_recognition
|
||||
import pickle
|
||||
import cv2
|
||||
from cryptography.fernet import Fernet
|
||||
from dotenv import load_dotenv
|
||||
|
||||
if "ENCODINGS_KEY" not in os.environ:
|
||||
print("Please set the ENCODINGS_KEY environment variable with your encryption key.")
|
||||
exit(1)
|
||||
key = os.environ.get("ENCODINGS_KEY").encode()
|
||||
#if "ENCODINGS_KEY" not in os.environ:
|
||||
# print("Please set the ENCODINGS_KEY environment variable with your encryption key.")
|
||||
# exit(1)
|
||||
#key = os.environ.get("ENCODINGS_KEY").encode()
|
||||
load_dotenv()
|
||||
key = os.getenv("ENCODINGS_KEY")
|
||||
fernet = Fernet(key)
|
||||
|
||||
encodings_path = "encodings-cnn_large.pickle"
|
||||
train_path = "datasets_web/dataset/learning"
|
||||
encodings_path = "encodings.pickle"
|
||||
train_path = "dataset"
|
||||
|
||||
if os.path.exists(encodings_path):
|
||||
print("[INFO] Loading existing encodings...")
|
||||
|
@ -16,7 +16,9 @@ numpy==2.2.3
|
||||
opencv-python==4.11.0.86
|
||||
pillow==11.1.0
|
||||
pycparser==2.22
|
||||
pymysql==1.1.1
|
||||
pyrealsense2==2.55.1.6486
|
||||
pyserial==3.5
|
||||
PyYAML==6.0.2
|
||||
python-dotenv==1.1.0
|
||||
Werkzeug==3.1.3
|
||||
|
68
src/servo.py
68
src/servo.py
@ -1,9 +1,55 @@
|
||||
import machine
|
||||
import time
|
||||
import sys
|
||||
# At the top of your script
|
||||
from machine import Pin, PWM
|
||||
import rp2
|
||||
import array, time, sys
|
||||
|
||||
servo_pin = machine.Pin(15)
|
||||
pwm = machine.PWM(servo_pin)
|
||||
# Setup LED
|
||||
NUM_LEDS = 16
|
||||
PIN_NUM = 22
|
||||
brightness = 0.2
|
||||
|
||||
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
|
||||
def ws2812():
|
||||
T1 = 2
|
||||
T2 = 5
|
||||
T3 = 3
|
||||
wrap_target()
|
||||
label("bitloop")
|
||||
out(x, 1) .side(0) [T3 - 1]
|
||||
jmp(not_x, "do_zero") .side(1) [T1 - 1]
|
||||
jmp("bitloop") .side(1) [T2 - 1]
|
||||
label("do_zero")
|
||||
nop() .side(0) [T2 - 1]
|
||||
wrap()
|
||||
|
||||
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(PIN_NUM))
|
||||
sm.active(1)
|
||||
ar = array.array("I", [0 for _ in range(NUM_LEDS)])
|
||||
|
||||
def pixels_show():
|
||||
dimmer_ar = array.array("I", [0 for _ in range(NUM_LEDS)])
|
||||
for i, c in enumerate(ar):
|
||||
r = int(((c >> 8) & 0xFF) * brightness)
|
||||
g = int(((c >> 16) & 0xFF) * brightness)
|
||||
b = int((c & 0xFF) * brightness)
|
||||
dimmer_ar[i] = (g << 16) + (r << 8) + b
|
||||
sm.put(dimmer_ar, 8)
|
||||
time.sleep_ms(10)
|
||||
|
||||
def pixels_set(i, color):
|
||||
ar[i] = (color[1]<<16) + (color[0]<<8) + color[2]
|
||||
|
||||
def pixels_fill(color):
|
||||
for i in range(len(ar)):
|
||||
pixels_set(i, color)
|
||||
|
||||
# Color constants
|
||||
BLACK = (0, 0, 0)
|
||||
WHITE = (255, 255, 255)
|
||||
|
||||
# Setup Servo
|
||||
servo_pin = Pin(15)
|
||||
pwm = PWM(servo_pin)
|
||||
pwm.freq(50)
|
||||
|
||||
def set_angle(angle):
|
||||
@ -22,11 +68,17 @@ def move_servo_smoothly(start_angle, end_angle, step=1, delay=0.02):
|
||||
time.sleep(delay)
|
||||
|
||||
def open_door():
|
||||
move_servo_smoothly(0, 180, step=2, delay=0.03)
|
||||
time.sleep(5)
|
||||
pixels_fill(WHITE)
|
||||
pixels_show()
|
||||
move_servo_smoothly(180, 0, step=2, delay=0.03)
|
||||
time.sleep(5)
|
||||
move_servo_smoothly(0, 180, step=2, delay=0.03)
|
||||
pixels_fill(BLACK)
|
||||
pixels_show()
|
||||
|
||||
# Wait for command
|
||||
while True:
|
||||
command = sys.stdin.readline().strip()
|
||||
if command == "run":
|
||||
open_door()
|
||||
open_door()
|
||||
|
||||
|
@ -1,13 +1,66 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Add Face{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="mb-4">Add a New Face</h1>
|
||||
<p>Enter the name of the person and click the button below to run the Add Face script.</p>
|
||||
<form method="post" action="{{ url_for('run_face') }}">
|
||||
<div class="mb-3">
|
||||
<label for="face_name" class="form-label">Name</label>
|
||||
<input type="text" class="form-control" id="face_name" name="face_name" placeholder="Enter name" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Run Add Face Script</button>
|
||||
</form>
|
||||
<h1 class="mb-4">Add a New Face</h1>
|
||||
<p>Enter the name of the person and click the button below to run the Add Face script.</p>
|
||||
|
||||
<form id="faceForm" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="face_name" class="form-label">Name</label>
|
||||
<input type="text" class="form-control" id="face_name" name="face_name" placeholder="Enter name" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Run Add Face Script</button>
|
||||
</form>
|
||||
|
||||
<!-- Loading animation -->
|
||||
<div id="loading" class="mt-3" style="display: none;">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<span class="ms-2">Processing face data...</span>
|
||||
</div>
|
||||
|
||||
<!-- Row for side-by-side display -->
|
||||
<div class="row mt-4">
|
||||
<!-- Output log -->
|
||||
<div class="col-md-6 mb-4">
|
||||
<h3>Live Script Output</h3>
|
||||
<pre id="output" style="background-color: #f8f9fa; padding: 1rem; height: 300px; overflow-y: scroll;"></pre>
|
||||
</div>
|
||||
|
||||
<!-- Live video feed -->
|
||||
<div class="col-md-6 mb-4">
|
||||
<h3>Camera Feed</h3>
|
||||
<img src="{{ url_for('video_feed') }}" class="img-fluid" alt="Live Stream" style="max-height: 300px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const form = document.getElementById("faceForm");
|
||||
const output = document.getElementById("output");
|
||||
const loading = document.getElementById("loading");
|
||||
|
||||
form.addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
output.textContent = "";
|
||||
loading.style.display = "block";
|
||||
|
||||
const formData = new FormData(form);
|
||||
const name = formData.get("face_name");
|
||||
|
||||
const eventSource = new EventSource(`/run_face_live?face_name=${encodeURIComponent(name)}`);
|
||||
|
||||
eventSource.onmessage = function (event) {
|
||||
output.textContent += event.data + "\n";
|
||||
output.scrollTop = output.scrollHeight;
|
||||
};
|
||||
|
||||
eventSource.onerror = function () {
|
||||
eventSource.close();
|
||||
loading.style.display = "none";
|
||||
output.textContent += "\n[Stream ended or error occurred]";
|
||||
};
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -3,7 +3,6 @@
|
||||
{% block content %}
|
||||
<h1 class="mb-4">Live Video Stream</h1>
|
||||
<div class="text-center">
|
||||
<img src="{{ url_for('video_feed') }}" class="img-fluid" alt="Live Stream">
|
||||
</div>
|
||||
<hr>
|
||||
<h2 class="mt-4">Recognition Logs</h2>
|
||||
|
Loading…
Reference in New Issue
Block a user