#ifndef ARCFACERT_H #define ARCFACERT_H #pragma once #include "ANSFRCommon.h" //#include "fastdeploy/vision.h" #include "hnswlib/hnswlib.h" #include #include "engine.h" namespace ANSCENTER { class ArcFace : public ANSFRBase { public: virtual bool Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) override; virtual bool LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) override; bool OptimizeModel(bool fp16, std::string& optimizedModelFolder); // Single face feature (uses RunArcFace) std::vector Feature(const cv::Mat& image, const ANSCENTER::Object& bBox); // Main entry: run recognition for all faces in bBox std::vector Match(const cv::Mat& input, const std::vector& bBox, const std::map& userDict); cv::Mat GetCropFace(const cv::Mat& input, const ANSCENTER::Object& bBox); void Init(); void AddEmbedding(const std::string& className, float embedding[]); void AddEmbedding(const std::string& className, const std::vector& embedding); bool UpdateParamater(double knownPersonThreshold) { _modelConfig.unknownPersonThreshold = knownPersonThreshold; m_knownPersonThresh = _modelConfig.unknownPersonThreshold; return true; } ~ArcFace(); bool Destroy(); private: bool LoadEngine(const std::string onnxModelPath, bool engineOptimisation = true); // Batched forward: one embedding per Object.mask std::vector> Forward(const cv::Mat& input, const std::vector& outputBbox); // Search embeddings in FAISS index std::tuple, std::vector> SearchForFaces(const std::vector>& detectedEmbeddings); // Single-face inference (kept for Feature) std::vector RunArcFace(const cv::Mat& input); // New: batched inference helper std::vector> RunArcFaceBatch(const std::vector& faceROIs); protected: std::vector classNames; ModelConfig _modelConfig; std::string _modelFilePath; float m_knownPersonThresh = 0.35f; const int FACE_WIDTH = 112; const int FACE_HEIGHT = 112; const int FACE_EMBEDDING_SIZE = 512; std::unique_ptr faiss_index; ANSCENTER::Options m_options; std::recursive_mutex _mutex; Engine m_trtEngine; float m_ratio = 1.0f; float m_imgWidth = 0.0f; float m_imgHeight = 0.0f; const std::array SUB_VALS{ 0.5f, 0.5f, 0.5f }; const std::array DIV_VALS{ 0.5f, 0.5f, 0.5f }; const bool NORMALIZE = true; }; // Using FastDeploy Enging to perform facial recognition // class ArcFace :public ANSFRBase { // public: // virtual bool Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) override; // virtual bool LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword)override; // bool OptimizeModel(bool fp16, std::string& optimizedModelFolder); // std::vector Feature(const cv::Mat& input, ANSCENTER::Object bBox); // Run inference and get embedding information from a cropped image // std::vector Match(const cv::Mat& input, std::vector bBox, std::mapuserDict); // Run inference and get embedding information from a cropped image (the first bbox) // cv::Mat GetCropFace(const cv::Mat& input, ANSCENTER::Object bBox); // void Init(); // void AddEmbedding(const std::string& className, float embedding[]); // void AddEmbedding(const std::string& className, const std::vector& embedding); // bool UpdateParamater(double knownPersonThreshold) { // _modelConfig.unknownPersonThreshold = knownPersonThreshold; // _modelConfig.unknownPersonThreshold = knownPersonThreshold; // m_knownPersonThresh = _modelConfig.unknownPersonThreshold; // return true; // } //~ArcFace(); // bool Destroy(); // private: // bool LoadEngine(const std::string engineFile, bool engineOptimisation = true); // std::vector> Forward(const cv::Mat& input, std::vector outputBbox); // std::tuple, std::vector> SearchForFaces(const std::vector>& detectedEmbeddings); //std::vector RunArcFace(const cv::Mat& input); // protected: // std::vector classNames; // ModelConfig _modelConfig; // std::string _modelFilePath; // float m_knownPersonThresh; // const int FACE_WIDTH = 112; // const int FACE_HEIGHT = 112; // const int FACE_EMBEDDING_SIZE = 512; // std::unique_ptr faiss_index; // Use shared_ptr // ANSCENTER::Options m_options; // std::recursive_mutex _mutex; // Engine m_trtEngine; // float m_ratio = 1; // float m_imgWidth = 0; // float m_imgHeight = 0; // const std::array SUB_VALS{ 0.5f, 0.5f, 0.5f }; // const std::array DIV_VALS{ 0.5f, 0.5f, 0.5f }; // const bool NORMALIZE = true; // }; } #endif