SmartFace Embedded Toolkit  4.2.1
Loading...
Searching...
No Matches
example_face_demographic_attributes.cpp
Go to the documentation of this file.
1
5#include "sfe_toolkit/sfe_core.h"
6#include "sfe_toolkit/sfe_face.h"
7
8#include "annotate.hpp"
9#include "solvers.h"
10#include "utils.hpp"
11
12#include <iomanip>
13#include <iostream>
14#include <sstream>
15#include <unordered_map>
16#include <vector>
17
18std::string image_probe = "assets/face/images/obiwan0.png";
19
21std::string solver_face_detect = SOLVER_FACE_DETECT;
22std::string solver_face_landmarks = SOLVER_FACE_LANDMARKS;
23std::string solver_face_demographic = SOLVER_FACE_DEMOGRAPHIC_ATTRIBUTES;
24
25const auto SOLVER_PARAMETERS = std::vector<SFESolverParameter>{};
26
28size_t face_size_min = 28;
29size_t face_size_max = 170;
30
32
33void printHelp() {
34 std::cout << "Help: Usage of the program." << std::endl;
35 std::cout << "Options:" << std::endl;
36 std::cout << "-h: Display help." << std::endl;
37 std::cout << "-p: Probe image file." << std::endl;
38 std::cout << "-d: Path to detector solver." << std::endl;
39 std::cout << "-l: Path to landmarks solver." << std::endl;
40 std::cout << "-g: Path to demographic attributes solver." << std::endl;
41 std::cout << "-t: Face detection threshold. <0,1>" << std::endl;
42 std::cout << "-m: Minimal face size in pixels to detect." << std::endl;
43 std::cout << "-x: Max face size in pixels to detect." << std::endl;
44}
45
46int main(int argc, char *argv[]) {
47
48 { // STAGE 0: Parse command line arguments
49 std::unordered_map<std::string, std::string> args;
50
51 for (int i = 1; i < argc; ++i) {
52 std::string arg = argv[i];
53 if (arg[0] == '-') {
54 if (arg == "-h") {
55 printHelp();
56 return 0;
57 }
58 if (i + 1 < argc && argv[i + 1][0] != '-') {
59 args[arg] = argv[++i];
60 } else {
61 std::cerr << "Option " << arg << " requires a value." << std::endl;
62 return 1;
63 }
64 } else {
65 std::cerr << "Unknown option: " << arg << std::endl;
66 return 1;
67 }
68 }
69
70 if (args.count("-p"))
71 image_probe = args["-p"];
72 if (args.count("-d"))
73 solver_face_detect = args["-d"];
74 if (args.count("-l"))
75 solver_face_landmarks = args["-l"];
76 if (args.count("-g"))
77 solver_face_demographic = args["-g"];
78 if (args.count("-t"))
79 detection_threshold = std::stof(args["-t"]);
80 if (args.count("-m"))
81 face_size_min = std::stoi(args["-m"]);
82 if (args.count("-x"))
83 face_size_max = std::stoi(args["-x"]);
84
85 utils::printFormatted("PARAMETERS");
86 std::cout << "Probe image: " << image_probe << std::endl;
87 std::cout << "Face detection solver: " << solver_face_detect << std::endl;
88 std::cout << "Face landmarks solver: " << solver_face_landmarks << std::endl;
89 std::cout << "Face demographic attributes solver: " << solver_face_demographic
90 << std::endl;
91 std::cout << "Min face size [px]: " << face_size_min << std::endl;
92 std::cout << "Max face size [px]: " << face_size_max << std::endl;
93 std::cout << "Detection threshold: " << detection_threshold << std::endl;
94 }
95
96 utils::printToolkitInfo();
97
98 SFEError error{};
99
100 SFESolver detector_solver{};
101 DEFER(sfeSolverFree(detector_solver));
102 SFESolver landmarks_solver{};
103 DEFER(sfeSolverFree(landmarks_solver));
104 SFESolver demographic_solver{};
105 DEFER(sfeSolverFree(demographic_solver));
106
107 { // STAGE 1: loading solvers
108 utils::printFormatted("LOADING solvers");
109
110 error = sfeSolverCreate(
112 SOLVER_PARAMETERS.size(), &detector_solver);
113 utils::checkError(error);
114
115 error = sfeSolverCreate(
117 SOLVER_PARAMETERS.size(), &landmarks_solver);
118 utils::checkError(error);
119
120 error = sfeSolverCreate(
122 SOLVER_PARAMETERS.size(), &demographic_solver);
123 utils::checkError(error);
124 }
125
126 SFEImage image{};
127 DEFER(sfeImageFree(image));
128
129 { // STAGE 2: Load image
130 utils::printFormatted("FACE DETECTION");
132 // Load image data from file
133 auto image_data = utils::readFile(image_probe);
134
135 // Decode image from data
136 error = sfeImageDecode(image_data.data(), image_data.size(), &image);
137 utils::checkError(error);
139 }
140
142 SFEDetection detected_face = {};
143 { // STAGE 3: Detect face in the image
144 size_t detection_count = 1;
145 error = sfeDetect(detector_solver, image, detection_threshold,
146 &detected_face, &detection_count);
147 utils::checkError(error);
148
149 if (detection_count == 0) {
150 std::cout << "No face detected in the probe image." << std::endl;
151 return 0;
152 } else {
153 std::cout << "Found " << detection_count
154 << " face(s) in the probe image. Using the face with highest "
155 "confidence."
156 << std::endl;
157 }
158 }
160
162 std::vector<SFEFaceLandmarks> landmarks(SFE_FACE_LANDMARK_COUNT);
163 { // STAGE 4: Get face landmarks
164 error = sfeFaceLandmarks(landmarks_solver, image, &detected_face,
165 landmarks.data());
166 utils::checkError(error);
167 }
169
171 SFEFaceDemographicAttributes attributes{};
172 { // STAGE 5: Demographic attributes
173 utils::printFormatted("FACE DEMOGRAPHIC ATTRIBUTES");
174 error = sfeFaceDemographicAttributes(demographic_solver, image,
175 landmarks.data(), &attributes);
176 utils::checkError(error);
177 }
179
180 { // STAGE 6: Print demographic attributes
181 std::cout << "Demographic attributes:" << std::endl;
182 std::cout << " Age: " << std::fixed << std::setprecision(1) << attributes.age
183 << " years" << std::endl;
184 std::cout << " Gender score: " << std::setprecision(2) << attributes.gender
185 << " (" << (attributes.gender > 0.0f ? "female" : "male") << ")"
186 << std::endl;
187 }
188
189 utils::printFormatted("FINISHED");
190}
191
192
std::string solver_face_demographic
void printHelp()
std::string solver_face_detect
Solvers to use in example, the defaults are filled in by CMake.
std::string image_probe
float detection_threshold
const auto SOLVER_PARAMETERS
size_t face_size_max
size_t face_size_min
Required size of the face to be detected.
std::string solver_face_landmarks
void sfeSolverFree(SFESolver solver)
Free memory associated with SFESolver.
void * SFESolver
Solver provides an abstract interface over inference models and engines.
Definition sfe_core.h:102
void * SFEError
Error type used to hold optional error message.
Definition sfe_core.h:97
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 sfeFaceDemographicAttributes(SFESolver solver, SFEImageView image, SFEFaceLandmarks face_landmarks[SFE_FACE_LANDMARK_COUNT], SFEFaceDemographicAttributes *out_demographic_attributes)
Estimate demographic attributes (age, gender) from a face image.
#define SFE_FACE_LANDMARK_COUNT
Definition sfe_face.h:17
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.
Core detection - tagged union containing all detection types.
Demographic attributes of the detected face.
Definition sfe_face.h:309
Raw owned raster image representation, HWC|BGR order.
Definition sfe_core.h:70