// // created by wangjiale on 2024/5/9 // description: 对face_folder中的人脸计算sim,然后将sim储存在txt文件中,然后用python 处理这些sim得到AUC曲线并得到合适的阈值。 #include "lite/lite.h" #include #include #include "dirent.h" #include #include struct Node{ std::string name; std::vector> embeddings; int num_embd; Node() :num_embd(0){}; }; int main(int argc, char* argv[]){ const std::string detect_onnx = R"(C:\Users\JIALE\Desktop\bns_proj\test2_ort\pipeline\hub\Pytorch_RetinaFace_resnet50.onnx)"; const std::string reg_onnx = R"(C:\Users\JIALE\Desktop\bns_proj\test2_ort\pipeline\hub\focal-arcface-bh-ir50-asia.onnx)"; if (argc <= 1) { std::cerr << "argc <= 1" < nodes; //储存着人脸的内容 // get face embeddings from folder if (face_folder.back() != '/' || face_folder.back() != '\\') face_folder.push_back('/'); DIR* dir = opendir(face_folder.c_str()); if (dir == nullptr){ std::cerr << "Cannot open directory: " << face_folder << std::endl; return -1; } struct dirent *outEntry, *entry; while((outEntry=readdir(dir)) != nullptr) { std::string foldername = outEntry->d_name; if(foldername.find('.') != std::string::npos) continue; std::string subfolder = face_folder + foldername + '/'; DIR* subdir = opendir(subfolder.c_str()); Node node; while ((entry = readdir(subdir)) != nullptr) { std::string fileName = entry->d_name; if(fileName == "." || fileName ==".." || fileName.find(".jpg") == std::string::npos) continue; std::string filePath = subfolder + fileName; cv::Mat img_bgr = cv::imread(filePath); lite::types::FaceContent known_face_content; std::vector detected_boxes; retinaface->detect(img_bgr, detected_boxes); if (detected_boxes.empty() || detected_boxes.size() > 1 || !detected_boxes[0].flag ) { std::cout << filePath + ": has " + std::to_string(static_cast(detected_boxes.size())); continue; } focal_asia_arcface->detect(img_bgr(detected_boxes[0].rect()), known_face_content); if (known_face_content.flag){ node.embeddings.push_back(known_face_content.embedding); ++ node.num_embd; // node.name = fileName.substr(0,fileName.size()-4); } // std::cout << "File name: " << fileName << std::endl; // std::cout << "File path: " << filePath << std::endl; } node.name = foldername; nodes.push_back(node); closedir(subdir); } closedir(dir); // compute sim between faces vector flags; vector sims; std::random_device rd; std::mt19937 gen(rd()); int num_sel = 8; for(int i = 0; i < nodes.size(); i++ ) { //compute negative similarity std::vector& source_embedding = nodes[i].embeddings[0]; for(int j = 0; j < num_sel; j++ ) { int idx = i; while(idx == i) idx = std::uniform_int_distribution(0,nodes.size()-1)(gen); int iidx = std::uniform_int_distribution(0,nodes[idx].num_embd)(gen); std::vector& target_embedding = nodes[idx].embeddings[iidx]; flags.push_back(0); sims.push_back( lite::utils::math::cosine_similarity(source_embedding, target_embedding) ) } //compute positive similarity vector& embds = nodes[i].embeddings; for(int a = 0; a < embds.size(); a++) { for(int b = a+1; b < embds.size(); b++) { flags.push_back(1); sims.push_back( lite::utils::math::cosine_similarity( embds[a], embds[b]) ) } } } delete retinaface; delete focal_asia_arcface; std::ofstream simfile("simfile.txt"); std::ofstream intfile("intfile.txt"); for(float similarity : sims) simfile << static_cast(similarity) << std::endl; for(int flag : flags) intfile << static_cast(flag) << std::endl; simfile.close(); intfile.close(); return 0; }