#include "face_pipeline.h" #include // 用于日志 // 构造函数:初始化ORT环境、会话选项,并加载模型 FacePipeline::FacePipeline(const std::string& model_dir) : m_env(ORT_LOGGING_LEVEL_WARNING, "FaceSDK") // 初始化ORT环境 { // 配置会话选项 m_session_options.SetIntraOpNumThreads(1); // 移动端通常设置为1 m_session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL); // 立即加载模型 m_initialized = LoadModels(model_dir); if (m_initialized) { std::cout << "FacePipeline initialized successfully." << std::endl; } else { std::cerr << "FacePipeline initialization failed." << std::endl; } } // 析构函数 (由于使用unique_ptr, 资源会自动释放) FacePipeline::~FacePipeline() {} // (私有) 加载所有模型 bool FacePipeline::LoadModels(const std::string& model_dir) { try { // 【【修正点】】: // 我们不再使用 to_wstring()。 // 我们直接使用 .c_str(),因为Android API需要 const char* // 1. 人脸检测 std::string detector_path = model_dir + "/faceboxesv2-640x640.onnx"; m_session_detector = std::make_unique(m_env, detector_path.c_str(), m_session_options); std::cout << "Loaded model: " << detector_path << std::endl; // 2. 关键点 (Net1) std::string lm1_path = model_dir + "/face_landmarker_pts5_net1.onnx"; m_session_landmarker1 = std::make_unique(m_env, lm1_path.c_str(), m_session_options); std::cout << "Loaded model: " << lm1_path << std::endl; // 3. 关键点 (Net2) std::string lm2_path = model_dir + "/face_landmarker_pts5_net2.onnx"; m_session_landmarker2 = std::make_unique(m_env, lm2_path.c_str(), m_session_options); std::cout << "Loaded model: " << lm2_path << std::endl; // 4. 人脸识别 std::string rec_path = model_dir + "/face_recognizer.onnx"; m_session_recognizer = std::make_unique(m_env, rec_path.c_str(), m_session_options); std::cout << "Loaded model: " << rec_path << std::endl; // 5. 旋转分类 std::string rot_path = model_dir + "/model_gray_mobilenetv2_rotcls.onnx"; m_session_rotator = std::make_unique(m_env, rot_path.c_str(), m_session_options); std::cout << "Loaded model: " << rot_path << std::endl; // 6. 姿态估计 (VAR) std::string pose_var_path = model_dir + "/fsanet-var.onnx"; m_session_pose_var = std::make_unique(m_env, pose_var_path.c_str(), m_session_options); std::cout << "Loaded model: " << pose_var_path << std::endl; // 7. 姿态估计 (CONV) std::string pose_conv_path = model_dir + "/fsanet-conv.onnx"; m_session_pose_conv = std::make_unique(m_env, pose_conv_path.c_str(), m_session_options); std::cout << "Loaded model: " << pose_conv_path << std::endl; } catch (const Ort::Exception& e) { // 如果任何模型加载失败,捕获异常 std::cerr << "Error loading models: " << e.what() << std::endl; return false; } std::cout << "All 7 models loaded successfully." << std::endl; return true; } // L2 归一化 (将在Extract中使用) void FacePipeline::normalize_l2(std::vector& v) { double norm = 0.0; for (float val : v) { norm += val * val; } if (norm > 1e-6) { // 避免除以零 norm = std::sqrt(norm); for (float& val : v) { val = static_cast(val / norm); } } } // Extract 方法的桩函数 (我们将在下一步实现) bool FacePipeline::Extract(const cv::Mat& image, std::vector& feature) { if (!m_initialized) { std::cerr << "Pipeline is not initialized." << std::endl; return false; } if (image.empty()) { std::cerr << "Input image is empty." << std::endl; return false; } // -------------------------------------------------- // TODO: 在这里实现完整的 7 模型推理管线 // -------------------------------------------------- // std::cout << "Extract method is not implemented yet." << std::endl; // 临时填充一个假的特征向量 feature.assign(512, 0.5f); normalize_l2(feature); return true; }