5#include "sfe_toolkit/sfe_core.h"
6#include "sfe_toolkit/sfe_face.h"
13#include <unordered_map>
15std::string
gallery =
"./assets/face/entities/";
42 size_t &recommended_width,
43 size_t &recommended_height) {
53 std::smatch width_height;
55 std::regex(
".*w([0-9]+)h([0-9]+).*"))) {
56 recommended_width = std::stoi(width_height[1]);
57 recommended_height = std::stoi(width_height[2]);
68 utils::checkError(error);
69 recommended_width = input_size.width;
70 recommended_height = input_size.height;
89 error =
sfeImageDecode(image_data.data(), image_data.size(), &image);
90 utils::checkError(error);
92 size_t recommended_width{};
93 size_t recommended_height{};
105 error =
sfeImageResize(image, recommended_width, recommended_height,
107 utils::checkError(error);
111 size_t detection_count = 1;
116 &detected_face, &detection_count);
117 utils::checkError(error);
119 if (detection_count == 0) {
120 throw std::runtime_error(
"No face detected in the image.");
131 utils::checkError(error);
140 landmarks.data(), &face_template);
141 utils::checkError(error);
143 return face_template;
147 std::cout <<
"Help: Usage of the program." << std::endl;
148 std::cout <<
"Options:" << std::endl;
149 std::cout <<
"-h: Display help." << std::endl;
150 std::cout <<
"-p: Probe image file." << std::endl;
151 std::cout <<
"-g: Path to folder with entities." << std::endl;
152 std::cout <<
"-d: Path to detector solver." << std::endl;
153 std::cout <<
"-l: Path to landmarks solver." << std::endl;
154 std::cout <<
"-e: Path to extraction solver." << std::endl;
155 std::cout <<
"-t: Detection threshold. <0,1>" << std::endl;
156 std::cout <<
"-i: Identification threshold. <0,1>" << std::endl;
157 std::cout <<
"-m: Minimal face size in pixels to detect." << std::endl;
158 std::cout <<
"-x: Max face size in pixels to detect." << std::endl;
161int main(
int argc,
char *argv[]) {
166 std::unordered_map<std::string, std::string> args;
169 for (
int i = 1; i < argc; ++i) {
170 std::string arg = argv[i];
177 if (i + 1 < argc && argv[i + 1][0] !=
'-') {
178 args[arg] = argv[++i];
180 std::cerr <<
"Option " << arg <<
" requires a value." << std::endl;
184 std::cerr <<
"Unknown option: " << arg << std::endl;
190 if (args.count(
"-p"))
192 if (args.count(
"-g"))
194 if (args.count(
"-d"))
196 if (args.count(
"-l"))
198 if (args.count(
"-e"))
200 if (args.count(
"-t"))
202 if (args.count(
"-i"))
204 if (args.count(
"-m"))
206 if (args.count(
"-x"))
209 utils::printFormatted(
"EXAMPLE PARAMETERS");
211 std::cout <<
"Probe image: " <<
image_probe << std::endl;
212 std::cout <<
"Entities folder: " <<
gallery << std::endl;
221 std::cout <<
"Min face size [px]: " <<
face_size_min << std::endl;
222 std::cout <<
"Max face size [px]: " <<
face_size_max << std::endl;
228 utils::printToolkitInfo();
243 utils::checkError(error);
249 utils::checkError(error);
255 utils::checkError(error);
260 utils::printFormatted(
"PROBE TEMPLATE EXTRACTION");
262 landmarks_solver, template_solver);
264 std::cout <<
"Probe face template extracted." << std::endl;
267 std::vector<SFEFaceTemplate> gallery_face_templates = {};
268 std::vector<SFEEntity> enitity_pairs = {};
281 utils::printFormatted(
"ENTITIES TEMPLATE EXTRACTION");
284 auto folder_names = utils::getFiles(
gallery);
286 for (
auto folder_name : folder_names) {
287 if (folder_name.find(
".jpg") != std::string::npos ||
288 folder_name.find(
".png") != std::string::npos) {
293 auto entity = utils::generateEntity();
295 auto entity_folder =
gallery + folder_name +
"/";
297 std::cout <<
"Folder: " << entity_folder <<
", entity UUID: ["
298 <<
static_cast<int>(entity.uuid[0]) <<
", "
299 <<
static_cast<int>(entity.uuid[1]) <<
"..."
300 <<
static_cast<int>(entity.uuid[15]) <<
"]" << std::endl;
303 auto image_names = utils::getFiles(entity_folder);
306 for (
auto image_name : image_names) {
311 image_path, detector_solver, landmarks_solver, template_solver);
313 gallery_face_templates.push_back(face_template);
314 enitity_pairs.push_back(entity);
320 size_t candidate_count = 1;
321 std::vector<SFEEntityIdentificationCandidate> results(candidate_count);
322 int best_candidate_index = -1;
327 utils::printFormatted(
"1:N IDENTIFICATION WITH ENTITIES");
329 &probe_face_template, gallery_face_templates.
data(),
330 enitity_pairs.data(), gallery_face_templates.size(),
332 utils::checkError(error);
334 if (candidate_count == 0) {
335 std::cout <<
"No candidates found. Exiting.." << std::endl;
339 std::cout << std::endl;
340 std::cout <<
"Found " << results.size() <<
" candidates " << std::endl;
341 for (
int i = 0; i < results.size(); i++) {
342 std::cout <<
"Index: " << i <<
", Score: " << results[i].score
344 std::cout <<
"Entity UUID: ["
345 <<
static_cast<int>(results[i].entity.uuid[0]) <<
", "
346 <<
static_cast<int>(results[i].entity.uuid[1]) <<
"..."
347 <<
static_cast<int>(results[i].entity.uuid[15]) <<
"]"
353 utils::printFormatted(
"FINISHED");
float identification_threshold
void getRecommendedImageSize(const std::string &solver_face_detect, SFEImage &image, const size_t face_size_min, const size_t face_size_max, size_t &recommended_width, size_t &recommended_height)
Get recommended image size for face detection.
std::string solver_face_detect
Solvers to use in example, the defaults are filled in by CMake.
float detection_threshold
const auto SOLVER_PARAMETERS
size_t face_size_min
Required size of the face to be detected.
std::string solver_face_landmarks
std::string solver_face_template
SFEFaceTemplate extractTemplate(std::string image_path, SFESolver &detector_solver, SFESolver &landmarks_solver, SFESolver &template_solver)
void sfeSolverFree(SFESolver solver)
Free memory associated with SFESolver.
SFEError sfeImageResize(SFEImageView image, size_t width, size_t height, SFEImage *out_image)
Resize image.
void * SFESolver
Solver provides an abstract interface over inference models and engines.
void * SFEError
Error type used to hold optional error message.
void sfeImageFree(SFEImage image)
Free memory associated with SFEImage.
SFEError sfeSolverCreate(const char *solver_file, const SFESolverParameter *solver_parameters, size_t solver_parameters_count, SFESolver *out_solver)
Create new solver from solver file.
SFEError sfeImageDecode(const unsigned char *data, size_t data_len, SFEImage *out_image)
Decode SFEImage from raw image data of various formats. Eg. PNG, JPEG ..
SFEError sfeDetect(SFESolver solver, SFEImageView image, float threshold, SFEDetection *out_detections, size_t *in_out_detection_count)
Detect objects in the source image using unified detection API.
SFEError sfeFaceDetectInputSize(SFEImageView image, SFEFaceDetectionAccuracyType detection_mode, size_t min_face_size, size_t max_face_size, SFEDetectionInputSize *out_input_size)
Calculation of recommended input image width and height according to desired minimal and maximal size...
#define SFE_FACE_LANDMARK_COUNT
SFEError sfeFaceLandmarks(SFESolver solver, SFEImageView image, const SFEDetection *detection, SFEFaceLandmarks out_face_landmarks[SFE_FACE_LANDMARK_COUNT])
Detect 23 landmarks of the face detected in the area of source image marked with detection.
SFEError sfeFaceEntityIdentify(SFEFaceTemplate *probe_face_template, SFEFaceTemplate *templates_gallery, SFEEntity *entities_gallery, size_t gallery_size, float matching_score_threshold, SFEEntityIdentificationCandidate *out_candidates, size_t *in_out_candidates_count, size_t thread_count)
Get an ordered array of SFEEntityIdentificationCandidate from tested template best matches of probe t...
SFEError sfeFaceTemplateExtract(SFESolver solver, SFEImageView image, const SFEDetection *detection, const SFEFaceLandmarks face_landmarks[SFE_FACE_LANDMARK_COUNT], SFEFaceTemplate *out_face_template)
Extract template from source image and given face landmarks.
Core detection - tagged union containing all detection types.
uint8_t data[SFE_FACE_TEMPLATE_SIZE]
Raw owned raster image representation, HWC|BGR order.