VL.Deepface

A set of nodes based on Serengil’s deepface

DeepFace is a lightweight face recognition and facial attribute analysis (age, gender, emotion and race) framework for python. It is a hybrid face recognition framework wrapping state-of-the-art models: VGG-Face, FaceNet, OpenFace, DeepFace, DeepID, ArcFace, Dlib, SFace and GhostFaceNet.

12 Likes

Thanks for sharing. After I had something similar running with vvvv via an online API, I was interested if I can get it running locally with your VL solution.

However I was at first facing some trouble with the following error:

TypeError: Object of type float32 is not JSON serializable

Here’s how I got rid of it, if anyone else runs into this:


Solution:

After a fresh install of Python (3.12) and DeepFace (0.0.93), I was able to run the DeepFace server from vvvv, but was facing the following error when sending an image over for analysis:

TypeError: Object of type float32 is not JSON serializable

Some AI helped me to find out the problem is on the Flask Server side. The function service.analyze() in routes.py apparently returns a dictionary or object that contains numpy.float32 values, and Flask tries to serialize those directly to JSON - which fails ().

The solution was simply modifying the routes.py to handle non-serializable numpy types to regular Python Data types.

(As I am not into Python: I hope I understood this correct, let me know if you know bette ;))

0.) Locate and edit

deepface\api\src\modules\core\routes.py

1.) Import Numpy

import numpy as np

2.) Add a helper function that converts the float32 (and other numpy types) to regular Python data types:

def convert_numpy_types(obj):
    if isinstance(obj, dict):
        return {k: convert_numpy_types(v) for k, v in obj.items()}
    elif isinstance(obj, list):
        return [convert_numpy_types(i) for i in obj]
    elif isinstance(obj, np.floating):
        return float(obj)
    elif isinstance(obj, np.integer):
        return int(obj)
    else:
        return obj
  1. Apply this function to demographies before returning it in the /analyze function:
    demographies = convert_numpy_types(demographies)
  1. The full /analyze endpoint looks like this then:
@blueprint.route("/analyze", methods=["POST"])
def analyze():
    input_args = request.get_json()

    if input_args is None:
        return {"message": "empty input set passed"}

    img_path = input_args.get("img") or input_args.get("img_path")
    if img_path is None:
        return {"message": "you must pass img_path input"}

    demographies = service.analyze(
        img_path=img_path,
        actions=input_args.get("actions", ["age", "gender", "emotion", "race"]),
        detector_backend=input_args.get("detector_backend", "opencv"),
        enforce_detection=input_args.get("enforce_detection", True),
        align=input_args.get("align", True),
        anti_spoofing=input_args.get("anti_spoofing", False),
    )

    logger.debug(demographies)

    demographies = convert_numpy_types(demographies)

    return demographies
3 Likes