Skip to content

MiniFAS selection uses the MobileNetV3 inference path #149

Description

@phucvinh57

Discussed in #144

Originally posted by Tunahanyrd July 13, 2026
I traced the anti-spoof model selection in 1.4.1 and found that the selected MiniFAS model type is lost before inference.

  • minifas-v2 is registered as a selectable anti-spoof model:

    KnownModel {
    slug: "mobilenetv3-antispoof",
    filename: "mobilenetv3_antispoof.onnx",
    display_name: "MobileNetV3 Anti-Spoof",
    model_type: "anti_spoofing",
    },
    KnownModel {
    slug: "minifas-v2",
    filename: "minifas_v2.onnx",
    display_name: "MiniFASNet V2",
    model_type: "anti_spoofing",
    },

  • The inference caller resolves the selected model path, but constructs FaceAntiSpoofing with only the path, image size and threshold:

    bool checkAntiSpoofByAIModel(const FaceMethodConfig& faceCfg, const std::string& username,
    const ImageRGB& face, const AuthConfig& authCfg,
    const ModelRegistry& model_registry) {
    const std::string modelPath =
    model_registry.resolveModelPath(faceCfg.anti_spoofing.model.model_id).value_or("");
    if (modelPath.empty() || !std::ifstream(modelPath).good()) {
    spdlog::error("FaceAuth: Anti-spoofing model file not found: {}", modelPath);
    return false;
    }
    try {
    FaceAntiSpoofing face_as(modelPath, 128, faceCfg.anti_spoofing.model.threshold);
    const SpoofResult result = face_as.inference(face);

  • The omitted fourth argument defaults to mobilenetv3:

    // model_type: "minifasv2" or "mobilenetv3" (default)
    class FaceAntiSpoofing {
    public:
    FaceAntiSpoofing(const std::string& ckpt, int imgsz = 128, const float threshold = 0.8,
    const std::string& model_type = "mobilenetv3");

  • Filename inference only runs when model_type is neither mobilenetv3 nor minifasv2. Since the default is already mobilenetv3, the MiniFAS filename is never inspected:

    FaceAntiSpoofing::FaceAntiSpoofing(const std::string& ckpt, int imgsz, const float threshold,
    const std::string& model_type)
    : threshold(threshold),
    imgsz(imgsz),
    model_type(model_type),
    session(ckpt, "FaceAntiSpoofing") {
    // Unrecognized model_type: infer from the checkpoint filename.
    if (this->model_type != "minifasv2" && this->model_type != "mobilenetv3") {
    this->model_type =
    (ckpt.find("mobilenetv3") != std::string::npos) ? "mobilenetv3" : "minifasv2";
    }

The loaded file can therefore be minifas_v2.onnx while preprocessing and output handling still follow the MobileNetV3 branch.

I would like to send a small PR that passes the selected built-in model type explicitly and adds a regression test. The scoring policy and other anti-spoof behavior would remain unchanged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions