SmartFace Embedded Toolkit  4.2.1
Loading...
Searching...
No Matches
example_iris_identify.cpp
Go to the documentation of this file.
1
5#include "sfe_toolkit/sfe_core.h"
6#include "sfe_toolkit/sfe_iris.h"
7#include <regex>
8#include <vector>
9
10#include <iomanip>
11#include <sstream>
12
13#include "annotate.hpp"
14#include "solvers.h"
15#include "utils.hpp"
16#include <unordered_map>
17
18std::string image_match = "assets/iris/iris1_1.png";
19std::string image_probe = "assets/iris/iris1_0.png";
20std::string image_non_match = "assets/iris/iris0.png";
21
23std::string solver_iris_detect = SOLVER_IRIS_DETECT;
24std::string solver_iris_template = SOLVER_IRIS_TEMPLATE;
25
26const auto SOLVER_PARAMETERS = std::vector<SFESolverParameter>{};
27
29
31 SFESolver &detector_solver,
32 SFESolver &template_solver) {
33
34 SFEImage image{};
35 DEFER(sfeImageFree(image));
36 SFEError error{};
37 { // STAGE 1: Load image
38 // Load image data from file
39 auto image_data = utils::readFile(image_path);
40
41 // Decode image from data
42 error = sfeImageDecode(image_data.data(), image_data.size(), &image);
43 utils::checkError(error);
44 }
45
47 SFEDetection detected_iris = {};
48 size_t iris_count = 1;
49 { // STAGE 2: Detect iris in the image
50
51 // Detect iris in the image
52 error = sfeDetect(detector_solver, image, 0.1f, &detected_iris, &iris_count);
53 utils::checkError(error);
54
55 if (iris_count == 0 || detected_iris.confidence < 0.5) {
56 throw std::runtime_error("No iris detected in the probe image.");
57 }
58
59 std::cout << "Found iris in the image. Extracting template..." << std::endl;
60 }
62
64 SFEIrisTemplate iris_template;
65 { // STAGE 3 Extract probe iris template
66 // Use template extraction solver to create new iris
67 // template
68 error = sfeIrisTemplateExtract(template_solver, image, &detected_iris,
69 &iris_template);
70 utils::checkError(error);
71 }
73 return iris_template;
74}
75
76void printHelp() {
77 std::cout << "Help: Usage of the program." << std::endl;
78 std::cout << "Options:" << std::endl;
79 std::cout << "-h: Display help." << std::endl;
80 std::cout << "-p: Probe image file." << std::endl;
81 std::cout << "-g: Matching image file. Our \"iris database\"." << std::endl;
82 std::cout << "-d: Path to detector solver." << std::endl;
83 std::cout << "-e: Path to extraction solver." << std::endl;
84 std::cout << "-t: Detection threshold. <0,1>" << std::endl;
85 std::cout << "-i: Identification threshold. <0,1>" << std::endl;
86}
87
89int main(int argc, char *argv[]) {
90
91 { // STAGE 0: Parse command line arguments
92 // Map to store argument values
93 std::unordered_map<std::string, std::string> args;
94
95 // Parse command line arguments
96 for (int i = 1; i < argc; ++i) {
97 std::string arg = argv[i];
98 if (arg[0] == '-') {
99 if (arg == "-h") {
100 printHelp();
101 return 0;
102 }
103 // Check if there's a next argument and it isn't another option
104 if (i + 1 < argc && argv[i + 1][0] != '-') {
105 args[arg] = argv[++i];
106 } else {
107 std::cerr << "Option " << arg << " requires a value." << std::endl;
108 return 1;
109 }
110 } else {
111 std::cerr << "Unknown option: " << arg << std::endl;
112 return 1;
113 }
114 }
115
116 // Assign values to variables based on parsed arguments
117 if (args.count("-p"))
118 image_probe = args["-p"];
119 if (args.count("-g"))
120 image_match = args["-g"];
121 if (args.count("-d"))
122 solver_iris_detect = args["-d"];
123 if (args.count("-e"))
124 solver_iris_template = args["-e"];
125 if (args.count("-i"))
126 identification_threshold = std::stof(args["-i"]);
127
128 utils::printFormatted("EXAMPLE PARAMETERS");
129 // Print resource names
130 std::cout << "Probe image: " << image_probe << std::endl;
131 std::cout << "Matching image: " << image_match << std::endl;
132
133 // Print solver names
134 std::cout << "Iris detection solver: " << solver_iris_detect << std::endl;
135 std::cout << "Iris template solver: " << solver_iris_template << std::endl;
136
137 // Print other options
138 std::cout << "Identification threshold: " << identification_threshold
139 << std::endl;
140 }
141
142 utils::printToolkitInfo();
143
144 SFEError error{};
145
146 SFESolver detector_solver{};
147 DEFER(sfeSolverFree(detector_solver));
148 SFESolver landmarks_solver{};
149 DEFER(sfeSolverFree(landmarks_solver));
150 SFESolver template_solver{};
151 DEFER(sfeSolverFree(template_solver));
152 { // STAGE 1.1: loading solvers
153 utils::printFormatted("LOADING SOLVERS");
154 // Initialize Iris detection solver
155 error = sfeSolverCreate(
157 SOLVER_PARAMETERS.size(), &detector_solver);
158 utils::checkError(error);
159
160 // Initialize template extraction solver
161 error = sfeSolverCreate(
163 SOLVER_PARAMETERS.size(), &template_solver);
164 utils::checkError(error);
165 }
166
167 SFEIrisTemplate probe_iris_template;
168 { // STAGE 1: Extract probe iris template
169 utils::printFormatted("PROBE TEMPLATE EXTRACTION");
170
171 probe_iris_template =
172 extract_template(image_probe, detector_solver, template_solver);
173 }
174
175 { // STAGE 1.1: (optional) Print template attributes
176 utils::printFormatted("PROBE TEMPLATE ATTRIBUTES");
177
179 SFEIrisTemplateVersion version = {};
180 error = sfeIrisTemplateVersion(&probe_iris_template, &version);
181 utils::checkError(error);
182
183 std::cout << "Version of the probe template: " << version.version_major
184 << '.' << version.version_minor << std::endl;
186
188 float quality = {};
189 error = sfeIrisTemplateQuality(&probe_iris_template, &quality);
190 utils::checkError(error);
191
192 std::cout << "Quality of the probe template: " << quality << std::endl;
194 }
195
196 size_t gallery_size = 10;
197 std::vector<SFEIrisTemplate> iris_template_gallery(gallery_size);
198 { // STAGE 2: Create iris templates gallery
199 utils::printFormatted("IRIS GALLERY EXTRACTION");
200
201 auto matching_iris_template =
202 extract_template(image_match, detector_solver, template_solver);
203
204 auto non_matching_iris_template =
205 extract_template(image_non_match, detector_solver, template_solver);
206
207 // Fill the gallery with non-matching templates for demonstration purposes
208 for (size_t i = 0; i < gallery_size; i++) {
209 iris_template_gallery[i] = non_matching_iris_template;
210 }
211
212 // Add matching template to the gallery at index 5
213 iris_template_gallery[5] = matching_iris_template;
214 }
215
217 size_t candidate_count = 1;
218 std::vector<SFETemplateIdentificationCandidate> identification_results(
219 candidate_count);
220 { // STAGE 3: Identify the probe template
221 utils::printFormatted("1:N IDENTIFICATION");
222
224 &probe_iris_template, iris_template_gallery.data(),
225 iris_template_gallery.size(), identification_threshold,
226 identification_results.data(), &candidate_count, 4);
227 utils::checkError(error);
228
229 if (candidate_count == 0) {
230 std::cout << "No candidates found above identification threshold "
231 << identification_threshold << std::endl;
232 return 0;
233 }
234
235 std::cout << "Found " << identification_results.size()
236 << " candidates above identification threshold "
237 << identification_threshold << std::endl;
238 for (auto &result : identification_results)
239 std::cout << "Template index: #" << result.index
240 << ", score: " << result.score << std::endl;
241 }
243
245 { // STAGE 4: 1:1 matching with top candidate to showcase 1:1 matching
246 utils::printFormatted("1:1 MATCHING");
247
248 if (identification_results.size() == 0) {
249 std::cout << "No candidates found above identification threshold "
250 << identification_threshold << std::endl;
251 return 0;
252 }
253
254 // Since it's sorted vector by score, the best candidate is the first one
255 auto match_iris_template =
256 iris_template_gallery[identification_results[0].index];
257
258 float match_confidence;
259 error = sfeIrisTemplateMatch(&probe_iris_template, &match_iris_template,
260 &match_confidence);
261 utils::checkError(error);
262
263 std::cout
264 << "Matching score of probe template with the best template, score: "
265 << match_confidence << std::endl;
266 }
268
269 utils::printFormatted("FINISHED");
270}
void printHelp()
float identification_threshold
std::string image_probe
const auto SOLVER_PARAMETERS
SFEIrisTemplate extract_template(std::string image_path, SFESolver &detector_solver, SFESolver &template_solver)
std::string solver_iris_detect
Solvers to use in example, the defaults are filled in by CMake.
std::string solver_iris_template
std::string image_match
std::string image_non_match
std::string image_path
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 sfeIrisTemplateMatch(const SFEIrisTemplate *template1, const SFEIrisTemplate *template2, float *out_matching_score)
Match two iris templates.
SFEError sfeIrisTemplateIdentify(const SFEIrisTemplate *probe_iris_template, const SFEIrisTemplate *templates_gallery, size_t gallery_size, float matching_score_threshold, SFETemplateIdentificationCandidate *out_candidates, size_t *in_out_candidates_count, size_t thread_count)
Get an ordered array of SFETemplateIdentificationCandidate from probe's template best matches with te...
SFEError sfeIrisTemplateVersion(const SFEIrisTemplate *iris_template, SFEIrisTemplateVersion *out_iris_template_version)
Get iris template version.
SFEError sfeIrisTemplateExtract(SFESolver solver, SFEImageView image, const SFEDetection *detection, SFEIrisTemplate *out_iris_template)
Extract template from source image and given iris detection.
SFEError sfeIrisTemplateQuality(const SFEIrisTemplate *iris_template, float *out_iris_template_quality)
Get iris template quality.
Core detection - tagged union containing all detection types.
float confidence
Detection confidence - range <0,1> (common for all detection types)
Raw owned raster image representation, HWC|BGR order.
Definition sfe_core.h:70
Iris template struct.
Definition sfe_iris.h:22
uint8_t data[SFE_IRIS_TEMPLATE_SIZE]
Definition sfe_iris.h:23
Iris template version struct.
Definition sfe_iris.h:27
uint8_t version_major
Major template version.
Definition sfe_iris.h:29
uint8_t version_minor
Minor template version.
Definition sfe_iris.h:31