Files
DeepCamFaceSDK2.0/DeepCamFace/DeepCamFace.cpp
2024-12-13 23:33:37 +08:00

356 lines
9.4 KiB
C++

#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<FaceInfo>& face_infos);
void ResetFaceInfo();
cv::Mat GetFrame();
private:
FaceCache() {};
private:
static FaceCache* m_instance;
std::mutex m_mt;
std::vector<FaceInfo> 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<FaceInfo>& face_infos)
{
std::lock_guard<std::mutex> 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<std::mutex> lock(m_mt);
m_face_infos.clear();
m_frame = cv::Mat().clone();
}
int FaceCache::GetFaceRect(int index, float* face_rect)
{
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> lock(m_mt);
return m_frame;
}
#ifdef __cplusplus
extern "C" {
#endif
DEEPCAM_API_EXPORT int DeepCamFaceDetect(IN const cv::Mat& frame, OUT std::vector<FaceInfo>& 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<float> pose;
std::vector<float> 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<FaceInfo> 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<float> _feature(feature, feature + 512);
std::vector<unsigned char> _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