diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 0000000..2aa61d5 --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -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 }} diff --git a/pyproject.toml b/pyproject.toml index 98790db..4e579dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] 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" authors = ["slashtechno <77907286+slashtechno@users.noreply.github.com>"] 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 # Might be able to remove this version constraint later tensorflow-io-gcs-filesystem = "0.31.0" +tensorflow = "^2.14.0" deepface = "^0.0.79" -tensorflow = "^2.14.0" [tool.poetry.group.dev.dependencies] black = "^23.9.1" diff --git a/wyzely_detect/utils/utils.py b/wyzely_detect/utils/utils.py index 6329324..46ae4d1 100644 --- a/wyzely_detect/utils/utils.py +++ b/wyzely_detect/utils/utils.py @@ -74,6 +74,7 @@ def recognize_face( 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 + 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 The directory should be structured as follows: faces/ @@ -101,11 +102,6 @@ def recognize_face( print("representations_arcface.pkl does not exist") 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 # 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( run_frame, db_path=str(path_to_directory), - # enforce_detection=True, - # Seems this works? + # Problem with enforce_detection=False is that it will always (?) return a face, no matter the confidence + # Thus, false-positives need to be filtered out enforce_detection=False, silent=True, # 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"], "y2": df.iloc[-1]["source_y"] + df.iloc[-1]["source_h"], } - # After some brief testing, it seems positve matches are > 0.3 - # I have not seen any false positives, so there is no threashold yet + # After some brief testing, it seems positive matches are > 0.3 distance = df.iloc[-1]["ArcFace_cosine"] + # TODO: Make this a CLI argument + if distance < 0.3: + return None # if 0.5 < distance < 0.7: # label = "Unknown" to_return = dict(label=label, **coordinates)