#ifndef ANSFRCOMMON_H #define ANSFRCOMMON_H #define ANSF_API __declspec(dllexport) #pragma once #include #include #include #include #include #include #include "NvInfer.h" //#include #include "ANSLicense.h" #include "LabVIEWHeader/extcode.h" #include "Utility.h" #include "macros.h" #include "ANSEngineCommon.h" #include "openvino/openvino.hpp" using namespace nvinfer1; #define CUDACHECK(status) \ do\ {\ auto ret = (status);\ if (ret != 0)\ {\ std::cerr << "Cuda failure: " << ret << std::endl;\ abort();\ }\ } while (0) namespace ANSCENTER { struct UserRecord { int UserId; std::string UserCode; std::string UserName; std::vector FaceIds; }; struct FaceRecord { int FaceId; int UserId; std::string ImagePath; }; struct alignas(float) Detection { float bbox[4]; //x1 y1 x2 y2 float class_confidence; float landmark[10]; }; struct CroppedFace { cv::Mat face; cv::Mat faceMat; int x1, y1, x2, y2; }; struct Bbox { int x1, y1, x2, y2; float score; }; struct Paths { std::string absPath; std::string className; }; struct AnchorBox { float cx; float cy; float sx; float sy; }; struct FRConfig { std::string _databasePath; int _videoFrameWidth; int _videoFrameHeight; std::string _detEngineFile; std::vector _detInputShape; std::string _detInputName; std::vector _detOutputNames; int _detMaxBatchSize; float _detThresholdNMS; float _detThresholdBbox; std::vector _recInputShape; int _recOutputDim; std::string _recEngineFile; int _maxFacesPerScene; float _knownPersonThreshold; int _recMaxBatchSize; std::string _recInputName; std::string _recOutputName; bool _gen; std::string _gen_imgSource; bool _gen_imgIsCropped; bool _apiImageIsCropped; }; struct HeadPoseResults { float angle_r; float angle_p; float angle_y; }; struct AgeGenderResults { float age; float maleProb; }; //// Class for face attribute class ANSF_API Face { public: //using Ptr = std::shared_ptr; explicit Face(size_t id, cv::Rect& location); void updateAge(float value); void updateGender(float value); void updateEmotions(std::map values); void updateHeadPose(HeadPoseResults values); void updateLandmarks(std::vector values); void updateRealFaceConfidence(float value); void updateFaceLiveness(int value); int getAge(); bool isMale(); bool isReal(); float getAntispoofingScore(); int getFaceLiveness(); std::map getEmotions(); std::pair getMainEmotion(); HeadPoseResults getHeadPose(); const std::vector& getLandmarks(); size_t getId(); void ageGenderEnable(bool value); void emotionsEnable(bool value); void headPoseEnable(bool value); void landmarksEnable(bool value); void antispoofingEnable(bool value); void faceLivenessEnable(bool value); bool isAgeGenderEnabled(); bool isEmotionsEnabled(); bool isHeadPoseEnabled(); bool isLandmarksEnabled(); bool isAntispoofingEnabled(); bool isFaceLivenessEnabled(); public: cv::Rect _location; float _intensity_mean; private: size_t _id; float _age; float _maleScore; float _femaleScore; std::map _emotions; HeadPoseResults _headPose; std::vector _landmarks; float _realFaceConfidence; int _faceLiveness; bool _isAgeGenderEnabled; bool _isEmotionsEnabled; bool _isHeadPoseEnabled; bool _isLandmarksEnabled; bool _isAntispoofingEnabled; bool _isFaceLivenessEnabled; }; class ANSF_API BaseDetection { public: BaseDetection(const std::string& pathToModel, bool doRawOutputMessages); virtual ~BaseDetection() = default; virtual std::shared_ptr read(const ov::Core& core) = 0; bool enabled() const; ov::InferRequest request; ov::Tensor inTensor; std::string pathToModel; ov::Shape inShape; const bool doRawOutputMessages; }; class ANSF_API HeadPoseDetection :public BaseDetection { public: std::recursive_mutex _mutex; std::string outputAngleR; std::string outputAngleP; std::string outputAngleY; std::string _modelFilePath; //size_t enquedFaces; cv::Mat cameraMatrix; HeadPoseDetection(const std::string& pathToModel, bool doRawOutputMessages); virtual std::shared_ptr read(const ov::Core& core) override; HeadPoseResults runInfer(const cv::Mat& frame); //void submitRequest(); //void enqueue(const cv::Mat& face); //HeadPoseResults getResult(int idx); //std::vector getAllResults(); }; class ANSF_API AgeGenderDetection :public BaseDetection { public: std::recursive_mutex _mutex; std::string outputAge; std::string outputGender; //size_t enquedFaces; std::string _modelFilePath; AgeGenderDetection(const std::string& pathToModel, bool doRawOutputMessages); virtual std::shared_ptr read(const ov::Core& core) override; AgeGenderResults runInfer(const cv::Mat& frame); //void submitRequest(); //void enqueue(const cv::Mat& face); //AgeGenderResults getResult(int idx); //std::vector getAllResults(); }; class ANSF_API EmotionsDetection : public BaseDetection { public: std::recursive_mutex _mutex; //size_t enquedFaces; std::string _modelFilePath; const std::vector emotionsVec = { "neutral", "happy", "sad", "surprise", "anger" }; EmotionsDetection(const std::string& pathToModel, bool doRawOutputMessages); virtual std::shared_ptr read(const ov::Core& core) override; std::map runInfer(const cv::Mat& frame); //void submitRequest(); //void enqueue(const cv::Mat& face); //std::map getResult(int idx); //std::vector> getAllResults(); }; class FacialLandmarksDetection : public BaseDetection { public: //size_t enquedFaces; std::vector> landmarks_results; std::vector faces_bounding_boxes; std::string _modelFilePath; std::recursive_mutex _mutex; FacialLandmarksDetection(const std::string& pathToModel, bool doRawOutputMessages); virtual std::shared_ptr read(const ov::Core& core) override; std::vector runInfer(const cv::Mat& frame); //void submitRequest(); //void enqueue(const cv::Mat& face); //std::vector getResult(int idx); }; class ANSF_API AntispoofingClassifier : public BaseDetection { public: std::recursive_mutex _mutex; //size_t enquedFaces; std::string _modelFilePath; AntispoofingClassifier(const std::string& pathToModel,bool doRawOutputMessages); virtual std::shared_ptr read(const ov::Core& core) override; float runInfer(const cv::Mat& frame); //void submitRequest(); //void enqueue(const cv::Mat& frame); //float getResult(int idx); }; class ANSFRHelper { public: static unsigned char* CVMatToBytes(cv::Mat image, unsigned int& bufferLengh); static void GetCroppedFaces(const cv::Mat& input, std::vector& outputBbox, int resize_w, int resize_h, std::vector& croppedFaces); static void GetFilePaths(std::string rootPath, std::vector& paths); static bool LoadConfigFile(std::string configFile, FRConfig& config); static std::string StringCurrentDateTime(); // Return current datetime in string format static std::string FaceObjectsToJsonString(const std::vector& faces); static cv::Mat PreprocessImg(cv::Mat& img, int inputW, int inputH); static int ReadFilesInDir(const char* pDirName, std::vector& fileNames); static cv::Rect GetRectAdaptLandmark(cv::Mat& img, int inputW, int inputH, float bBox[4], float lmk[10]); static float IOU(float lbox[4], float rbox[4]); static bool CMP(const Detection& a, const Detection& b); static void NMS(std::vector& res, float* output, float nms_thresh = 0.4); static std::map LoadWeights(const std::string file); static Weights GetWeights(std::map& weightMap, std::string key); static IScaleLayer* AddBatchNorm2D(INetworkDefinition* network, std::map& weightMap, ITensor& input, std::string lName, float eps); static std::string UserRecordToJsonString(const UserRecord userRecord); static std::string UserRecordsToJsonString(const std::vector userRecords); static std::string FaceRecordToJsonString(const FaceRecord faceRecord); static std::string FaceRecordsToJsonString(const std::vector faceRecords); static std::string FaceAttributeToJsonString(Face face); }; float calcIoU(cv::Rect& src, cv::Rect& dst); float calcMean(const cv::Mat& src); Face matchFace(cv::Rect rect, std::list& faces); // Class to extend TensorRT logger /* class TRTLogger : public nvinfer1::ILogger { public: void log(Severity severity, const char* msg) noexcept override { if (severity <= Severity::kWARNING) { std::cout << "TENSORRT_ENGINE:" << msg << std::endl; } } void LogDebug(const std::string source, std::string message) { std::cout << source << ":" << message << std::endl; } void LogInfo(const std::string source, std::string message) { std::cout << source << ":" << message << std::endl; } void LogError(const std::string source, std::string message) { std::cout << source << ":" << message << std::endl; } void LogFatal(const std::string source, std::string message) { std::cout << source << ":" << message << std::endl; } ~TRTLogger() { } }; class MatMul { public: MatMul(); ~MatMul(); void Init(float* knownEmbeds, int numRow, int numCol); void Calculate(float* embeds, int embedCount, float* outputs); private: cudaDataType_t cudaDataType = CUDA_R_32F; cublasComputeType_t computeType = CUBLAS_COMPUTE_32F; cublasLtHandle_t ltHandle; cublasOperation_t transa = CUBLAS_OP_T; cublasOperation_t transb = CUBLAS_OP_N; void* workspace; const size_t workspaceSize = 1024 * 1024 * 4; cudaStream_t stream; float* dA, * dB, * dC; const float alpha = 1, beta = 0; int m, n, k, lda, ldb, ldc; cublasLtMatmulDesc_t operationDesc = NULL; cublasLtMatrixLayout_t Adesc = NULL; cublasLtMatmulPreference_t preference = NULL; }; class Int8EntropyCalibrator2 : public nvinfer1::IInt8EntropyCalibrator2 { public: Int8EntropyCalibrator2(int batchsize, int input_w, int input_h, const char* img_dir, const char* calib_table_name, const char* input_blob_name, bool read_cache = true); virtual ~Int8EntropyCalibrator2(); int getBatchSize() const TRT_NOEXCEPT override; bool getBatch(void* bindings[], const char* names[], int nbBindings) TRT_NOEXCEPT override; const void* readCalibrationCache(size_t& length) TRT_NOEXCEPT override; void writeCalibrationCache(const void* cache, size_t length) TRT_NOEXCEPT override; private: int batchsize_; int input_w_; int input_h_; int img_idx_; std::string img_dir_; std::vector img_files_; size_t input_count_; std::string calib_table_name_; const char* input_blob_name_; bool read_cache_; void* device_input_; std::vector calib_cache_; };*/ } #endif