#include "Inc/DeepCamFaceApi.h" #include "Inc/CenterFaceMnn.h" #include "Inc/MobileFaceFeatureMnn.h" #include "Inc/LivenessRGB.h" #include "Inc/LivenessIRMnn.h" #include "Inc/FaceQuality.h" #include "Inc/Landmark68.h" #include "Inc/FaceDbMgr.h" class FaceCache { public: static FaceCache* GetInstance(); int GetFaceRect(int index, float* face_rect); int GetFaceLandmark(int index, float* landmark); void LoadFaceInfo(cv::Mat& frame, std::vector& face_infos); void ResetFaceInfo(); cv::Mat GetFrame(); private: FaceCache() {}; private: static FaceCache* m_instance; std::mutex m_mt; std::vector m_face_infos; cv::Mat m_frame; }; FaceCache* FaceCache::m_instance = nullptr; FaceCache* FaceCache::GetInstance() { if (m_instance == nullptr) { m_instance = new FaceCache; } return m_instance; } void FaceCache::LoadFaceInfo(cv::Mat& frame, std::vector& face_infos) { std::lock_guard lock(m_mt); m_face_infos.clear(); for (auto& obj : face_infos) { m_face_infos.push_back(std::move(obj)); //m_face_info.x1 = obj.x1; //m_face_info.x2 = obj.x1; //m_face_info.y1 = obj.y1; //m_face_info.y2 = obj.y2; //m_face_info.score = 0.f; //memcpy(m_face_info.landmarks, face_info.landmarks, 10 * sizeof(float)); } m_frame = frame.clone(); } void FaceCache::ResetFaceInfo() { std::lock_guard lock(m_mt); m_face_infos.clear(); m_frame = cv::Mat().clone(); } int FaceCache::GetFaceRect(int index, float* face_rect) { std::lock_guard lock(m_mt); if (index < m_face_infos.size()) { face_rect[0] = m_face_infos[index].x1; face_rect[1] = m_face_infos[index].y1; face_rect[2] = m_face_infos[index].x2; face_rect[3] = m_face_infos[index].y2; return ERR_OK; } else { memset(face_rect, 0.f, 4 * sizeof(float)); return ERR_INDEX_INVALID; } } int FaceCache::GetFaceLandmark(int index, float* landmark) { std::lock_guard lock(m_mt); if (index < m_face_infos.size()) { memcpy(landmark, m_face_infos[index].landmarks, 10 * sizeof(float)); return ERR_OK; } else { return ERR_INDEX_INVALID; } } cv::Mat FaceCache::GetFrame() { std::lock_guard lock(m_mt); return m_frame; } #ifdef __cplusplus extern "C" { #endif DEEPCAM_API_EXPORT int DeepCamFaceDetect(IN const cv::Mat& frame, OUT std::vector& faceList) { if (frame.empty()) { return ERR_IMG; } return CenterFaceMnn::GetInstance()->Detect(frame, faceList); } DEEPCAM_API_EXPORT int DeepCamGetFaceFeature(IN const cv::Mat& frame, IN const float* landmarks, OUT float* feature) { if (frame.empty()) { return ERR_IMG; } if (landmarks == nullptr) { return ERR_LANDMARK; } return MobileFaceFeatureMnn::GetInstance()->GetFaceFeature(frame, landmarks, feature); } DEEPCAM_API_EXPORT int DeepCamFaceFeatureCompare(IN const float* feature1, IN const float* feature2, OUT float & fSimilarity) { fSimilarity = 0.f; if (feature1 == nullptr || feature2 == nullptr) { return ERR_FEATURE; } float tmp0 = 0, tmp1 = 0, tmp2 = 0; for (int i = 0; i < 512; i++) { tmp0 += feature1[i] * feature2[i]; tmp1 += feature1[i] * feature1[i]; tmp2 += feature2[i] * feature2[i]; } float score = (float(tmp0 / (sqrt(tmp1)* sqrt(tmp2)))); //拉高分数 float max_score = log10f(1.01); float min_score = log10f(0.02); float ret, temp; if (score <= 0) { temp = fabs(score); if (temp > 0.3) { ret = 0.0001; } else { ret = temp; } } else { temp = log10f(score + 0.01); fSimilarity = fabsf(temp - min_score) / (max_score - min_score); } return ERR_OK; } DEEPCAM_API_EXPORT int DeepCamFaceLivenessRgb(IN const cv::Mat& frame, IN const float* landmarks, OUT float& livenessScore) { if (frame.empty()) { return ERR_IMG; } if (landmarks == nullptr) { return ERR_LANDMARK; } livenessScore = LivenessRGB::GetInstance()->LivenessDetect(frame, landmarks); return ERR_OK; } DEEPCAM_API_EXPORT int DeepCamFaceLivenesIr(IN const cv::Mat& frame, IN float face_x1, IN float face_y1, IN float face_x2, IN float face_y2, IN const float* landmarks, OUT float& livenessScore) { livenessScore = 0.f; if (frame.empty()) { return ERR_IMG; } if (landmarks == nullptr) { return ERR_LANDMARK; } return LivenessIRMnn::GetInstance()->LivenessDetect(frame, face_x1, face_y1, face_x2, face_y2, landmarks, livenessScore, true); } DEEPCAM_API_EXPORT int DeepCamGetFaceQuality(IN const cv::Mat& frame, IN float face_x1, IN float face_y1, IN float face_x2, IN float face_y2, OUT float& score) { if (frame.empty()) { return ERR_IMG; } score = FaceQuality::GetInstance()->DetectQuality(frame, cv::Rect(face_x1, face_y1, face_x2 - face_x1, face_y2 - face_y1)); return ERR_OK; } DEEPCAM_API_EXPORT int DeepCamGetFaceLandmarks68(IN const cv::Mat& frame, IN float face_x1, IN float face_y1, IN float face_x2, IN float face_y2, OUT float* landmark68) { std::vector pose; std::vector landmark; int ret = Landmark68::GetInstance()->Detect(frame, face_x1, face_y1, face_x2, face_y2, pose, landmark); if (ret != ERR_OK || landmark.size() != 136) { memset(landmark68, 0, 136 * sizeof(float)); return ret; } memcpy(landmark68, landmark.data(), sizeof(float) * 136); return ERR_OK; } /**********************************人脸通用接口************************************/ DEEPCAM_API_EXPORT int DeepCamFaceDetectStd(IN unsigned char * data, IN int width, IN int height, IN int pixelType) { if (data == NULL || width < 1 || height < 1 || (pixelType != PIXEL_BGR &&pixelType != PIXEL_RGB)) { return ERR_IMG; } cv::Mat tempMat(height, width, CV_8UC(3), (void *)data); if (tempMat.empty() || !tempMat.data) { return ERR_IMG; } std::vector face_infos; int ret = DeepCamFaceDetect(tempMat, face_infos); if (face_infos.size() > 0) { FaceCache::GetInstance()->LoadFaceInfo(tempMat, face_infos); } return ret; } DEEPCAM_API_EXPORT int DeepCamGetFaceRectStd(IN int index, OUT float* face_rect) { return FaceCache::GetInstance()->GetFaceRect(index, face_rect); } DEEPCAM_API_EXPORT int DeepCamGetFaceLandmarkStd(IN int index, OUT float* landmark) { return FaceCache::GetInstance()->GetFaceLandmark(index, landmark); } DEEPCAM_API_EXPORT int DeepCamGetFaceQualityStd(IN int index, OUT float& score) { float face_rect[4] = { 0.f }; int ret = FaceCache::GetInstance()->GetFaceRect(index, face_rect); if (ret != ERR_OK) { return ret; } return DeepCamGetFaceQuality(FaceCache::GetInstance()->GetFrame(), face_rect[0], face_rect[1], face_rect[2], face_rect[3], score); } DEEPCAM_API_EXPORT int DeepCamGetFaceFeatureStd(IN int index, OUT float* feature) { float landmark[10] = { 0 }; int ret = FaceCache::GetInstance()->GetFaceLandmark(index, landmark); if (ret != ERR_OK) { return ret; } return DeepCamGetFaceFeature(FaceCache::GetInstance()->GetFrame(), landmark, feature); } DEEPCAM_API_EXPORT int DeepCamFaceFeatureCompareStd(const float* feature1, const float* feature2, float & fSimilarity) { return DeepCamFaceFeatureCompare(feature1, feature2, fSimilarity); } DEEPCAM_API_EXPORT int DeepCamFaceLivenessRgbStd(IN int index, OUT float& score) { float landmark[10] = { 0 }; int ret = FaceCache::GetInstance()->GetFaceLandmark(index, landmark); if (ret != ERR_OK) { return ret; } return DeepCamFaceLivenessRgb(FaceCache::GetInstance()->GetFrame(), landmark, score); } DEEPCAM_API_EXPORT int DeepCamFaceLivenesIrStd(IN int index, OUT float& score) { float landmark[10] = { 0 }; float face_rect[4] = { 0 }; int ret = FaceCache::GetInstance()->GetFaceLandmark(index, landmark); if (ret != ERR_OK) { return ret; } ret = FaceCache::GetInstance()->GetFaceRect(index, face_rect); if (ret != ERR_OK) { return ret; } return DeepCamFaceLivenesIr(FaceCache::GetInstance()->GetFrame(), face_rect[0], face_rect[1], face_rect[2], face_rect[3],landmark, score); } DEEPCAM_API_EXPORT int DeepCamGetFaceLandmark68Std(IN int index, OUT float* landmark68) { float face_rect[4] = { 0 }; int ret = FaceCache::GetInstance()->GetFaceRect(index, face_rect); if (ret != ERR_OK) { memset(landmark68, 0, sizeof(float) * 136); return ret; } return DeepCamGetFaceLandmarks68(FaceCache::GetInstance()->GetFrame(), face_rect[0], face_rect[1], face_rect[2], face_rect[3], landmark68); } /**********************************人脸库管理接口************************************/ DEEPCAM_API_EXPORT int DeepCamEnterFace(IN const char* name, IN const char* vid, IN const char* group_name, IN const float* feature, IN const unsigned char* img_data, IN int img_data_len) { std::vector _feature(feature, feature + 512); std::vector _img_data(img_data, img_data + img_data_len); return FaceDbMgr::GetInstance()->EnterFace(_feature, std::string(name), std::string(vid), std::string(group_name), _img_data); } //DEEPCAM_API_EXPORT int DeepCamFaceSearch(IN const float* feature, IN const char* group_name, OUT char* name, OUT char* vid, // OUT const uint8_t* img_data, OUT float& fSimilarity, float fThreshold = 0.8) //{ //} //DEEPCAM_API_EXPORT int DeepCamDeleteFaceByName(IN const char* name, IN const char* group_name); //DEEPCAM_API_EXPORT int DeepCamDeleteAllFace(IN const char* group_name); //DEEPCAM_API_EXPORT int DeepCamAddFaceGroup(IN const char* group_name, IN const char* remarks); //DEEPCAM_API_EXPORT int DeepCamDeleteFaceGroup(IN const char* group_name); #ifdef __cplusplus } //end extern "C" #endif