Added facial recognition confidence threshold
Also reset version and added release workflow
This commit is contained in:
parent
4f1f253c6c
commit
c767a819c2
|
@ -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 }}
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue