134 lines
5.7 KiB
C
134 lines
5.7 KiB
C
|
|
#ifndef ARCFACERT_H
|
||
|
|
#define ARCFACERT_H
|
||
|
|
#pragma once
|
||
|
|
#include "ANSFRCommon.h"
|
||
|
|
//#include "fastdeploy/vision.h"
|
||
|
|
#include "hnswlib/hnswlib.h"
|
||
|
|
#include <faiss/IndexFlat.h>
|
||
|
|
#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<float> Feature(const cv::Mat& image, const ANSCENTER::Object& bBox);
|
||
|
|
|
||
|
|
// Main entry: run recognition for all faces in bBox
|
||
|
|
std::vector<FaceResultObject> Match(const cv::Mat& input,
|
||
|
|
const std::vector<ANSCENTER::Object>& bBox,
|
||
|
|
const std::map<std::string, std::string>& 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<float>& 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<std::vector<float>> Forward(const cv::Mat& input,
|
||
|
|
const std::vector<ANSCENTER::Object>& outputBbox);
|
||
|
|
|
||
|
|
// Search embeddings in FAISS index
|
||
|
|
std::tuple<std::vector<std::string>, std::vector<float>>
|
||
|
|
SearchForFaces(const std::vector<std::vector<float>>& detectedEmbeddings);
|
||
|
|
|
||
|
|
// Single-face inference (kept for Feature)
|
||
|
|
std::vector<float> RunArcFace(const cv::Mat& input);
|
||
|
|
|
||
|
|
// New: batched inference helper
|
||
|
|
std::vector<std::vector<float>> RunArcFaceBatch(const std::vector<cv::Mat>& faceROIs);
|
||
|
|
|
||
|
|
protected:
|
||
|
|
std::vector<std::string> 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::IndexFlatL2> faiss_index;
|
||
|
|
ANSCENTER::Options m_options;
|
||
|
|
std::recursive_mutex _mutex;
|
||
|
|
Engine<float> m_trtEngine;
|
||
|
|
|
||
|
|
float m_ratio = 1.0f;
|
||
|
|
float m_imgWidth = 0.0f;
|
||
|
|
float m_imgHeight = 0.0f;
|
||
|
|
|
||
|
|
const std::array<float, 3> SUB_VALS{ 0.5f, 0.5f, 0.5f };
|
||
|
|
const std::array<float, 3> 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<float> Feature(const cv::Mat& input, ANSCENTER::Object bBox); // Run inference and get embedding information from a cropped image
|
||
|
|
// std::vector<FaceResultObject> Match(const cv::Mat& input, std::vector<ANSCENTER::Object> bBox, std::map<std::string, std::string>userDict); // 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<float>& 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<std::vector<float>> Forward(const cv::Mat& input, std::vector<ANSCENTER::Object> outputBbox);
|
||
|
|
// std::tuple<std::vector<std::string>, std::vector<float>> SearchForFaces(const std::vector<std::vector<float>>& detectedEmbeddings);
|
||
|
|
//std::vector<float> RunArcFace(const cv::Mat& input);
|
||
|
|
// protected:
|
||
|
|
// std::vector<std::string> 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::IndexFlatL2> faiss_index; // Use shared_ptr
|
||
|
|
// ANSCENTER::Options m_options;
|
||
|
|
// std::recursive_mutex _mutex;
|
||
|
|
// Engine<float> m_trtEngine;
|
||
|
|
// float m_ratio = 1;
|
||
|
|
// float m_imgWidth = 0;
|
||
|
|
// float m_imgHeight = 0;
|
||
|
|
// const std::array<float, 3> SUB_VALS{ 0.5f, 0.5f, 0.5f };
|
||
|
|
// const std::array<float, 3> DIV_VALS{ 0.5f, 0.5f, 0.5f };
|
||
|
|
// const bool NORMALIZE = true;
|
||
|
|
// };
|
||
|
|
}
|
||
|
|
#endif
|