Added facial recognition confidence threshold

Also reset version and added release workflow
This commit is contained in:
slashtechno 2023-10-22 16:45:01 -05:00
parent 4f1f253c6c
commit c767a819c2
Signed by: slashtechno
GPG Key ID: 8EC1D9D9286C2B17
3 changed files with 48 additions and 11 deletions

39
.github/workflows/python-publish.yml vendored Normal file
View File

@ -0,0 +1,39 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Upload Python Package
on:
release:
types: [published]
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@v1.8.10
with:
user: __token__
password: ${{ secrets.PYPI_PROJECT_API_TOKEN }}

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "wyzely-detect" name = "wyzely-detect"
version = "0.1.9" version = "0.1.0"
description = "Recognize faces/objects in a video stream (from a webcam or a security camera) and send notifications to your devices" description = "Recognize faces/objects in a video stream (from a webcam or a security camera) and send notifications to your devices"
authors = ["slashtechno <77907286+slashtechno@users.noreply.github.com>"] authors = ["slashtechno <77907286+slashtechno@users.noreply.github.com>"]
license = "MIT" license = "MIT"
@ -26,10 +26,10 @@ torch = ">=2.0.0, !=2.0.1, !=2.1.0"
# https://discuss.tensorflow.org/t/tensorflow-io-gcs-filesystem-with-windows/18849/4 # https://discuss.tensorflow.org/t/tensorflow-io-gcs-filesystem-with-windows/18849/4
# Might be able to remove this version constraint later # Might be able to remove this version constraint later
tensorflow-io-gcs-filesystem = "0.31.0" tensorflow-io-gcs-filesystem = "0.31.0"
tensorflow = "^2.14.0"
deepface = "^0.0.79" deepface = "^0.0.79"
tensorflow = "^2.14.0"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
black = "^23.9.1" black = "^23.9.1"

View File

@ -74,6 +74,7 @@ def recognize_face(
In addition, accepts an opencv image to be used as the frame to be searched In addition, accepts an opencv image to be used as the frame to be searched
Returns a single dictonary as currently only 1 face can be detected in each frame Returns a single dictonary as currently only 1 face can be detected in each frame
Cosine threshold is 0.3, so if the confidence is less than that, it will return None
dict contains the following keys: label, x1, y1, x2, y2 dict contains the following keys: label, x1, y1, x2, y2
The directory should be structured as follows: The directory should be structured as follows:
faces/ faces/
@ -101,11 +102,6 @@ def recognize_face(
print("representations_arcface.pkl does not exist") print("representations_arcface.pkl does not exist")
first_face_try = False first_face_try = False
# For debugging
# if path_to_directory.joinpath("representations_arcface.pkl").exists():
# print("representations_arcface.pkl exists")
# else:
# print("representations_arcface.pkl does not exist")
# face_dataframes is a vanilla list of dataframes # face_dataframes is a vanilla list of dataframes
# It seems face_dataframes is empty if the face database (directory) doesn't exist. Seems to work if it's empty though # It seems face_dataframes is empty if the face database (directory) doesn't exist. Seems to work if it's empty though
@ -115,8 +111,8 @@ def recognize_face(
face_dataframes = DeepFace.find( face_dataframes = DeepFace.find(
run_frame, run_frame,
db_path=str(path_to_directory), db_path=str(path_to_directory),
# enforce_detection=True, # Problem with enforce_detection=False is that it will always (?) return a face, no matter the confidence
# Seems this works? # Thus, false-positives need to be filtered out
enforce_detection=False, enforce_detection=False,
silent=True, silent=True,
# Could use VGG-Face, but whilst fixing another issue, ArcFace seemed to be slightly faster # Could use VGG-Face, but whilst fixing another issue, ArcFace seemed to be slightly faster
@ -152,9 +148,11 @@ def recognize_face(
"x2": df.iloc[-1]["source_x"] + df.iloc[-1]["source_w"], "x2": df.iloc[-1]["source_x"] + df.iloc[-1]["source_w"],
"y2": df.iloc[-1]["source_y"] + df.iloc[-1]["source_h"], "y2": df.iloc[-1]["source_y"] + df.iloc[-1]["source_h"],
} }
# After some brief testing, it seems positve matches are > 0.3 # After some brief testing, it seems positive matches are > 0.3
# I have not seen any false positives, so there is no threashold yet
distance = df.iloc[-1]["ArcFace_cosine"] distance = df.iloc[-1]["ArcFace_cosine"]
# TODO: Make this a CLI argument
if distance < 0.3:
return None
# if 0.5 < distance < 0.7: # if 0.5 < distance < 0.7:
# label = "Unknown" # label = "Unknown"
to_return = dict(label=label, **coordinates) to_return = dict(label=label, **coordinates)