#include "ANSOVFBFaceDetector.h" #include #include #include #include #include "Utility.h" namespace ANSCENTER { bool ANSOVFBFD::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) { bool result = ANSFDBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap); labelMap = "Face"; // We do not need to check for the license _licenseValid = true; if (!_licenseValid) return false; try { _modelConfig = modelConfig; _modelConfig.modelType = ModelType::FACEDETECT; _modelConfig.detectionType = DetectionType::FACEDETECTOR; // We need to get the modelfolder from here std::string xmlfile = CreateFilePath(_modelFolder, "facebox.xml"); if (std::filesystem::exists(xmlfile)) { _modelFilePath = xmlfile; this->_logger.LogDebug("ANSOVFBFD::Initialize. Loading ansovfb weight", _modelFilePath, __FILE__, __LINE__); } else { this->_logger.LogError("ANSOVFBFD::Initialize. Model ansovfb.xml file is not exist", _modelFilePath, __FILE__, __LINE__); return false; } std::string landmarkModel = CreateFilePath(_modelFolder, "landmarks.xml"); if (std::filesystem::exists(landmarkModel)) { _landmarkModelFilePath = landmarkModel; this->_logger.LogDebug("ANSOVFBFD::Initialize. Loading landmarks weight", _landmarkModelFilePath, __FILE__, __LINE__); ov::Core lmcore; CnnConfig landmarks_config(_landmarkModelFilePath, "Facial Landmarks Regression"); landmarks_config.m_deviceName = "GPU"; landmarks_config.m_max_batch_size = 1; landmarks_config.m_core = lmcore; this->_faceLandmark = std::make_unique(landmarks_config); if (_faceLandmark == nullptr) { this->_logger.LogFatal("ANSOVFBFD::Initialize", "Failed to initialize face recognizer model", __FILE__, __LINE__); } } else { this->_logger.LogError("ANSOVFBFD::Initialize. Model landmarks.xml file is not exist", _landmarkModelFilePath, __FILE__, __LINE__); } std::vector labels; labels.push_back(labelMap); std::unique_ptr _faceDetector; _faceDetector.reset(new ModelFaceBoxes(_modelFilePath, static_cast(0.5), false, static_cast(0.5), "")); _faceDetector->setInputsPreprocessing(false, "", ""); ov::Core core; this->_faceDectectorPipeline = std::make_unique(std::move(_faceDetector), ConfigFactory::getUserConfig("GPU", 0, "", 0), core); _isInitialized = true; return true; } catch (std::exception& e) { this->_logger.LogFatal("ANSOVFBFD::Initialize", e.what(), __FILE__, __LINE__); return false; } } bool ANSOVFBFD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) { try { // We need to get the _modelFolder bool result = ANSFDBase::LoadModel(modelZipFilePath, modelZipPassword); if (!result) return false; // We need to get the modelfolder from here std::string xmlfile = CreateFilePath(_modelFolder, "ansovfb.xml"); if (std::filesystem::exists(xmlfile)) { _modelFilePath = xmlfile; this->_logger.LogDebug("ANSOVFBFD::LoadModel. Loading ansovfb weight", _modelFilePath, __FILE__, __LINE__); } else { this->_logger.LogError("ANSOVFBFD::LoadModel. Model ansovfb.xml file is not exist", _modelFilePath, __FILE__, __LINE__); return false; } return true; } catch (std::exception& e) { this->_logger.LogFatal("ANSOVFBFD::LoadModel", e.what(), __FILE__, __LINE__); return false; } } bool ANSOVFBFD::OptimizeModel(bool fp16, std::string& optimizedModelFolder) { if (!FileExist(_modelFilePath)) { optimizedModelFolder = ""; return false; } return true; } std::vector ANSOVFBFD::RunInference(const cv::Mat& input) { std::vector output; output.clear(); if (!_licenseValid) { this->_logger.LogError("ANSOVFBFD::RunInference", "Invalid license", __FILE__, __LINE__); return output; } if (!_isInitialized) { this->_logger.LogError("ANSOVFBFD::RunInference", "Model is not initialized", __FILE__, __LINE__); return output; } try { bool croppedFace = false; // Check if the image is cropped face image cv::Mat im = input.clone(); //std::cout << "Width x Height=" << input.size[0] << "x" << input.size[1] << std::endl; // We know that the image sizes <=300 px, it is likely that image is cropped for face only if ((input.size[0] <= 300) || (input.size[1] <= 300)) croppedFace = true; if (croppedFace) cv::copyMakeBorder(input, im, 200, 200, 200, 200, cv::BORDER_REPLICATE); ; auto startTime = std::chrono::steady_clock::now(); int64_t frameNum = _faceDectectorPipeline->submitData(ImageInputData(im), std::make_shared(im, startTime)); _faceDectectorPipeline->waitForTotalCompletion(); std::unique_ptr result = _faceDectectorPipeline->getResult(); auto outputImg = result->metaData->asRef().img; if (outputImg.empty()) { throw std::invalid_argument("Renderer: image provided in metadata is empty"); } for (auto& obj : result->asRef().objects) { Object result; std::vector face_rois; std::vector landmarks; float confidence = obj.confidence; if (confidence >= _modelConfig.detectionScoreThreshold) { int x_min = obj.x; int y_min = obj.y; int x_max = obj.x + obj.width; int y_max = obj.y + obj.height; result.classId = obj.labelID; result.className = obj.label; result.confidence = confidence; result.box.x = x_min; result.box.y = y_min; if (croppedFace) { if (x_min <= 200) x_min = 200; if (y_min <= 200) y_min = 200; result.box.x = x_min - 200; result.box.y = y_min - 200; } result.box.width = x_max - x_min; result.box.height = y_max - y_min; if (_faceLandmark != nullptr) { landmarks.clear(); face_rois.clear(); cv::Mat face_roi = ANSUtilityHelper::GetCroppedFace(im, x_min, y_min, x_max, y_max); face_rois.push_back(face_roi); _faceLandmark->Compute(face_rois, &landmarks, cv::Size(2, 5)); ANSUtilityHelper::AlignFaces(&face_rois, &landmarks); result.mask = face_rois[0]; face_roi.release(); } else { result.mask = ANSUtilityHelper::GetCroppedFace(im, x_min, y_min, x_max, y_max); } result.cameraId = "FBFaceCAM"; output.push_back(result); } } im.release(); EnqueueDetection(output, "FBFaceCAM"); return output; } catch (std::exception& e) { this->_logger.LogFatal("ANSOVFBFD::RunInference", e.what(), __FILE__, __LINE__); return output; } } std::vector ANSOVFBFD::RunInference(const cv::Mat& input, const std::string& camera_id) { std::vector output; output.clear(); if (!_licenseValid) { this->_logger.LogError("ANSOVFBFD::RunInference", "Invalid license", __FILE__, __LINE__); return output; } if (!_isInitialized) { this->_logger.LogError("ANSOVFBFD::RunInference", "Model is not initialized", __FILE__, __LINE__); return output; } try { bool croppedFace = false; // Check if the image is cropped face image cv::Mat im = input.clone(); //std::cout << "Width x Height=" << input.size[0] << "x" << input.size[1] << std::endl; // We know that the image sizes <=300 px, it is likely that image is cropped for face only if ((input.size[0] <= 300) || (input.size[1] <= 300)) croppedFace = true; if (croppedFace) cv::copyMakeBorder(input, im, 200, 200, 200, 200, cv::BORDER_REPLICATE); ; auto startTime = std::chrono::steady_clock::now(); int64_t frameNum = _faceDectectorPipeline->submitData(ImageInputData(im), std::make_shared(im, startTime)); _faceDectectorPipeline->waitForTotalCompletion(); std::unique_ptr result = _faceDectectorPipeline->getResult(); auto outputImg = result->metaData->asRef().img; if (outputImg.empty()) { throw std::invalid_argument("Renderer: image provided in metadata is empty"); } for (auto& obj : result->asRef().objects) { Object result; std::vector face_rois; std::vector landmarks; float confidence = obj.confidence; if (confidence >= _modelConfig.detectionScoreThreshold) { int x_min = obj.x; int y_min = obj.y; int x_max = obj.x + obj.width; int y_max = obj.y + obj.height; result.classId = obj.labelID; result.className = obj.label; result.confidence = confidence; result.box.x = x_min; result.box.y = y_min; if (croppedFace) { if (x_min <= 200) x_min = 200; if (y_min <= 200) y_min = 200; result.box.x = x_min - 200; result.box.y = y_min - 200; } result.box.width = x_max - x_min; result.box.height = y_max - y_min; if (_faceLandmark != nullptr) { landmarks.clear(); face_rois.clear(); cv::Mat face_roi = ANSUtilityHelper::GetCroppedFace(im, x_min, y_min, x_max, y_max); face_rois.push_back(face_roi); _faceLandmark->Compute(face_rois, &landmarks, cv::Size(2, 5)); ANSUtilityHelper::AlignFaces(&face_rois, &landmarks); result.mask = face_rois[0]; face_roi.release(); } else { result.mask = ANSUtilityHelper::GetCroppedFace(im, x_min, y_min, x_max, y_max); } result.cameraId = camera_id; output.push_back(result); } } im.release(); EnqueueDetection(output, camera_id); return output; } catch (std::exception& e) { this->_logger.LogFatal("ANSOVFBFD::RunInference", e.what(), __FILE__, __LINE__); return output; } } ANSOVFBFD::~ANSOVFBFD() { try { } catch (std::exception& e) { this->_logger.LogFatal("ANSOVFBFD::Destroy", e.what(), __FILE__, __LINE__); } } bool ANSOVFBFD::Destroy() { try { return true; } catch (std::exception& e) { this->_logger.LogFatal("ANSOVFBFD::Destroy", e.what(), __FILE__, __LINE__); return false; } } }