added to tuke git

This commit is contained in:
Valér Jakubčo 2025-04-12 12:38:47 +02:00
commit dd6b3a72d7
259 changed files with 34611 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.git
src/dataset
src/encodings.pickle

15
services/face_rec.service Normal file
View File

@ -0,0 +1,15 @@
[Unit]
Description=Face Recognition Service
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
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,15 @@
[Unit]
Description=Web Application Service
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
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

1
src/.env.sample Normal file
View File

@ -0,0 +1 @@
ENCODINGS_KEY='EEKH1w-VSoR-QJSHPVgkLprSqaeaKeUo2m02WhcK1MU='

BIN
src/Python-3.10.0.tgz Normal file

Binary file not shown.

150
src/app.py Normal file
View File

@ -0,0 +1,150 @@
import os
import cv2
import time
import subprocess
import pickle
import dlib
import face_recognition
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
app = Flask(__name__)
app.secret_key = FLASK_SECRET_KEY
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not session.get("logged_in"):
flash("You need to be logged in to access that page.", "warning")
return redirect(url_for("login", next=request.url))
return f(*args, **kwargs)
return decorated_function
@app.route("/login", methods=["GET", "POST"])
def login():
error = None
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password")
if username == "admin" and password == "secret":
session["logged_in"] = True
session["username"] = username
flash("You were successfully logged in.", "success")
return redirect(url_for("index"))
else:
error = "Invalid credentials. Please try again."
return render_template("login.html", error=error)
@app.route("/logout")
def logout():
session.clear()
flash("You have been logged out.", "info")
return redirect(url_for("login"))
@app.route("/add_face")
@login_required
def add_face():
return render_template("add_face.html")
@app.route("/run_face", methods=["POST"])
@login_required
def run_face():
face_name = request.form.get("face_name")
if not face_name:
flash("Please provide a name.", "danger")
return redirect(url_for("add_face"))
script = "enroll_no_gui.py"
try:
result = subprocess.run(["python3", 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("/delete_person")
@login_required
def delete_person():
return render_template("delete_person.html")
@app.route("/run_delete_person", methods=["POST"])
@login_required
def run_delete_person():
person_name = request.form.get("person_name")
if not person_name:
flash("Please provide a name.", "danger")
return redirect(url_for("delete_person"))
script = "remove_face.py"
try:
result = subprocess.run(["python3", script, person_name],
capture_output=True, text=True, timeout=60)
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("/list_people")
@login_required
def list_people():
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))
return render_template("list_people.html", people=unique_names)
@app.route("/logs")
@login_required
def logs():
recognition_logs = get_recognition_logs()
return render_template("logs.html", logs=recognition_logs)
def gen_frames_raw():
cap = cv2.VideoCapture(4)
if not cap.isOpened():
print("Error: Could not open camera.")
return
while True:
ret, frame = cap.read()
if not ret:
continue
ret, buffer = cv2.imencode('.jpg', frame)
if not ret:
continue
frame_bytes = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
time.sleep(0.1)
cap.release()
@app.route("/")
@login_required
def index():
logs = get_recognition_logs()
return render_template("index.html", logs=logs)
@app.route("/video_feed")
@login_required
def video_feed():
return Response(gen_frames_raw(), mimetype="multipart/x-mixed-replace; boundary=frame")
@app.route("/open_door", methods=["GET", "POST"])
@login_required
def open_door():
try:
result = subprocess.run(["python3", "open_door.py"], capture_output=True, text=True, timeout=60, check=True)
output = result.stdout if result.stdout else result.stderr
flash("Door opened successfully!", "success")
except Exception as e:
output = str(e)
flash("Door open failed!", "danger")
return render_template("result.html", output=output)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=False)

81
src/camera_manager.py Normal file
View File

@ -0,0 +1,81 @@
import cv2
import time
import subprocess
import numpy as np
import face_recognition
import dlib
from imutils import face_utils
from config import THRESHOLD, COOLDOWN, CV_SCALER, LANDMARKS_PATH
from db_connector import log_recognition
latest_frame = None
last_trigger_time = 0
cap = cv2.VideoCapture(2)
if not cap.isOpened():
raise Exception("Error: Could not open camera.")
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(LANDMARKS_PATH)
def is_blinking(landmarks):
left_eye = landmarks[36:42]
right_eye = landmarks[42:48]
def eye_aspect_ratio(eye):
A = cv2.norm(eye[1] - eye[5])
B = cv2.norm(eye[2] - eye[4])
C = cv2.norm(eye[0] - eye[3])
return (A + B) / (2.0 * C)
left_eye_ratio = eye_aspect_ratio(left_eye)
right_eye_ratio = eye_aspect_ratio(right_eye)
ear = (left_eye_ratio + right_eye_ratio) / 2.0
return ear < 0.5
def camera_loop(known_face_encodings, known_face_names):
global latest_frame, last_trigger_time, cap
while True:
ret, frame = cap.read()
if not ret:
time.sleep(0.1)
continue
latest_frame = frame.copy()
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = detector(gray_frame)
for face in faces:
landmarks = predictor(gray_frame, face)
landmarks = face_utils.shape_to_np(landmarks)
if is_blinking(landmarks):
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
face_encodings_found = face_recognition.face_encodings(
rgb_frame,
[(face.top(), face.right(), face.bottom(), face.left())],
model='large'
)
if face_encodings_found and known_face_encodings:
face_encoding = face_encodings_found[0]
matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
if len(face_distances) > 0:
best_match_index = np.argmin(face_distances)
if face_distances[best_match_index] < THRESHOLD and matches[best_match_index]:
name = known_face_names[best_match_index]
current_time = time.time()
if current_time - last_trigger_time >= COOLDOWN:
print(f"[CAMERA] Detected: {name}")
log_recognition(name)
subprocess.run(["python3", "open_door.py"], check=True)
last_trigger_time = current_time
flush_camera(cap, flush_time=2.0)
break
time.sleep(0.1)
def flush_camera(cap, flush_time=2.0):
start = time.time()
while time.time() - start < flush_time:
cap.grab()
time.sleep(0.05)

17
src/config.py Normal file
View File

@ -0,0 +1,17 @@
import os
from cryptography.fernet import Fernet
FLASK_SECRET_KEY = "your_secret_key_here"
if "ENCODINGS_KEY" not in os.environ:
raise Exception("Please set the ENCODINGS_KEY environment variable with your encryption key.")
ENCODINGS_KEY = os.environ["ENCODINGS_KEY"].encode()
fernet = Fernet(ENCODINGS_KEY)
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
COOLDOWN = 15
CV_SCALER = 4

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Some files were not shown because too many files have changed in this diff Show More