//#include #include #include #include #include "Inc/FaceDbMgr.h" #define SEARCH_FACE_THRESHOLD 0.8 //A similarity threshold for default match #define SAME_FACE_THRESHOLD 0.7 //A similarity threshold for entering the same person #define FEATURE_NAME_MAX_LEN 64 //Max lenght for entering name //创建人脸数据表 ID Feature Name VID Image GroupID EnterTime #define FS_DB_CREATE_TABLE "CREATE TABLE table_features(ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,Feature blob NOT NULL,Name VARCHAR(64) NOT NULL,VID VARCHAR(64),Image blob NOT NULL,GroupID INTEGER NOT NULL,EnterTime datetime default(datetime('now','localtime')));" //检查人脸数据表是否存在 #define FS_DB_CHECK_TABLE_EXIST "select count(*) from sqlite_master where type='table' and name = 'table_features';" //给人脸数据表 ID字段加上索引 #define FS_DB_CREATE_ID_INDEX "CREATE UNIQUE INDEX id_index ON table_features(ID);" //检查人脸数据表 ID字段是否有索引 #define FS_DB_CHECK_ID_INDEX_EXIST "select count(*) from sqlite_master where type='index' and name = 'id_index';" //给人脸数据表 NAME字段加上索引 #define FS_DB_CREATE_NAME_INDEX "CREATE INDEX name_index ON table_features(Name);" //检查人脸数据表 NAME字段是否有索引 #define FS_DB_CHECK_NAME_INDEX_EXIST "select count(*) from sqlite_master where type='index' and name = 'name_index';" //查询人数据表 人脸特征总数 #define FS_DB_QUERY_FEATURES_SIZE "select count(*) from table_features;" //查询分组下面的人脸特征总数 #define FS_DB_QUERY_GROUP_FEATURES_SIZE "select count(*) from table_features where GroupID=?;" //添加人脸数据 #define FS_DB_INSERT_FEATURE_DATA "insert into table_features(Feature,Name,VID,Image,GroupID) values(?,?,?,?,?)" #define FS_DB_CLEAR_TABLE_SEQUENCE "UPDATE sqlite_sequence SET seq = 0 WHERE name='table_features';" //通过名字删除人脸 #define FS_DB_DELETE_FEATURE_BY_NAME "delete from table_features where Name=? and GroupID=?;" //The '?' in string can't be quoted with '',or it can't not be parsed by 'sqlite3_prepare' //删除分组下面的所有人脸数据 #define FS_DB_DELETE_FEATURE_BY_GROUP "delete from table_features where GroupID=?;" //查询所有人脸数据 #define FS_DB_QUERY_FEATURES_INFO "SELECT * FROM table_features;" //通过Group Id 查询人脸数据 #define FS_DB_QUERY_FEATURES_INFO_BY_GROPU "SELECT * FROM table_features WHERE GroupID=?;" //通过名字查询人脸数据 #define FS_DB_QUERY_FEATURES_INFO_BY_NAME "SELECT * FROM table_features WHERE NAME=? AND GroupID=?;" //通过名字和组ID查询图片 #define FS_DB_QUERY_IMG_BY_NAME "SELECT Image FROM table_features WHERE NAME=? AND GroupID=?;" #define FACEFEATURES_DEFAULT_SIZE 2000 //A default increase size //分组表sql //创建人脸分组索引表 #define FS_DB_CREATE_GROUP_TABLE "CREATE TABLE table_group(ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,Name VARCHAR(64) NOT NULL, Remarks VARCHAR(512),EnterTime datetime default(datetime('now','localtime')));" //检查分组表是否存在 #define FS_DB_CHECK_GROUP_TABLE_EXIST "select count(*) from sqlite_master where type='table' and name = 'table_group';" //给分组表添加名称索引 #define FS_DB_GROUP_CREATE_ID_INDEX "CREATE UNIQUE INDEX group_name_index ON table_group(Name);" //查询分组总数 #define FS_DB_QUERY_GROUP_SIZE "select count(*) from table_group;" //通过名字查询分组ID #define FS_DB_QUERY_GROUP_ID_BY_NAME "select ID from table_group where Name=?;" //通过名字查询分组信息 #define FS_DB_QUERY_GROUP_BY_NAME "select * from table_group where Name=?;" //通过ID查询分组信息 #define FS_DB_QUERY_GROUP_BY_ID "select * from table_group where ID=?;" //查询分组数据 #define FS_DB_QUERY_GROUP_DATA "select * from table_group;" //通过名字删除分组表 #define FS_DB_DELETE_GROUP_BY_NAME "delete from table_group where Name=?;" //插入一条分组数据 #define FS_DB_INSTER_GROUP_DATA "insert into table_group(Name,Remarks) values(?,?)" FaceDbMgr* FaceDbMgr::m_instance = nullptr; std::vector FaceDbMgr::m_groups; std::map> FaceDbMgr::m_GroupDb; static int _callback_exec(void * notused, int argc, char ** argv, char ** aszColName) { return 0; } /******************************************************************/ float FaceDbMgr::FeatureCompare(const float* feature1, const float* feature2) { 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)))); //return score; //拉高分数 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); ret = fabsf(temp - min_score) / (max_score - min_score); } return ret; } /******************************************************************/ FaceDbMgr* FaceDbMgr::GetInstance() { if (m_instance == nullptr) { m_instance = new FaceDbMgr(); } return m_instance; } FaceDbMgr::FaceDbMgr(char * pcDbName) { /******************初始化错误映射表**********************/ //m_err_info[DB_ERR_SQL] = UnicodeToUtf8(L"数据库引擎内部SQL脚本错误"); //m_err_info[DB_ERR_BIND_SQL_DATA] = UnicodeToUtf8(L"数据库引擎内部绑定SQL参数错误"); //m_err_info[DB_ERR_SQL_EXE] = UnicodeToUtf8(L"数据库引擎内部执行SQL错误"); //m_err_info[DB_ERR_FEATURE_LEN] = UnicodeToUtf8(L"人脸特征长度错误"); //m_err_info[DB_ERR_NAME_FEATURE_EXIST] = UnicodeToUtf8(L"当前名字已经被注册"); //m_err_info[DB_ERR_GROUP_FEATURE_FULL] = UnicodeToUtf8(L"当前分组下的人脸注册数量已经达到上限"); //m_err_info[DB_ERR_GROUP_FULL] = UnicodeToUtf8(L"当前分组数量已经达到上限,无法创建新的分组"); //m_err_info[DB_ERR_ADD_FACE_FEATURE] = UnicodeToUtf8(L"录入人脸特征失败"); //m_err_info[DB_ERR_NON_GROUP] = UnicodeToUtf8(L"输入的分组名称不存在"); //m_err_info[DB_ERR_GROUP_REPEAT] = UnicodeToUtf8(L"当前分组名称已经被使用"); //m_err_info[DB_ERR_ADD_GROUP] = UnicodeToUtf8(L"添加分组失败"); //m_err_info[DB_ERR_NO_INIT] = UnicodeToUtf8(L"数据库引擎未初始化"); //m_err_info[DB_ERR_NO_DATA] = UnicodeToUtf8(L"未查询到数据"); //m_err_info[DB_ERR_OK] = UnicodeToUtf8(L"无错误"); /******************************************************/ m_bDbInit = false; m_db = NULL; std::string tempDbPath = std::string(std::experimental::filesystem::current_path().generic_string()) + std::string("/FaceDb/"); if (!std::experimental::filesystem::exists(std::experimental::filesystem::path(tempDbPath))) { std::experimental::filesystem::create_directory(std::experimental::filesystem::path(tempDbPath)); } tempDbPath.append(pcDbName); int res = 0; res = sqlite3_open(tempDbPath.c_str(), &m_db); if (res != SQLITE_OK) { std::cout << "Open DB " << tempDbPath.c_str() << "Failed. ErrCode is :" << res << std::endl; return; } m_bDbInit = true; //查询分组索引表是否存在 if (QueryTableSize(FS_DB_CHECK_GROUP_TABLE_EXIST) < 1) { //创建分组索引表 FeatureDBMgrExec(FS_DB_CREATE_GROUP_TABLE); FeatureDBMgrExec(FS_DB_GROUP_CREATE_ID_INDEX); } if (QueryTableSize(FS_DB_CHECK_TABLE_EXIST) < 1) { //创建人脸数据表 FeatureDBMgrExec(FS_DB_CREATE_TABLE); if (QueryTableSize(FS_DB_CHECK_NAME_INDEX_EXIST) < 1) {//创建名字索引 res = FeatureDBMgrExec(FS_DB_CREATE_NAME_INDEX); if (res != SQLITE_OK) { std::cout << "Create name_index Failed ...ErrCode:" << res << std::endl; return; } res = FeatureDBMgrExec(FS_DB_CREATE_ID_INDEX); if (res != SQLITE_OK) { std::cout << "Create id_index Failed ...ErrCode:" << res << std::endl; return; } } } std::cout << "Face DB Init Ok! " << std::endl; {//加载人脸数据到内存 int group_num = QueryTableSize(FS_DB_QUERY_GROUP_SIZE); if (group_num < 1) return; //没有分组,数据库没有人脸数据 QueryGroupDatas(m_groups); std::cout << "group num: "<< m_groups.size() << std::endl; for (auto& obj: m_groups) { std::vector face_objs; QueryFeatrueByGroup(obj, face_objs); m_GroupDb[obj.group_id] = face_objs; std::cout << "load group " << obj.group_name << ",face num: " << face_objs.size() << std::endl; } std::cout << "load data ok!" << std::endl; } } FaceDbMgr::~FaceDbMgr() { if (m_db) { int res = sqlite3_close(m_db); if (res == SQLITE_OK) { m_db = NULL; } else { std::cout << "Close DB Failed. ErrCode is : " << res << std::endl; } } } bool FaceDbMgr::IsDbInit() { return m_bDbInit; } int FaceDbMgr::FeatureDBMgrExec(const char * strSql) { if (!m_bDbInit) { return -1;//DB must be initialized } char * pErrMsg = NULL; int res = sqlite3_exec(m_db, strSql, _callback_exec, 0, &pErrMsg); return res; } /***************************************************************/ /* 查询数据数量 */ int FaceDbMgr::QueryTableSize(const char * strSql) { if (!m_bDbInit || strSql == NULL) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, strSql, strlen(strSql), &pstmt, 0); if (ret != SQLITE_OK) { return 0; } AutoDeleteStmt ads(pstmt);//这里不清理干净会导致数据库关闭时返回错误码SQLITE_BUSY ret = sqlite3_step(pstmt); if (ret != SQLITE_ROW) { return 0; } int countNum = sqlite3_column_int(pstmt, 0); return countNum; } /* 通过名字查询查询数据数量 */ int FaceDbMgr::QueryTableSizeByName(const char * strSql, const char * strPersonName) { if (!IsDbInit()) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, strSql, strlen(strSql), &pstmt, 0); if (ret != SQLITE_OK) { return DB_ERR_SQL; } AutoDeleteStmt ads(pstmt);//这里不清理干净会导致数据库关闭时返回错误码SQLITE_BUSY ret = sqlite3_bind_text(pstmt, 1, strPersonName, strnlen_s(strPersonName, 64), NULL); if (ret != SQLITE_OK) { return DB_ERR_BIND_SQL_DATA; } ret = sqlite3_step(pstmt); if (ret != SQLITE_ROW) { return DB_ERR_SQL_EXE; } int countNum = sqlite3_column_int(pstmt, 0); return countNum; } /* 查询所有的人脸特征数量*/ int FaceDbMgr::QueryAllFeatureSize() { if (!IsDbInit()) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, FS_DB_QUERY_FEATURES_SIZE, strlen(FS_DB_QUERY_FEATURES_SIZE), &pstmt, 0); if (ret != SQLITE_OK) return DB_ERR_SQL; AutoDeleteStmt ads(pstmt);//这里不清理干净会导致数据库关闭时返回错误码SQLITE_BUSY ret = sqlite3_step(pstmt); if (ret != SQLITE_ROW) return DB_ERR_SQL_EXE; return sqlite3_column_int(pstmt, 0); } /* 查询分组内所有的人脸特征数量 */ int FaceDbMgr::QueryGroupAllFeatureSize(int group_id) { if (!IsDbInit()) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, FS_DB_QUERY_GROUP_FEATURES_SIZE, strlen(FS_DB_QUERY_GROUP_FEATURES_SIZE), &pstmt, 0); if (ret != SQLITE_OK) return DB_ERR_SQL; ret = sqlite3_bind_int(pstmt, 1, group_id); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; AutoDeleteStmt ads(pstmt);//这里不清理干净会导致数据库关闭时返回错误码SQLITE_BUSY ret = sqlite3_step(pstmt); if (ret != SQLITE_ROW) { if (ret != SQLITE_DONE) { return DB_ERR_SQL_EXE; } return DB_ERR_NO_DATA; } int num = sqlite3_column_int(pstmt, 0); return num; } //通过组名查询组内注册人脸特征数量 int FaceDbMgr::QueryNameFeatureInGroupSize(std::string groupName, std::string faceName) { if (!IsDbInit()) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, FS_DB_QUERY_GROUP_FEATURES_SIZE, strlen(FS_DB_QUERY_GROUP_FEATURES_SIZE), &pstmt, 0); if (ret != SQLITE_OK) return DB_ERR_SQL; ret = sqlite3_bind_text(pstmt, 1, groupName.c_str(), groupName.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_bind_text(pstmt, 2, faceName.c_str(), faceName.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; AutoDeleteStmt ads(pstmt);//这里不清理干净会导致数据库关闭时返回错误码SQLITE_BUSY ret = sqlite3_step(pstmt); if (ret != SQLITE_ROW) { if (ret == SQLITE_DONE) { return DB_ERR_NO_DATA; } return DB_ERR_SQL_EXE; } int feature_num = sqlite3_column_int(pstmt, 0); return feature_num; } //查询所有分组数量 int FaceDbMgr::QueryAllGroupSize() { if (!IsDbInit()) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, FS_DB_QUERY_GROUP_SIZE, strlen(FS_DB_QUERY_GROUP_SIZE), &pstmt, 0); if (ret != SQLITE_OK) return DB_ERR_SQL; ret = sqlite3_step(pstmt); AutoDeleteStmt ads(pstmt);//这里不清理干净会导致数据库关闭时返回错误码SQLITE_BUSY if (ret != SQLITE_ROW) { if (ret == SQLITE_DONE) { return DB_ERR_NO_DATA; } return DB_ERR_SQL_EXE; } return sqlite3_column_int(pstmt, 0); } //通过组名字查询组ID int FaceDbMgr::QueryGroupIdByName(std::string groupName) { if (!IsDbInit()) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, FS_DB_QUERY_GROUP_ID_BY_NAME, strlen(FS_DB_QUERY_GROUP_ID_BY_NAME), &pstmt, 0); if (ret != SQLITE_OK) return DB_ERR_SQL; ret = sqlite3_bind_text(pstmt, 1, groupName.c_str(), groupName.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_step(pstmt); AutoDeleteStmt ads(pstmt);//这里不清理干净会导致数据库关闭时返回错误码SQLITE_BUSY if (ret != SQLITE_ROW) { if (ret == SQLITE_DONE) { return DB_ERR_NO_DATA; } return DB_ERR_SQL_EXE; } int group_id = sqlite3_column_int(pstmt, 0); return group_id; } int FaceDbMgr::QueryGroupByName(std::string groupName, std::vector& objs) { if (!IsDbInit()) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, FS_DB_QUERY_GROUP_BY_NAME, strlen(FS_DB_QUERY_GROUP_BY_NAME), &pstmt, 0); AutoDeleteStmt ads(pstmt); if (ret != SQLITE_OK) return DB_ERR_SQL; ret = sqlite3_bind_text(pstmt, 1, groupName.c_str(), groupName.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; while (sqlite3_step(pstmt) == SQLITE_ROW) { DB_GROUP_OBJ obj; obj.group_id = sqlite3_column_int(pstmt, 0); obj.group_name = std::string((const char*)sqlite3_column_text(pstmt, 1), sqlite3_column_bytes(pstmt, 1)); obj.remarks = std::string((const char*)sqlite3_column_text(pstmt, 2), sqlite3_column_bytes(pstmt, 2)); obj.remarks = std::string((const char*)sqlite3_column_text(pstmt, 3), sqlite3_column_bytes(pstmt, 3)); objs.push_back(obj); } return objs.size(); } int FaceDbMgr::QueryGroupByID(int group_id, std::vector& objs) { if (!IsDbInit()) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, FS_DB_QUERY_GROUP_BY_NAME, strlen(FS_DB_QUERY_GROUP_BY_NAME), &pstmt, 0); AutoDeleteStmt ads(pstmt); if (ret != SQLITE_OK) return DB_ERR_SQL; ret = sqlite3_bind_int(pstmt, 1, group_id); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; while (sqlite3_step(pstmt) == SQLITE_ROW) { DB_GROUP_OBJ obj; obj.group_id = sqlite3_column_int(pstmt, 0); obj.group_name = std::string((const char*)sqlite3_column_text(pstmt, 1), sqlite3_column_bytes(pstmt, 1)); obj.remarks = std::string((const char*)sqlite3_column_text(pstmt, 2), sqlite3_column_bytes(pstmt, 2)); obj.remarks = std::string((const char*)sqlite3_column_text(pstmt, 3), sqlite3_column_bytes(pstmt, 3)); objs.push_back(obj); } return objs.size(); } /* 查询所有的组数据 */ DB_ERR_CODE FaceDbMgr::QueryGroupDatas(std::vector& objs) { if (!IsDbInit()) return DB_ERR_NO_INIT; sqlite3_stmt * stat = NULL; int res = sqlite3_prepare(m_db, FS_DB_QUERY_GROUP_DATA, -1, &stat, 0); if (res != SQLITE_OK) return DB_ERR_SQL; AutoDeleteStmt ads(stat); while (sqlite3_step(stat) == SQLITE_ROW) { DB_GROUP_OBJ obj; obj.group_id = sqlite3_column_int(stat, 0); obj.group_name = std::string((const char*)sqlite3_column_text(stat, 1), sqlite3_column_bytes(stat,1)); obj.remarks = std::string((const char*)sqlite3_column_text(stat, 2), sqlite3_column_bytes(stat, 2)); obj.create_time = std::string((const char*)sqlite3_column_text(stat, 3), sqlite3_column_bytes(stat, 3)); objs.push_back(obj); } return DB_ERR_OK; } /*根据组ID查询人脸数据*/ int FaceDbMgr::QueryFeatrueByGroup(DB_GROUP_OBJ& group, std::vector& face_db) { if (!IsDbInit()) return DB_ERR_NO_INIT; sqlite3_stmt * stat = NULL; int res = sqlite3_prepare(m_db, FS_DB_QUERY_FEATURES_INFO_BY_GROPU, -1, &stat, 0); AutoDeleteStmt ads(stat); if (res != SQLITE_OK) return DB_ERR_SQL; res = sqlite3_bind_int(stat, 1, group.group_id); if (res != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; while (sqlite3_step(stat) == SQLITE_ROW) { DB_FACE_OBJ obj; const void* pFeatureBytes = sqlite3_column_blob(stat, 1); int featureLen = sqlite3_column_bytes(stat, 1); if (featureLen != MOBILE_FACE_FEATURE_BYTE_LEN) { std::cout << "feature length error..." << std::endl; continue; } memcpy_s(obj.byteFeature, featureLen, pFeatureBytes, featureLen); obj.name = std::string((const char*)sqlite3_column_text(stat, 2), sqlite3_column_bytes(stat, 2)); obj.vip_id = std::string((const char*)sqlite3_column_text(stat, 3), sqlite3_column_bytes(stat, 3)); obj.group = group; obj.enter_time = std::string((const char*)sqlite3_column_text(stat, 6), sqlite3_column_bytes(stat, 6)); face_db.push_back(obj); } return face_db.size(); } /*通过姓名查询人脸特征库*/ int FaceDbMgr::QueryFeatureByName(std::string face_name, std::string group_name, std::vector& face_db) { face_db.clear(); std::vector group_objs; QueryGroupByName(group_name, group_objs); if (group_objs.size() < 1) return DB_ERR_NON_GROUP; sqlite3_stmt * stat = NULL; int res = sqlite3_prepare(m_db, FS_DB_QUERY_FEATURES_INFO_BY_NAME, -1, &stat, 0); AutoDeleteStmt ads(stat); if (res != SQLITE_OK) return DB_ERR_SQL; res = sqlite3_bind_text(stat, 1, face_name.c_str(), face_name.length(), NULL); if (res != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; res = sqlite3_bind_int(stat, 2, group_objs[0].group_id); if (res != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; while (sqlite3_step(stat) == SQLITE_ROW) { DB_FACE_OBJ obj; const void* pFeatureBytes = sqlite3_column_blob(stat, 1); int featureLen = sqlite3_column_bytes(stat, 1); if (featureLen != MOBILE_FACE_FEATURE_BYTE_LEN) { std::cout << "feature length error..." << std::endl; continue; } memcpy_s(obj.byteFeature, featureLen, pFeatureBytes, featureLen); obj.name = std::string((const char*)sqlite3_column_text(stat, 2), sqlite3_column_bytes(stat, 2)); obj.vip_id = std::string((const char*)sqlite3_column_text(stat, 3), sqlite3_column_bytes(stat, 3)); obj.group = group_objs[0]; obj.enter_time = std::string((const char*)sqlite3_column_text(stat, 6), sqlite3_column_bytes(stat, 6)); face_db.push_back(obj); } return face_db.size(); } /*通过姓名查询人脸图片*/ //FS_DB_QUERY_IMG_BY_NAME int FaceDbMgr::QueryImageByName(std::string face_name, int group_id, std::vector& img_data) { if (!IsDbInit()) return DB_ERR_NO_INIT; int ret; sqlite3_stmt * pstmt = NULL; ret = sqlite3_prepare_v2(m_db, FS_DB_QUERY_IMG_BY_NAME, strlen(FS_DB_QUERY_IMG_BY_NAME), &pstmt, 0); if (ret != SQLITE_OK) { return DB_ERR_SQL; } AutoDeleteStmt ads(pstmt);//这里不清理干净会导致数据库关闭时返回错误码SQLITE_BUSY ret = sqlite3_bind_text(pstmt, 1, face_name.c_str(), face_name.length(), NULL); if (ret != SQLITE_OK)return DB_ERR_BIND_SQL_DATA; ret = sqlite3_bind_int(pstmt, 2, group_id); if (ret != SQLITE_OK)return DB_ERR_BIND_SQL_DATA; ret = sqlite3_step(pstmt); if (ret != SQLITE_ROW) return DB_ERR_SQL_EXE; const void* tmp_data = sqlite3_column_blob(pstmt, 0); int data_len = sqlite3_column_bytes(pstmt, 0); img_data.resize(data_len); memcpy_s(img_data.data(), data_len, tmp_data, data_len); return DB_ERR_OK; } /*********************** FaceDB API *****************************/ std::string FaceDbMgr::GetErrInfo(DB_ERR_CODE err_code) { std::string err_info = m_err_info[err_code]; if (err_info.empty()) { return "unknow error"; //return UnicodeToUtf8(L"未知错误..."); } return err_info; } DB_ERR_CODE FaceDbMgr::EnterFace(const std::vector& feature, std::string face_name, std::string vid, std::string group_name, std::vector & imgData) { /* 1.判断特征长度 2.判断分组是否存在 3.判断分组数据是否存满 4.判断人脸特征是否已注册 */ std::lock_guard lock(m_db_lock); if (!m_bDbInit) return DB_ERR_NO_INIT; if (feature.size() != MOBILE_FACE_FEATURE_FLOAT_LEN) return DB_ERR_FEATURE_LEN;//特征长度不对 int group_id = QueryGroupIdByName(group_name); if (group_id < 0) return DB_ERR_NON_GROUP; //分组不存在 if (QueryGroupAllFeatureSize(group_id) >= MAX_FEATURE_FOR_GROUP) return DB_ERR_GROUP_FEATURE_FULL; std::vector face_objs; if (QueryFeatureByName(face_name, group_name, face_objs) > 0) { return DB_ERR_NAME_FEATURE_EXIST; } /* 插入人脸数据 */ sqlite3_stmt * stat; int ret = sqlite3_prepare_v2(m_db, FS_DB_INSERT_FEATURE_DATA, -1, &stat, 0); AutoDeleteStmt ads(stat); if (ret != SQLITE_OK) return DB_ERR_SQL; ret = sqlite3_bind_blob(stat, 1, (unsigned char *)feature.data(), feature.size()*sizeof(float), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_bind_text(stat, 2, face_name.c_str(), face_name.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_bind_text(stat, 3, vid.c_str(), vid.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_bind_blob(stat, 4, imgData.data(), imgData.size(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_bind_int64(stat, 5, group_id); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_step(stat); if (ret != SQLITE_DONE) return DB_ERR_ADD_FACE_FEATURE; //同步到内存 if (QueryFeatureByName(face_name, group_name, face_objs) < 1) { return DB_ERR_ADD_FACE_FEATURE; } m_GroupDb[group_id].push_back(face_objs[0]); return DB_ERR_OK; } DB_ERR_CODE FaceDbMgr::FaceSearch(const std::vector & feature, const std::string group_name, DB_FACE_OBJ& face_obj, std::vector& img_data, float & fSimilarity, float fThreshold) { /* 1.查询组ID 2.在对应分组人脸库比对特征 */ std::lock_guard lock(m_db_lock); fSimilarity = 0.f; //if (feature.size() != MOBILE_FACE_FEATURE_FLOAT_LEN) return 0; auto iter = find_if(m_groups.begin(), m_groups.end(), [&group_name](const DB_GROUP_OBJ& tmp_obj) { if (tmp_obj.group_name.compare(group_name) == 0) { return true; } return false; }); if (iter == m_groups.end()) { //没找到分组 return DB_ERR_NON_GROUP; } auto& face_db = m_GroupDb[iter->group_id]; if (face_db.size() == 0) { return DB_ERR_NO_DATA; //分组内没有人脸数据 } std::vector results; results.resize(face_db.size()); { omp_set_num_threads(omp_get_num_procs() - 1); #pragma omp parallel for for (int i = 0; i < face_db.size(); i++) { results[i].score = FeatureCompare(feature.data(), (float*)face_db[i].byteFeature); results[i].face_obj = face_db[i]; } } sort(results.begin(), results.end(), [&results](const SEARCH_FACE_RESULT& v1, const SEARCH_FACE_RESULT& v2) { return v1.score > v2.score; }); for (int j = 0; j < results.size(); j++) { if (results[j].score > fThreshold) { face_obj = results[j].face_obj; fSimilarity = results[j].score; QueryImageByName(face_obj.name, face_obj.group.group_id, img_data); //FILE* fp; //errno_t err = fopen_s(&fp,"E:/out1.jpg", "wb+"); //fwrite(img_data.data(), 1, img_data.size(), fp); //fclose(fp); } break; } return DB_ERR_OK; } DB_ERR_CODE FaceDbMgr::DeleteFaceByName(std::string face_name, std::string group_name) { /* 1.通过分组名查询分组ID 2.通过名字和分组ID从数据库中删除数据 3.从内存中删除数据 */ std::lock_guard lock(m_db_lock); if (!m_bDbInit) return DB_ERR_NO_INIT; int group_id = QueryGroupIdByName(group_name); if (group_id < 0) return DB_ERR_NON_GROUP; //分组不存在 sqlite3_stmt * stat; int ret = sqlite3_prepare_v2(m_db, FS_DB_DELETE_FEATURE_BY_NAME, -1, &stat, 0); if (ret != SQLITE_OK) return DB_ERR_SQL; AutoDeleteStmt ads(stat); ret = sqlite3_bind_text(stat, 1, face_name.c_str(), face_name.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_bind_int(stat, 2, group_id); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_step(stat); if (ret != SQLITE_DONE) {//删除人脸失败 return DB_ERR_SQL_EXE; } //从内存中删除 m_GroupDb[group_id].erase(remove_if(m_GroupDb[group_id].begin(), m_GroupDb[group_id].end(), [&face_name](DB_FACE_OBJ& face_obj) { return face_obj.name.compare(face_name) == 0 ? true : false; }), m_GroupDb[group_id].end()); return DB_ERR_OK; } DB_ERR_CODE FaceDbMgr::DeleteAllFace(std::string group_name) { std::lock_guard lock(m_db_lock); if (!m_bDbInit) return DB_ERR_NO_INIT; int group_id = QueryGroupIdByName(group_name); if (group_id < 0) return DB_ERR_NON_GROUP; //分组不存在 sqlite3_stmt * stat; int ret = sqlite3_prepare_v2(m_db, FS_DB_DELETE_FEATURE_BY_NAME, -1, &stat, 0); AutoDeleteStmt ads(stat); if (ret != SQLITE_OK) return DB_ERR_SQL; ret = sqlite3_bind_int(stat, 1, group_id); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_step(stat); if (ret != SQLITE_DONE) return DB_ERR_SQL_EXE; //从内存中删除 m_GroupDb[group_id].clear(); return DB_ERR_OK; } DB_ERR_CODE FaceDbMgr::AddGroup(std::string group_name, std::string remarks) { std::lock_guard lock(m_db_lock); if (!m_bDbInit) return DB_ERR_NO_INIT; int group_id = QueryGroupIdByName(group_name); if (group_id >= 0) return DB_ERR_GROUP_REPEAT; sqlite3_stmt * stat; int ret = sqlite3_prepare_v2(m_db, FS_DB_INSTER_GROUP_DATA, -1, &stat, 0); if (ret != SQLITE_OK) return DB_ERR_SQL; AutoDeleteStmt ads(stat); ret = sqlite3_bind_text(stat, 1, group_name.c_str(), group_name.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_bind_text(stat, 2, remarks.c_str(), remarks.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_step(stat); if (ret != SQLITE_DONE) return DB_ERR_ADD_GROUP; std::vector groups; QueryGroupByName(group_name, groups); if (groups.size() < 1) return DB_ERR_ADD_GROUP; m_groups.push_back(groups[0]); return DB_ERR_OK; } DB_ERR_CODE FaceDbMgr::DeleteGroup(std::string group_name) { std::lock_guard lock(m_db_lock); if (!m_bDbInit) return DB_ERR_NO_INIT; int group_id = QueryGroupIdByName(group_name); if (group_id < 0) return DB_ERR_NON_GROUP; auto err_code = DeleteAllFace(group_name); if (err_code != DB_ERR_OK) return err_code; sqlite3_stmt * stat; int ret = sqlite3_prepare_v2(m_db, FS_DB_DELETE_GROUP_BY_NAME, -1, &stat, 0); AutoDeleteStmt ads(stat); if (ret != SQLITE_OK) return DB_ERR_SQL; ret = sqlite3_bind_text(stat, 1, group_name.c_str(), group_name.length(), NULL); if (ret != SQLITE_OK) return DB_ERR_BIND_SQL_DATA; ret = sqlite3_step(stat); if (ret != SQLITE_DONE) return DB_ERR_ADD_GROUP; //从内存中删除 m_groups.erase(remove_if(m_groups.begin(), m_groups.end(), [&group_name](DB_GROUP_OBJ& group_obj) { return (group_obj.group_name.compare(group_name) == 0) ? true : false; })); for (auto it = m_GroupDb.begin(); it != m_GroupDb.end();) { if (it->first == group_id) m_GroupDb.erase(it); } return DB_ERR_OK; }