tradle / KYCDeepFace

KYC face matching project.
GNU Affero General Public License v3.0
4 stars 0 forks source link

Python API concept #2

Open martinheidegger opened 2 years ago

martinheidegger commented 2 years ago

Hello @fyr91 - what do you think about this as a Python high-level API:

I imagine this API could allows to get the embedding/features for the images based on input images, it would allow a two-step process where the embedding can be created and matched as well as put into a bigger matching database.

Part of the API design was thought to also have easy means to put a CLI, HTTP or other interface on top of it.

Do you think this could hold up? Is this a good idea?

class KYCDeepFaceDB:
    def __init__(self):
        return

    def set (self, face_id, features):
        return

    def delete (self, face_id):
        return

    def find_face (self, features):
        return {
            # Successfully matched both embeddings
            "code": "SUCCESS",
            "found": "features_id_3", # Feature that we found
            "confidence": 0.78,
            "verified": True
        }
        return {
            # Any unexpected error occured
            "code": "ERROR",
            "message": "Something strange happend"
        }

class KYCDeepFace:
    def __init__(self, verify_confidence=0.76, max_image_size=(500, 500), min_image_size=(100, 100), model=None):
        return

    def get_faces (self, image_binary_data):
        return {
            "code": "SUCCESS",
            "faces": [
                {
                    "box": { "x1": 0, "x2": 290, "y1": 269, "y2": 488 },
                    "features": "ABCD=" # The embedding as base64 encoded binary data
                },
                {
                    "box": { "x1": 0, "x2": 290, "y1": 269, "y2": 488 },
                    "features": "ABCD=" # Any other face in the image
                }
            ],
            "partial_faces": [
                # For parts of the image that may almost be detected as face but eventually were deemed non-viable
                # The existing errors are depending on what we can detect. Some examples that could work below:
                {
                    "reason": "CROPPED", # Exemplary (unsure if possible): if a face was cropped on top
                    "box": { "x1": 0, "x2": 0, "y1": 25, "y2": 70 }
                },
                {
                    "reason": "NOT_FRONT_FACING", # Face not facing
                    "box": { "x1": 0, "x2": 0, "y1": 25, "y2": 70 }
                },
                {
                    "reason": "MASKED", # Face with a mask
                    "box": { "x1": 0, "x2": 0, "y1": 25, "y2": 70 }
                }
            ]
        }
        return {
            "code": "INVALID_IMAGE",
            "reason": "TOO_SMALL" # TOO_LARGE, INVALID_FORMAT, READ_ERROR, TOO_DARK...
        }
        return {
            "code": "ERROR",
            "message": "Something strange happened"
        }

    def match_faces (self, face_1_features, face_2_features):
        return {
            "code": "SUCCESS",
            "confidence": 0.78,
            "verified": True
        }
        return {
            # Any unexpected error occurred
            "code": "ERROR",
            "message": "Something strange happened"
        }
urbien commented 2 years ago

@martinheidegger for KYC and identification purposes we do not have situations where there is more than one face in the image. Neither ID nor a selfie should contain more than one face. Due to that, I think the interface can be simplified. Didn't I suggest in the past what the interface could be like, in view of the need for 1:1 and 1:N matching?

martinheidegger commented 2 years ago

The matching itself is 1:1 matching - match_faces(self, face_1_features, face_2_features)) - and 1:N matching - find_face(self, features).

The input images may contain multiple faces or no faces. If the API were to return error cases like NO_FACE_FOUND, or TOO_MANY_FACES_FOUND it would complicate the API but also make it less flexible. By providing the list of all faces in an image a user interface could show which images are found and maybe help debug if something that wasn't supposed to be a face be treated as a face.