Enrollment 28.2.0
Loading...
Searching...
No Matches
Face.h
Go to the documentation of this file.
1
10
11#pragma once
12
24#include <algorithm>
25#include <array>
26#include <memory>
27#include <mutex>
28#include <optional>
29#include <unordered_map>
30#include <vector>
31
32// cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes: This is not
33// a problem because we are using them only as read only. cppcoreguidelines-avoid-const-or-ref-data-members: We design
34// te API with const member variables instead of implementing getter methods. This is nicely transformed in C# to
35// properties. Usually our objects are immutable by intention to have no problem in multithreaded applications.
36// NOLINTBEGIN(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes,cppcoreguidelines-avoid-const-or-ref-data-members)
37namespace inno
38{
39 class Face;
40
44 */
45 class FaceExtractorConfig : public Serializable
46 {
47 public:
50 */
51 enum class Type : uint8_t
52 {
59 ACCURATE,
66 BALANCED,
72 FAST
73 };
77 */
78 void SetExtractor(Type value)
79 {
80 type = value;
81 }
85 */
86 [[nodiscard]] Type GetExtractor() const
87 {
88 return type;
89 }
90
94 */
95 void WriteTo(Writer& writer) const final
96 {
97 writer.Write("t", static_cast<unsigned int>(type));
98 }
99
105 */
107 {
108 static const FaceExtractorConfig DefaultCfg;
109 return DefaultCfg;
110 }
111
116 FaceExtractorConfig() = default;
117 virtual ~FaceExtractorConfig() = default;
120 FaceExtractorConfig& operator=(const FaceExtractorConfig&) = default;
121 FaceExtractorConfig& operator=(FaceExtractorConfig&&) = default;
122
123 private:
124 Type type = Type::BALANCED;
125 };
126
131 */
132 class FaceTemplate : public Serializable
133 {
134 public:
136 const std::vector<uint8_t> data;
137
143 */
144 [[nodiscard]] FaceSimilarityScore SimilarWith(const FaceTemplate& gallery) const
145 {
146 log.LogInfo("Matching faces %v - %v", *this, gallery);
147 float score = 0.0F;
148
149 exec->Match(data.data(), data.size(), gallery.data.data(), gallery.data.size(), &score, ThrowOnError{});
150
151 FaceSimilarityScore faceScore = static_cast<int>(score);
152 log.LogInfo("Matching faces %v - %v with score %u from %f", *this, gallery, faceScore, score);
153 return faceScore;
154 }
155
159 */
160 [[nodiscard]] std::string GetVersion() const
161 {
162 int32_t quality = 0;
163 uint32_t modelVersion = 0;
164 uint32_t enrollmentVersion = 0;
165 std::ignore = exec->GetTemplateEmbeddingInfo(
166 data.data(), data.size(), &quality, &modelVersion, &enrollmentVersion, ThrowOnError{});
167 std::ignore = quality;
168
169 return std::to_string(modelVersion) + "." + std::to_string(enrollmentVersion);
170 }
171
175 */
176 void WriteTo(Writer& writer) const override
177 {
178 writer.WriteArray("t", data);
179 }
180
188 */
189 FaceTemplate(std::vector<uint8_t>&& templ, std::shared_ptr<FaceExecutor> executor)
190 : data(std::move(templ))
191 , exec(std::move(executor))
192 , log(GlobalLogger::Get())
193 {
194 if (exec == nullptr)
195 {
196 throw NullArgumentException("executor can not be null");
197 }
198 if (data.empty())
199 {
200 throw InvalidTemplateException("Face template MUST have data");
201 }
202 }
203
209 */
210 explicit FaceTemplate(std::vector<uint8_t>&& templ)
211 : data(std::move(templ))
212 , exec(GlobalFaceExecutor::Get())
213 , log(GlobalLogger::Get())
214 {
215 if (data.empty())
216 {
217 throw InvalidTemplateException("Face template MUST have data");
218 }
219 }
220
228 */
229 FaceTemplate(const std::vector<uint8_t>& templ, std::shared_ptr<FaceExecutor> executor)
230 : data(templ)
231 , exec(std::move(executor))
232 , log(GlobalLogger::Get())
233 {
234 if (exec == nullptr)
235 {
236 throw NullArgumentException("executor can not be null");
237 }
238 if (data.empty())
239 {
240 throw InvalidTemplateException("Face template MUST have data");
241 }
242 }
243
249 */
250 explicit FaceTemplate(const std::vector<uint8_t>& templ)
251 : data(templ)
252 , exec(GlobalFaceExecutor::Get())
253 , log(GlobalLogger::Get())
254 {
255 if (data.empty())
256 {
257 throw InvalidTemplateException("Face template MUST have data");
258 }
259 }
260
261 [[nodiscard]] bool operator==(const FaceTemplate& other) const noexcept
262 {
263 return data == other.data;
264 }
265
266 [[nodiscard]] std::size_t Hash() const noexcept
267 {
268 return detail::HashBytes(data);
269 }
270
271 FaceTemplate(const FaceTemplate&) = delete;
272 FaceTemplate(FaceTemplate&&) = delete;
273 FaceTemplate& operator=(const FaceTemplate&) = delete;
274 FaceTemplate& operator=(FaceTemplate&&) = delete;
275 FaceTemplate() = delete;
276 virtual ~FaceTemplate() = default;
277
278 private:
279 std::shared_ptr<void> faceHandler;
280 std::shared_ptr<FaceExecutor> exec;
281 FormattingLogger log;
282 };
283
284 class Face;
285
290 */
291 class ExtractedFace : public FaceTemplate
292 {
293 public:
295 const std::shared_ptr<Face> face;
296
305 */
306 static std::vector<std::shared_ptr<FaceTemplate>> ToTemplates(
307 const std::vector<std::shared_ptr<ExtractedFace>>& faces)
308 {
309 std::vector<std::shared_ptr<FaceTemplate>> templates(faces.size());
310 std::transform(faces.begin(), faces.end(), templates.begin(), [](const auto& t) { return t; });
311 return templates;
312 }
317 void WriteTo(Writer& writer) const final;
318
319 ExtractedFace(const ExtractedFace&) = delete;
320 ExtractedFace(ExtractedFace&&) = delete;
321 ExtractedFace& operator=(const ExtractedFace&) = delete;
322 ExtractedFace& operator=(ExtractedFace&&) = delete;
323 ExtractedFace() = delete;
324 virtual ~ExtractedFace() = default;
325
326 private:
327 std::shared_ptr<FaceExecutor> exec;
329 /*
330 * @brief Construct a new ExtractedFace object
331 *
332 * @param face Face
333 * @param templ template data
334 * @param faceHandler face handler
335 * @return ExtractedFace object
336 */
337 static std::shared_ptr<ExtractedFace> Create(std::shared_ptr<Face> face,
338 std::vector<uint8_t>&& templ,
339 std::shared_ptr<FaceExecutor> exec)
340 {
341 return std::shared_ptr<ExtractedFace>(
342 new ExtractedFace(std::move(face), std::move(templ), std::move(exec)));
343 }
344
345 ExtractedFace(std::shared_ptr<Face> i, std::vector<uint8_t>&& t, std::shared_ptr<FaceExecutor> e)
346 : FaceTemplate(std::move(t))
347 , face(std::move(i))
348 , exec(std::move(e))
349 , log(GlobalLogger::Get())
350 {
351 }
352
353 friend class Face;
354 };
355
359 */
360 class CroppedFace
361 {
362 public:
366 */
367 [[nodiscard]] std::shared_ptr<FaceCapture> GetFaceCapture() const
368 {
369 if (config.GetCropMethod() == FaceCrop::FULL_NOT_ALIGNED)
370 {
371 auto croppedImage = originalCapture->CropFace(GetCropRectangle(), config.GetCropBackground());
372 auto faceAttributes = originalCapture->faceAttributes;
373 faceAttributes.SetFaceImageType(FaceImageType::BASIC);
374 return FaceCapture::Create(std::move(croppedImage), faceAttributes);
375 }
376
377 auto imageDataAllocator = +[](void* container, size_t size)
378 {
379 auto& vector = *static_cast<std::vector<uint8_t>*>(container);
380 vector.resize(size);
381 return vector.data();
382 };
383 std::vector<uint8_t> imageData;
384
385 ImageHeight imageHeight = 0;
386 ImageWidth imageWidth = 0;
387 exec->CropImage(faceItem.get(),
388 static_cast<unsigned int>(config.GetCropMethod()),
389 config.GetCropScale(),
390 config.GetCropBackground().color.red,
391 config.GetCropBackground().color.green,
392 config.GetCropBackground().color.blue,
393 &imageWidth,
394 &imageHeight,
395 imageDataAllocator,
396 &imageData,
397 ThrowOnError{});
398
399 auto raw = RawImage(
400 imageWidth, imageHeight, originalCapture->image->Dpi(), RawImage::Type::BGR, std::move(imageData));
401 auto croppedImage = Image::DecodeRawImage(raw);
402
403 auto faceAttributes = originalCapture->faceAttributes;
404 switch (config.GetCropMethod())
405 {
406 case FaceCrop::FULL:
407 faceAttributes.SetFaceImageType(FaceImageType::FULL_FRONTAL);
408 break;
409 case FaceCrop::TOKEN:
410 faceAttributes.SetFaceImageType(FaceImageType::TOKEN_FRONTAL);
411 break;
412 default:
413 faceAttributes.SetFaceImageType(FaceImageType::BASIC);
414 break;
415 }
416
417 return FaceCapture::Create(std::move(croppedImage), faceAttributes);
418 }
419
423 */
424 [[nodiscard]] Rectangle GetCropRectangle() const
425 {
426
427 auto rectangle = exec->CropRectangle(
428 faceItem.get(), static_cast<unsigned int>(config.GetCropMethod()), config.GetCropScale(), ThrowOnError{});
429
430 return Rectangle{ { rectangle.topLeftX, rectangle.topLeftY },
431 { rectangle.topRightX, rectangle.topRightY },
432 { rectangle.bottomRightX, rectangle.bottomRightY },
433 { rectangle.bottomLeftX, rectangle.bottomLeftY } };
434 }
435
439 */
440 [[nodiscard]] bool IsCropRegionInsideImage() const
441 {
442 return originalCapture->IsWholeCroppedRectangleInside(GetCropRectangle());
443 }
444
456 */
457 [[nodiscard]] std::shared_ptr<Image> FaceAreaMask() const
458 {
459 if (config.GetCropMethod() == FaceCrop::FULL_NOT_ALIGNED)
460 {
462 "It is not possible to get face area mask for FULL_NOT_ALIGNED crop method");
463 }
464
465 unsigned int width = 0;
466 unsigned int height = 0;
467 size_t length = 0;
468 uint8_t* data = nullptr;
469 exec->FaceAreaMask(faceItem.get(),
470 &width,
471 &height,
472 &data,
473 &length,
474 static_cast<unsigned int>(config.GetCropMethod()),
475 config.GetCropScale(),
476 ThrowOnError{});
477
478 std::vector<uint8_t> mask(data, std::next(data, static_cast<ptrdiff_t>(length)));
479 exec->DeleteBytes(data);
481 RawImage(width, height, originalCapture->image->Dpi(), RawImage::Type::GRAYSCALE, std::move(mask)));
482 }
483
495 */
496 [[nodiscard]] std::shared_ptr<Image> FaceAreaSegment(const RGB& color) const
497 {
498 if (config.GetCropMethod() == FaceCrop::FULL_NOT_ALIGNED)
499 {
501 "It is not possible to get color segmentation for FULL_NOT_ALIGNED crop method");
502 }
503
504 unsigned int width = 0;
505 unsigned int height = 0;
506 size_t length = 0;
507 uint8_t* data = nullptr;
508 exec->FaceAreaSegmentationColor(faceItem.get(),
509 &width,
510 &height,
511 &data,
512 &length,
513 static_cast<unsigned int>(config.GetCropMethod()),
514 config.GetCropScale(),
515 color.red,
516 color.green,
517 color.blue,
518 ThrowOnError{});
519
520 std::vector<uint8_t> mask(data, std::next(data, static_cast<ptrdiff_t>(length)));
521 exec->DeleteBytes(data);
523 RawImage(width, height, originalCapture->image->Dpi(), RawImage::Type::BGR, std::move(mask)));
524 }
525
535 */
536 [[nodiscard]] std::shared_ptr<Image> FaceAreaSegment() const
537 {
538 if (config.GetCropMethod() == FaceCrop::FULL_NOT_ALIGNED)
539 {
540 throw NotSupportedException("It is not possible to get segmentation for FULL_NOT_ALIGNED crop method");
541 }
542
543 unsigned int width = 0;
544 unsigned int height = 0;
545 size_t length = 0;
546 uint8_t* data = nullptr;
547 std::ignore = exec->FaceAreaSegmentation(faceItem.get(),
548 &width,
549 &height,
550 &data,
551 &length,
552 static_cast<unsigned int>(config.GetCropMethod()),
553 config.GetCropScale(),
554 ThrowOnError{});
555
556 std::vector<uint8_t> mask(data, std::next(data, static_cast<ptrdiff_t>(length)));
557 exec->DeleteBytes(data);
559 RawImage(width, height, originalCapture->image->Dpi(), RawImage::Type::BGRA, std::move(mask)));
560 }
561 CroppedFace() = delete;
562 virtual ~CroppedFace() = default;
563 CroppedFace(const CroppedFace&) = delete;
564 CroppedFace(CroppedFace&&) = delete;
565 CroppedFace& operator=(const CroppedFace&) = delete;
566 CroppedFace& operator=(CroppedFace&&) = delete;
567
568 private:
569 std::shared_ptr<void> faceItem;
570 std::shared_ptr<FaceCapture> originalCapture;
572 std::shared_ptr<FaceExecutor> exec;
573
574 CroppedFace(std::shared_ptr<void> f,
575 std::shared_ptr<FaceCapture> oc,
577 std::shared_ptr<FaceExecutor> e)
578 : faceItem(std::move(f))
579 , originalCapture(std::move(oc))
580 , config(std::move(c))
581 , exec(std::move(e))
582 {
583 }
584
585 friend class Face;
586 };
587
591 */
592 class Face final
593 : public Serializable
594 , public std::enable_shared_from_this<Face>
595 {
596 public:
597 class Keypoints;
601 */
602 class Keypoint : public Serializable
603 {
604 public:
610 */
611 [[nodiscard]] Point GetPosition() const
612 {
613 return pos;
614 }
615
621 */
622 [[nodiscard]] float GetScore() const
623 {
624 return score;
625 }
626
630 */
631 void WriteTo(Writer& writer) const final
632 {
633 writer.Write("p", GetPosition());
634 writer.Write("s", GetScore());
635 }
636
637 private:
638 Point pos;
639 float score = 0.0F;
640
641 Keypoint() = default;
642
643 Keypoint(Point position, float reliabilityScore)
644 : pos(std::move(position))
645 , score(reliabilityScore)
646 {
647 }
648
649 friend class Keypoints;
650 };
651
657 */
658 class Keypoints : public Serializable
659 {
660 public:
668 */
670 {
671 return CalculateKeypoint(exec->GetRightEyeOuterCornerId(), "reoc");
672 }
673
681 */
683 {
684 return CalculateKeypoint(exec->GetRightEyeCentreId(), "rec");
685 }
686
694 */
696 {
697 return CalculateKeypoint(exec->GetRightEyeInnerCornerId(), "reic");
698 }
699
707 */
709 {
710 return CalculateKeypoint(exec->GetLeftEyeInnerCornerId(), "leic");
711 }
712
720 */
722 {
723 return CalculateKeypoint(exec->GetLeftEyeCentreId(), "lec");
724 }
725
733 */
735 {
736 return CalculateKeypoint(exec->GetLeftEyeOuterCornerId(), "leoc");
737 }
738
744 */
746 {
747 return CalculateKeypoint(exec->GetNoseRootId(), "nr");
748 }
749
757 */
759 {
760 return CalculateKeypoint(exec->GetNoseRightBottomId(), "nrb");
761 }
762
768 */
770 {
771 return CalculateKeypoint(exec->GetNoseTipId(), "nt");
772 }
773
781 */
783 {
784 return CalculateKeypoint(exec->GetNoseLeftBottomId(), "nlb");
785 }
786
792 */
794 {
795 return CalculateKeypoint(exec->GetNoseBottomId(), "nb");
796 }
797
805 */
807 {
808 return CalculateKeypoint(exec->GetMouthRightCornerId(), "mrc");
809 }
810
816 */
818 {
819 return CalculateKeypoint(exec->GetMouthCenterId(), "mc");
820 }
821
829 */
831 {
832 return CalculateKeypoint(exec->GetMouthLeftCornerId(), "mlc");
833 }
834
840 */
842 {
843 return CalculateKeypoint(exec->GetMouthUpperEdgeId(), "mue");
844 }
845
851 */
853 {
854 return CalculateKeypoint(exec->GetMouthLowerEdgeId(), "mle");
855 }
856
864 */
866 {
867 return CalculateKeypoint(exec->GetRightEyebrowOuterEndId(), "reoe");
868 }
869
877 */
879 {
880 return CalculateKeypoint(exec->GetRightEyebrowInnerEndId(), "reie");
881 }
882
890 */
892 {
893 return CalculateKeypoint(exec->GetLeftEyebrowInnerEndId(), "leie");
894 }
895
903 */
905 {
906 return CalculateKeypoint(exec->GetLeftEyebrowOuterEndId(), "leoe");
907 }
908
916 */
918 {
919 return CalculateKeypoint(exec->GetRightEdgeId(), "re");
920 }
921
927 */
929 {
930 return CalculateKeypoint(exec->GetChinTipId(), "cht");
931 }
932
940 */
942 {
943 return CalculateKeypoint(exec->GetLeftEdgeId(), "le");
944 }
945
949 */
950 [[nodiscard]] std::shared_ptr<Image> GetImage() const
951 {
952 return capture->image;
953 }
954
958 */
959 void WriteTo(Writer& writer) const final
960 {
961 const std::scoped_lock lock(keyPointsMux);
962 for (const auto& [id, serializableKeypoint] : keypoints)
963 {
964 writer.Write(serializableKeypoint.serializationKey, serializableKeypoint.keypoint);
965 }
966 }
967
968 private:
969 /*
970 * @brief Construct a new Keypoints object
971 *
972 * @param faceCapture original face image on which face was detected
973 * @param face face detected on the image
974 * @param executor is FaceExecutor
975 * @throws NullArgumentException when image is null
976 * @throws NullArgumentException when face is null
977 * @throws NullArgumentException when executor is null
978 */
979 Keypoints(std::shared_ptr<FaceCapture> faceCapture,
980 std::shared_ptr<void> face,
981 std::shared_ptr<FaceExecutor> executor)
982 : capture(std::move(faceCapture))
983 , faceItem(std::move(face))
984 , exec(std::move(executor))
985 {
986 if (capture == nullptr)
987 {
988 throw NullArgumentException("Face capture can not be null");
989 }
990 if (faceItem == nullptr)
991 {
992 throw NullArgumentException("face cannot be null");
993 }
994 if (exec == nullptr)
995 {
996 throw NullArgumentException("executor can not be null");
997 }
998 }
999
1000 Keypoint CalculateKeypoint(unsigned int id, const char* serializationKey)
1001 {
1002 const std::scoped_lock keyPointsLock(keyPointsMux);
1003
1004 const bool alreadyCalculated = keypoints.contains(id);
1005 if (!alreadyCalculated)
1006 {
1007 float score = {};
1008 float x = {};
1009 float y = {};
1010 exec->GetKeypoint(GlobalLogger::Get(), faceItem.get(), id, &score, &x, &y, ThrowOnError{});
1011
1012 keypoints.emplace(
1013 id,
1014 SerializableKeypoint{ serializationKey,
1015 Keypoint(Point{ static_cast<X>(x), static_cast<Y>(y) }, score) });
1016 }
1017 return keypoints[id].keypoint;
1018 }
1019
1020 std::shared_ptr<FaceCapture> capture;
1021 std::shared_ptr<void> faceItem;
1022 std::shared_ptr<FaceExecutor> exec;
1023 struct SerializableKeypoint
1024 {
1025 const char* serializationKey = nullptr;
1026 Keypoint keypoint;
1027 };
1028
1029 std::unordered_map<unsigned int, SerializableKeypoint> keypoints;
1030 mutable std::mutex keyPointsMux;
1031
1032 friend class Face;
1033 };
1034
1040 [[nodiscard]] std::shared_ptr<Keypoints> GetKeypoints() const
1041 {
1042 return keypoints;
1043 }
1044
1047 const std::shared_ptr<FaceCapture> capture;
1052 const unsigned int confidence;
1053
1064 [[nodiscard]] std::shared_ptr<CroppedFace> Crop(FaceCropConfiguration cfg) const
1065 {
1066 return std::shared_ptr<CroppedFace>(new CroppedFace(faceItem, capture, std::move(cfg), exec));
1067 }
1068
1077 [[nodiscard]] Rectangle DetectionRectangle() const
1078 {
1079 return boundingBox;
1080 }
1090 [[nodiscard]] std::vector<uint8_t> ToIsoImage(ImageEncoder& encoder) const
1091 {
1092 auto isoEncoder = IsoImageEncoder(*this, encoder);
1093 return isoEncoder.Encode();
1094 }
1095
1103 std::shared_ptr<ExtractedFace> Extract(const FaceExtractorConfig& cfg)
1104 {
1105 log.LogInfo("Face extraction for %v with cfg %v ...", capture, cfg);
1106
1107 std::vector<uint8_t> templData;
1108
1109 exec->Extract(
1110 faceItem.get(),
1111 +[](void* container, size_t size) -> uint8_t*
1112 {
1113 auto* data = static_cast<std::vector<uint8_t>*>(container);
1114 data->resize(size);
1115 return data->data();
1116 },
1117 &templData,
1118 static_cast<unsigned int>(cfg.GetExtractor()),
1119 ThrowOnError{});
1120
1121 auto face = shared_from_this();
1122 auto extractedFace = ExtractedFace::Create(face, std::move(templData), exec);
1123
1124 log.LogInfo("Face extraction result %v", extractedFace);
1125
1126 return extractedFace;
1127 }
1128
1134 std::shared_ptr<ExtractedFace> Extract()
1135 {
1136 auto cfg = FaceExtractorConfig::Default();
1137 return Extract(cfg);
1138 }
1139
1144 void WriteTo(Writer& writer) const final
1145 {
1146 writer.Write("c", confidence);
1147 writer.Write("k", keypoints);
1148 writer.Write("cp", capture);
1149 for (auto const& attribute : attributes)
1150 {
1151 const std::scoped_lock lock(attribute.mux);
1152 if (attribute.value.has_value())
1153 {
1154 writer.Write(attribute.serializationKey, attribute.value.value());
1155 }
1156 }
1157 {
1158 const std::scoped_lock lock(fastPassiveLivenessMux);
1159 if (fastPassiveLiveness.has_value())
1160 {
1161 writer.Write("ulf", fastPassiveLiveness.value());
1162 }
1163 }
1164 {
1165 const std::scoped_lock lock(accuratePassiveLivenessMux);
1166 if (accuratePassiveLiveness.has_value())
1167 {
1168 writer.Write("ula", accuratePassiveLiveness.value());
1169 }
1170 }
1171 }
1172
1180 bool IsSameAs(const Face& face) const
1181 {
1182 return this == &face;
1183 }
1184
1192 bool operator==(const Face& f) const
1193 {
1194 if (this == &f)
1195 {
1196 return true;
1197 }
1198
1199 return *capture->image == *f.capture->image && capture->faceAttributes == f.capture->faceAttributes;
1200 }
1201
1209 bool operator!=(const Face& f) const
1210 {
1211 return !(*this == f);
1212 }
1213
1228 float Sharpness()
1229 {
1230 return CalculateAttribute(exec->GetSharpnessId(), "sr");
1231 }
1232
1248 float Brightness()
1249 {
1250 return CalculateAttribute(exec->GetBrightnessId(), "br");
1251 }
1252
1268 float Contrast()
1269 {
1270 return CalculateAttribute(exec->GetContrastId(), "ct");
1271 }
1272
1288 float UniqueIntensityLevels()
1289 {
1290 return CalculateAttribute(exec->GetUniqueIntensityLevelsId(), "uil");
1291 }
1292
1308 float Shadow()
1309 {
1310 return CalculateAttribute(exec->GetShadowId(), "sh");
1311 }
1312
1326 float NoseShadow()
1327 {
1328 return CalculateAttribute(exec->GetNoseShadowId(), "ns");
1329 }
1330
1346 float Specularity()
1347 {
1348 return CalculateAttribute(exec->GetSpecularityId(), "sp");
1349 }
1350
1365 float EyeGaze()
1366 {
1367 return CalculateAttribute(exec->GetEyeGazeId(), "eg");
1368 }
1369
1382 float RightEyeStatus()
1383 {
1384 return CalculateAttribute(exec->GetEyeStatusRId(), "esr");
1385 }
1386
1399 float LeftEyeStatus()
1400 {
1401 return CalculateAttribute(exec->GetEyeStatusLId(), "esl");
1402 }
1403
1414 float GlassStatus()
1415 {
1416 return CalculateAttribute(exec->GetGlassStatusId(), "gs");
1417 }
1418
1432 float HeavyFrame()
1433 {
1434 return CalculateAttribute(exec->GetHeavyFrameId(), "hf");
1435 }
1436
1450 float MouthStatus()
1451 {
1452 return CalculateAttribute(exec->GetMouthStatusId(), "ms");
1453 }
1454
1473 float BackgroundUniformity(uint8_t minimalBackgroundRatio)
1474 {
1475 static constexpr uint8_t MaxBackgroundRatio = 100;
1476 if (minimalBackgroundRatio > MaxBackgroundRatio)
1477 {
1479 "The minimal background ratio for face background uniformity MUST be in range <0,100>");
1480 }
1481 AttributeConfiguration config;
1482 config.emplace_back(inno_FaceParams::BackgroundUniformityMinRatioName,
1483 std::to_string(minimalBackgroundRatio));
1484 return CalculateAttribute(exec->GetBackgroundUniformityId(), "bu", std::move(config));
1485 }
1486
1504 float BackgroundUniformity()
1505 {
1506 static constexpr uint8_t DefaultMinimalBackgroundRatio = 5;
1507 return BackgroundUniformity(DefaultMinimalBackgroundRatio);
1508 }
1509
1513 enum class AgeEstimationMode : uint8_t
1514 {
1521 BALANCED = 1,
1530 ACCURATE = 2
1531 };
1532
1542 float Age()
1543 {
1545 }
1546
1555 float Age(AgeEstimationMode mode)
1556 {
1557 AttributeConfiguration config;
1558 config.emplace_back(inno_FaceParams::AgeGenderMode, ToString(mode));
1559 return CalculateAttribute(exec->GetAgeId(), "age", std::move(config));
1560 }
1561
1574 float RightRedEye()
1575 {
1576 return CalculateAttribute(exec->GetRedEyeRId(), "rer");
1577 }
1578
1591 float LeftRedEye()
1592 {
1593 return CalculateAttribute(exec->GetRedEyeLId(), "rel");
1594 }
1595
1599 enum class GenderEstimationMode : uint8_t
1600 {
1608 BALANCED = 1,
1617 ACCURATE = 2
1618 };
1619
1631 float Gender()
1632 {
1634 }
1635
1647 float Gender(GenderEstimationMode mode)
1648 {
1649 AttributeConfiguration config;
1650 config.emplace_back(inno_FaceParams::AgeGenderMode, ToString(mode));
1651 return CalculateAttribute(exec->GetGenderId(), "gen", std::move(config));
1652 }
1653
1665 float EyeDistance()
1666 {
1667 return CalculateAttribute(exec->GetEyeDistanceId(), "ed");
1668 }
1669
1681 float RollAngle()
1682 {
1683 return CalculateAttribute(exec->GetRollAngleId(), "ra");
1684 }
1685
1694 float PitchAngle()
1695 {
1696 return CalculateAttribute(exec->GetPitchAngleId(), "pa");
1697 }
1698
1707 float YawAngle()
1708 {
1709 return CalculateAttribute(exec->GetYawAngleId(), "ya");
1710 }
1711
1718 float FaceSize()
1719 {
1720 return CalculateAttribute(exec->GetFaceSizeId(), "fs");
1721 }
1722
1732 float FaceRelativeArea()
1733 {
1734 return CalculateAttribute(exec->GetFaceRelativeAreaId(), "fra");
1735 }
1736
1747 {
1748 return CalculateAttribute(exec->GetFaceRelativeAreaInImageId(), "fri");
1749 }
1750
1761 float TintedGlasses()
1762 {
1763 return CalculateAttribute(exec->GetTintedGlassesId(), "tg");
1764 }
1765
1775 float WidthHeightRatio() const
1776 {
1777 return CalculateWidthHeightRatio();
1778 }
1779
1780 /// Mode of passive liveness calculation
1781 enum class PassiveLivenessMode : uint8_t
1782 {
1789 FAST,
1796 ACCURATE
1797 };
1816 }
1842 {
1843 if (mode == PassiveLivenessMode::FAST)
1844 {
1845 return CalculateFastPassiveLiveness();
1846 }
1847
1848 return CalculateAccuratePassiveLiveness();
1849 }
1850
1851 /// Face attributes IDs
1852 enum class AttributeID : uint8_t
1853 {
1856 CONFIDENCE,
1859 SHARPNESS,
1862 BRIGHTNESS,
1865 CONTRAST,
1868 UNIQUE_INTENSITY_LEVELS,
1871 SHADOW,
1874 NOSE_SHADOW,
1877 SPECULARITY,
1880 EYE_GAZE,
1883 RIGHT_EYE_STATUS,
1886 LEFT_EYE_STATUS,
1889 GLASS_STATUS,
1892 HEAVY_FRAME,
1895 MOUTH_STATUS,
1898 BACKGROUND_UNIFORMITY,
1901 AGE,
1904 RIGHT_RED_EYE,
1907 LEFT_RED_EYE,
1910 GENDER,
1913 EYE_DISTANCE,
1916 ROLL_ANGLE,
1919 PITCH_ANGLE,
1922 YAW_ANGLE,
1925 FACE_SIZE,
1928 FACE_RELATIVE_AREA,
1931 FACE_RELATIVE_AREA_IN_IMAGE,
1934 TINTED_GLASSES,
1937 WIDTH_HEIGHT_RATIO,
1938 };
1939
1940 Face(const Face&) = delete;
1941 Face(Face&&) = delete;
1942 Face& operator=(const Face&) = delete;
1943 Face& operator=(Face&&) = delete;
1944 virtual ~Face() = default;
1945 Face() = delete;
1946
1947 private:
1948 using AttributeConfiguration = std::vector<std::tuple<const char*, std::string>>;
1949 class Attribute
1950 {
1951 public:
1952 const char* serializationKey = nullptr;
1953 std::optional<float> value;
1954 AttributeConfiguration config;
1955 mutable std::mutex mux;
1956
1957 Attribute() = default;
1958 ~Attribute() = default;
1959 Attribute(const Attribute&) = delete;
1960 Attribute(Attribute&&) = delete;
1961 Attribute& operator=(const Attribute&) = delete;
1962 Attribute& operator=(Attribute&&) = delete;
1963 };
1964
1965 std::vector<Attribute> attributes;
1966 std::optional<float> fastPassiveLiveness;
1967 mutable std::mutex fastPassiveLivenessMux;
1968 std::optional<float> accuratePassiveLiveness;
1969 mutable std::mutex accuratePassiveLivenessMux;
1970 FormattingLogger log;
1971
1981 static std::shared_ptr<Face> Create(std::shared_ptr<FaceCapture> capture,
1982 std::shared_ptr<void> faceItem,
1983 Rectangle bb,
1984 unsigned int confidence,
1985 std::shared_ptr<FaceExecutor> exec = GlobalFaceExecutor::Get())
1986 {
1987 return std::shared_ptr<Face>(
1988 new Face(std::move(capture), std::move(bb), confidence, std::move(faceItem), std::move(exec)));
1989 }
1990
1991 Face(std::shared_ptr<FaceCapture> capt,
1992 Rectangle bb,
1993 unsigned int conf,
1994 std::shared_ptr<void> fi,
1995 std::shared_ptr<FaceExecutor> e)
1996 : capture(std::move(capt))
1997 , confidence(conf)
1998 , attributes(e->GetMaxId())
1999 , log(GlobalLogger::Get())
2000 , faceItem(std::move(fi))
2001 , boundingBox(std::move(bb))
2002 , exec(std::move(e))
2003 , keypoints(new Keypoints(capture, faceItem, exec))
2004 {
2005 if (exec == nullptr)
2006 {
2007 throw NullArgumentException("Could not create Face due to executor can not be null");
2008 }
2009
2010 if (capture == nullptr)
2011 {
2012 throw NullArgumentException("Could not create Face due to the face original capture can not be null");
2013 }
2014 }
2015
2016 float CalculateAttribute(unsigned int id, const char* serializationKey)
2017 {
2018 AttributeConfiguration config;
2019 return CalculateAttribute(id, serializationKey, std::move(config));
2020 }
2021 float CalculateAttribute(unsigned int id, const char* serializationKey, AttributeConfiguration&& config)
2022 {
2023 const std::scoped_lock attributesLock(attributes[id].mux);
2024 auto& attribute = attributes[id];
2025
2026 if (attribute.value.has_value() && config == attribute.config)
2027 {
2028 return attribute.value.value();
2029 }
2030
2031 std::vector<inno_FaceParams> params(config.size());
2032 std::transform(config.begin(),
2033 config.end(),
2034 params.begin(),
2035 [](const auto& c) { return inno_FaceParams{ std::get<0>(c), std::get<1>(c).c_str() }; });
2036
2037 float value =
2038 exec->GetAttribute(GlobalLogger::Get(), faceItem.get(), id, params.data(), params.size(), ThrowOnError{});
2039
2040 attribute.value = value;
2041 attribute.serializationKey = serializationKey;
2042 attribute.config = std::move(config);
2043
2044 return value;
2045 }
2046
2047 float CalculateAccuratePassiveLiveness()
2048 {
2049 const std::scoped_lock attributesLock(accuratePassiveLivenessMux);
2050
2051 if (accuratePassiveLiveness.has_value())
2052 {
2053 return accuratePassiveLiveness.value();
2054 }
2055
2056 float value = exec->GetPassiveLivenessAccurate(GlobalLogger::Get(), faceItem.get(), ThrowOnError{});
2057
2058 accuratePassiveLiveness = value;
2059
2060 return value;
2061 }
2062
2063 float CalculateFastPassiveLiveness()
2064 {
2065 const std::scoped_lock attributesLock(fastPassiveLivenessMux);
2066
2067 if (fastPassiveLiveness.has_value())
2068 {
2069 return fastPassiveLiveness.value();
2070 }
2071
2072 float value = exec->GetPassiveLivenessFast(GlobalLogger::Get(), faceItem.get(), ThrowOnError{});
2073
2074 fastPassiveLiveness = value;
2075
2076 return value;
2077 }
2078
2079 float CalculateWidthHeightRatio() const
2080 {
2081 auto width = capture->image->Width();
2082 auto height = capture->image->Height();
2083 if (width == 0 || height == 0)
2084 {
2085 return 0.F;
2086 }
2087 const float ratio = static_cast<float>(width) / static_cast<float>(height);
2088 return ratio;
2089 }
2090
2091 static std::string ToString(AgeEstimationMode mode)
2092 {
2093 switch (mode)
2094 {
2095 case AgeEstimationMode::BALANCED:
2096 return "balanced";
2097 case AgeEstimationMode::ACCURATE:
2098 return "accurate";
2099 }
2100
2101 throw EnrollmentInvalidArgumentException("Incorrect AgeEstimationMode '" +
2102 std::to_string(static_cast<uint8_t>(mode)) + "'");
2103 }
2104
2105 static std::string ToString(GenderEstimationMode mode)
2106 {
2107 switch (mode)
2108 {
2109 case GenderEstimationMode::BALANCED:
2110 return "balanced";
2111 case GenderEstimationMode::ACCURATE:
2112 return "accurate";
2113 }
2114
2115 throw EnrollmentInvalidArgumentException("Incorrect GenderEstimationMode '" +
2116 std::to_string(static_cast<uint8_t>(mode)) + "'");
2117 }
2118
2119 class IsoImage
2120 {
2121 public:
2122 explicit IsoImage(const Face& f)
2123 : face(f)
2124 {
2125 }
2126 IsoImage() = delete;
2127 ~IsoImage() = default;
2128 IsoImage(const IsoImage&) = delete;
2129 IsoImage(IsoImage&&) = delete;
2130 IsoImage& operator=(const IsoImage&) = delete;
2131 IsoImage& operator=(IsoImage&&) = delete;
2132
2133 void SetCompressionType(uint8_t ct)
2134 {
2135 compressionType = ct;
2136 }
2137
2138 std::vector<uint8_t> FillIsoImage(const std::vector<uint8_t>& encodedImage)
2139 {
2140 // General header contains 17 bytes.
2141 static constexpr size_t GeneralHeaderLength = 17;
2142
2143 // Quality Blocks are not used optional fields.
2144 static constexpr size_t NumberOfQualityBlocks = 0;
2145
2146 // Quality Block contains 5 bytes.
2147 static constexpr size_t SizeOfQualityBlock = 5;
2148
2149 // Landmark Points are not used optional fields.
2150 static constexpr size_t NumberOfLandmarkPoints = 0;
2151
2152 // Landmark Points contain 8 bytes.
2153 static constexpr size_t SizeOfLandmarkPoints = 8;
2154
2155 // Representation header contains 47 bytes + size of optional fields.
2156 static constexpr size_t RepresentationHeaderLength =
2157 47 + NumberOfQualityBlocks * SizeOfQualityBlock + NumberOfLandmarkPoints * SizeOfLandmarkPoints;
2158
2159 // Length of Image Data Block contains 4 bytes.
2160 static constexpr size_t ImageDataBlockLength = 4;
2161
2162 // Length of encoded image.
2163 auto imageLength = encodedImage.size();
2164
2165 // Representation length including the representation header length.
2166 auto representationLength = RepresentationHeaderLength + imageLength + ImageDataBlockLength;
2167
2168 // Record length with image data.
2169 auto recordLength = GeneralHeaderLength + representationLength;
2170
2171 std::vector<uint8_t> isoImage;
2172 isoImage.resize(recordLength);
2173
2174 FillGeneralHeader(isoImage, recordLength);
2175 FillRepresentationHeader(isoImage, representationLength);
2176 FillRepresentationBody(isoImage, encodedImage, imageLength);
2177
2178 return isoImage;
2179 }
2180
2181 private:
2182 static void ThrowWhenValueCannotFitInto4Bytes(size_t recordLength)
2183 {
2184 if (recordLength > static_cast<size_t>(std::numeric_limits<uint32_t>::max()))
2185 {
2186 throw EnrollmentRuntimeException("Invalid conversion size");
2187 }
2188 }
2189
2198 void FillGeneralHeader(std::vector<uint8_t>& isoImage, const size_t recordLength)
2199 {
2200 FillFormatIdentifier(isoImage);
2201 FillVersionNumber(isoImage);
2202 FillLengthOfRecord(isoImage, recordLength);
2203 FillNumberOfRepresentations(isoImage);
2204 FillCertificationFlag(isoImage);
2205 FilTemporalSemantics(isoImage);
2206 }
2207
2214 void FillFormatIdentifier(std::vector<uint8_t>& isoImage)
2215 {
2216 // Mandatory fields.
2217 isoImage[writeIndex++] = 'F';
2218 isoImage[writeIndex++] = 'A';
2219 isoImage[writeIndex++] = 'C';
2220 isoImage[writeIndex++] = '\0';
2221 }
2222
2232 void FillVersionNumber(std::vector<uint8_t>& isoImage)
2233 {
2234 // Mandatory fields.
2235 isoImage[writeIndex++] = '0';
2236 isoImage[writeIndex++] = '3';
2237 isoImage[writeIndex++] = '0';
2238 isoImage[writeIndex++] = '\0';
2239 }
2240
2250 void FillLengthOfRecord(std::vector<uint8_t>& isoImage, const size_t recordLength)
2251 {
2252 ThrowWhenValueCannotFitInto4Bytes(recordLength);
2253
2254 // Mandatory fields.
2255 isoImage[writeIndex++] = static_cast<uint8_t>(recordLength >> ThreeBytesBitsCount);
2256 isoImage[writeIndex++] = static_cast<uint8_t>((recordLength >> TwoBytesBitsCount) & ByteMask);
2257 isoImage[writeIndex++] = static_cast<uint8_t>((recordLength >> OneByteBitsCount) & ByteMask);
2258 isoImage[writeIndex++] = static_cast<uint8_t>(recordLength & ByteMask);
2259 }
2260
2267 void FillNumberOfRepresentations(std::vector<uint8_t>& isoImage)
2268 {
2269 // Mandatory fields.
2270 isoImage[writeIndex++] = 0x00;
2271 isoImage[writeIndex++] = 0x01;
2272 }
2273
2279 void FillCertificationFlag(std::vector<uint8_t>& isoImage)
2280 {
2281 isoImage[writeIndex++] = 0x00; // Mandatory field.
2282 }
2283
2291 void FilTemporalSemantics(std::vector<uint8_t>& isoImage)
2292 {
2293 // Mandatory fields.
2294 isoImage[writeIndex++] = 0x00;
2295 isoImage[writeIndex++] = 0x00;
2296 }
2297
2311 void FillRepresentationHeader(std::vector<uint8_t>& isoImage, size_t representationLength)
2312 {
2313 FillRepresentationLength(isoImage, representationLength);
2314 FillCaptureDateTime(isoImage);
2315 FillCaptureDeviceTechnologyIdentifier(isoImage);
2316 FillCaptureDeviceVendorIdentifier(isoImage);
2317 FillCaptureDeviceTypeIdentifier(isoImage);
2318 FillNumberOfQualityBlocks(isoImage);
2319 FillFacialInformation(isoImage);
2320 FillImageInformation(isoImage);
2321 }
2322
2334 void FillRepresentationLength(std::vector<uint8_t>& isoImage, size_t representationLength)
2335 {
2336 ThrowWhenValueCannotFitInto4Bytes(representationLength);
2337
2338 // Mandatory fields.
2339 isoImage[writeIndex++] = static_cast<uint8_t>(representationLength >> ThreeBytesBitsCount);
2340 isoImage[writeIndex++] = static_cast<uint8_t>((representationLength >> TwoBytesBitsCount) & ByteMask);
2341 isoImage[writeIndex++] = static_cast<uint8_t>((representationLength >> OneByteBitsCount) & ByteMask);
2342 isoImage[writeIndex++] = static_cast<uint8_t>(representationLength & ByteMask);
2343 }
2344
2352 void FillCaptureDateTime(std::vector<uint8_t>& isoImage)
2353 {
2354 // Mandatory fields.
2355 static constexpr uint8_t DummyValue = 0xff;
2356 isoImage[writeIndex++] = DummyValue; // year
2357 isoImage[writeIndex++] = DummyValue; // year
2358 isoImage[writeIndex++] = DummyValue; // month
2359 isoImage[writeIndex++] = DummyValue; // day
2360 isoImage[writeIndex++] = DummyValue; // hour
2361 isoImage[writeIndex++] = DummyValue; // minute
2362 isoImage[writeIndex++] = DummyValue; // second
2363 isoImage[writeIndex++] = DummyValue; // millisecond
2364 isoImage[writeIndex++] = DummyValue; // millisecond
2365 }
2366
2375 void FillCaptureDeviceTechnologyIdentifier(std::vector<uint8_t>& isoImage)
2376 {
2377 const FaceCaptureDeviceTechnology& technology =
2378 face.capture->faceAttributes.GetCaptureDeviceTechnology();
2379 isoImage[writeIndex++] =
2380 static_cast<uint8_t>(FaceToIsoCaptureDeviceTechnology(technology)); // Mandatory field.
2381 }
2382
2392 void FillCaptureDeviceVendorIdentifier(std::vector<uint8_t>& isoImage)
2393 {
2394 // Mandatory fields.
2395 const FaceCaptureDeviceVendorID& vendor = face.capture->faceAttributes.GetCaptureDeviceVendorID();
2396 isoImage[writeIndex++] = static_cast<uint8_t>(static_cast<unsigned int>(vendor) >> OneByteBitsCount);
2397 isoImage[writeIndex++] = static_cast<uint8_t>(static_cast<unsigned int>(vendor) & ByteMask);
2398 }
2399
2409 void FillCaptureDeviceTypeIdentifier(std::vector<uint8_t>& isoImage)
2410 {
2411 // Mandatory fields.
2412 const FaceCaptureDeviceTypeID type = face.capture->faceAttributes.GetCaptureDeviceTypeID();
2413 isoImage[writeIndex++] = static_cast<uint8_t>(static_cast<unsigned int>(type) >> OneByteBitsCount);
2414 isoImage[writeIndex++] = static_cast<uint8_t>(static_cast<unsigned int>(type) & ByteMask);
2415 }
2416
2423 void FillNumberOfQualityBlocks(std::vector<uint8_t>& isoImage)
2424 {
2425 isoImage[writeIndex++] = 0x00; // Not used
2426 }
2427
2432 void FillQualityBlockData(std::vector<uint8_t>& isoImage)
2433 {
2434 // Optional fields.
2435 FillQualityScore(isoImage);
2436 FillQualityAlgorithmVendorId(isoImage);
2437 FillQualityAlgorithmId(isoImage);
2438 }
2439
2449 void FillQualityScore(std::vector<uint8_t>& isoImage)
2450 {
2451 isoImage[writeIndex++] = 0x00; // Optional field.
2452 }
2453
2461 void FillQualityAlgorithmVendorId(std::vector<uint8_t>& isoImage)
2462 {
2463 // Optional fields.
2464 isoImage[writeIndex++] = 0x00;
2465 isoImage[writeIndex++] = 0x00;
2466 }
2467
2475 void FillQualityAlgorithmId(std::vector<uint8_t>& isoImage)
2476 {
2477 // Optional fields.
2478 isoImage[writeIndex++] = 0x00;
2479 isoImage[writeIndex++] = 0x00;
2480 }
2481
2489 void FillFacialInformation(std::vector<uint8_t>& isoImage)
2490 {
2491 FillNumberOfLandmarkPoints(isoImage);
2492 FillGender(isoImage);
2493 FillEyeColour(isoImage);
2494 FillHairColour(isoImage);
2495 FillSubjectHeight(isoImage);
2496 FillPropertyMask(isoImage);
2497 FillExpressionMask(isoImage);
2498 FillPoseAngle(isoImage);
2499 FillPoseAngleUncertainty(isoImage);
2500 }
2501
2508 void FillNumberOfLandmarkPoints(std::vector<uint8_t>& isoImage)
2509 {
2510 // Not used
2511 isoImage[writeIndex++] = 0x00;
2512 isoImage[writeIndex++] = 0x00;
2513 }
2514
2520 void FillGender(std::vector<uint8_t>& isoImage)
2521 {
2522 isoImage[writeIndex++] = 0x00; // Mandatory field.
2523 }
2524
2531 void FillEyeColour(std::vector<uint8_t>& isoImage)
2532 {
2533 isoImage[writeIndex++] = 0x00; // Mandatory field.
2534 }
2535
2541 void FillHairColour(std::vector<uint8_t>& isoImage)
2542 {
2543 isoImage[writeIndex++] = 0x00; // Mandatory field.
2544 }
2545
2551 void FillSubjectHeight(std::vector<uint8_t>& isoImage)
2552 {
2553 isoImage[writeIndex++] = 0x00; // Mandatory field.
2554 }
2555
2562 void FillPropertyMask(std::vector<uint8_t>& isoImage)
2563 {
2564 // Mandatory fields.
2565 isoImage[writeIndex++] = 0x00;
2566 isoImage[writeIndex++] = 0x00;
2567 isoImage[writeIndex++] = 0x00;
2568 }
2569
2576 void FillExpressionMask(std::vector<uint8_t>& isoImage)
2577 {
2578 // Mandatory fields.
2579 isoImage[writeIndex++] = 0x00;
2580 isoImage[writeIndex++] = 0x00;
2581 }
2582
2592 void FillPoseAngle(std::vector<uint8_t>& isoImage)
2593 {
2594 // Mandatory fields.
2595 isoImage[writeIndex++] = 0x00;
2596 isoImage[writeIndex++] = 0x00;
2597 isoImage[writeIndex++] = 0x00;
2598 }
2599
2608 void FillPoseAngleUncertainty(std::vector<uint8_t>& isoImage)
2609 {
2610 // Mandatory fields.
2611 isoImage[writeIndex++] = 0x00;
2612 isoImage[writeIndex++] = 0x00;
2613 isoImage[writeIndex++] = 0x00;
2614 }
2615
2623 void Fill2D3DLandmarkPoints(std::vector<uint8_t>& isoImage)
2624 {
2625 FillLandmarkPointType(isoImage);
2626 FillLandmarkPointCode(isoImage);
2627 FillLandmarkXCoordinate(isoImage);
2628 FillLandmarkYCoordinate(isoImage);
2629 FillLandmarkZCoordinate(isoImage);
2630 }
2631
2638 void FillLandmarkPointType(std::vector<uint8_t>& isoImage)
2639 {
2640 isoImage[writeIndex++] = 0x00;
2641 }
2642
2649 void FillLandmarkPointCode(std::vector<uint8_t>& isoImage)
2650 {
2651 isoImage[writeIndex++] = 0x00;
2652 }
2653
2658 void FillLandmarkXCoordinate(std::vector<uint8_t>& isoImage)
2659 {
2660 isoImage[writeIndex++] = 0x00;
2661 isoImage[writeIndex++] = 0x00;
2662 }
2663
2668 void FillLandmarkYCoordinate(std::vector<uint8_t>& isoImage)
2669 {
2670 isoImage[writeIndex++] = 0x00;
2671 isoImage[writeIndex++] = 0x00;
2672 }
2673
2678 void FillLandmarkZCoordinate(std::vector<uint8_t>& isoImage)
2679 {
2680 isoImage[writeIndex++] = 0x00;
2681 isoImage[writeIndex++] = 0x00;
2682 }
2683
2691 void FillImageInformation(std::vector<uint8_t>& isoImage)
2692 {
2693 FaceImageType(isoImage);
2694 ImageDataType(isoImage);
2695 ImageWidth(isoImage);
2696 ImageHeight(isoImage);
2697 SpatialSamplingRateLevel(isoImage);
2698 PostAcquisitionProcessing(isoImage);
2699 CrossReference(isoImage);
2700 ImageColourSpace(isoImage);
2701 }
2702
2709 void FaceImageType(std::vector<uint8_t>& isoImage)
2710 {
2711 isoImage[writeIndex++] = static_cast<uint8_t>(
2712 FaceToIsoImageType(face.capture->faceAttributes.GetFaceImageType())); // Mandatory field.
2713 }
2714
2722 void ImageDataType(std::vector<uint8_t>& isoImage)
2723 {
2724 isoImage[writeIndex++] = compressionType; // Mandatory field.
2725 }
2726
2733 void ImageWidth(std::vector<uint8_t>& isoImage)
2734 {
2735 // Mandatory fields.
2736 isoImage[writeIndex++] = static_cast<uint8_t>(face.capture->image->Width() >> OneByteBitsCount);
2737 isoImage[writeIndex++] = static_cast<uint8_t>(face.capture->image->Width() & ByteMask);
2738 }
2739
2746 void ImageHeight(std::vector<uint8_t>& isoImage)
2747 {
2748 // Mandatory fields.
2749 isoImage[writeIndex++] = static_cast<uint8_t>(face.capture->image->Height() >> OneByteBitsCount);
2750 isoImage[writeIndex++] = static_cast<uint8_t>(face.capture->image->Height() & ByteMask);
2751 }
2752
2762 void SpatialSamplingRateLevel(std::vector<uint8_t>& isoImage)
2763 {
2764 isoImage[writeIndex++] = 0x00; // Mandatory field.
2765 }
2766
2776 void PostAcquisitionProcessing(std::vector<uint8_t>& isoImage)
2777 {
2778 // Mandatory fields.
2779 isoImage[writeIndex++] = 0x00;
2780 isoImage[writeIndex++] = 0x00;
2781 }
2782
2792 void CrossReference(std::vector<uint8_t>& isoImage)
2793 {
2794 isoImage[writeIndex++] = 0x00; // Mandatory field.
2795 }
2796
2804 void ImageColourSpace(std::vector<uint8_t>& isoImage)
2805 {
2806 isoImage[writeIndex++] = 0x00; // Mandatory field.
2807 }
2808
2816 void FillRepresentationBody(std::vector<uint8_t>& isoImage,
2817 const std::vector<uint8_t>& encodedImage,
2818 size_t imageLength)
2819 {
2820 FillImageDataLength(isoImage, imageLength);
2821 FillImageData(isoImage, encodedImage);
2822 }
2823
2830 void FillImageDataLength(std::vector<uint8_t>& isoImage, size_t imageLength)
2831 {
2832 ThrowWhenValueCannotFitInto4Bytes(imageLength);
2833 // Mandatory fields.
2834 isoImage[writeIndex++] = static_cast<uint8_t>(imageLength >> ThreeBytesBitsCount);
2835 isoImage[writeIndex++] = static_cast<uint8_t>((imageLength >> TwoBytesBitsCount) & ByteMask);
2836 isoImage[writeIndex++] = static_cast<uint8_t>((imageLength >> OneByteBitsCount) & ByteMask);
2837 isoImage[writeIndex++] = static_cast<uint8_t>(imageLength & ByteMask);
2838 }
2839
2847 void FillImageData(std::vector<uint8_t>& isoImage, const std::vector<uint8_t>& encodedImage)
2848 {
2849 std::copy(encodedImage.begin(),
2850 encodedImage.end(),
2851 std::next(isoImage.begin(), static_cast<ptrdiff_t>(writeIndex))); // Mandatory field.
2852 writeIndex += encodedImage.size();
2853 }
2854
2855 size_t writeIndex = 0U;
2856 const Face& face;
2857 static constexpr uint8_t NoCompressionType = 255;
2858 uint8_t compressionType = NoCompressionType;
2859 static constexpr unsigned int OneByteBitsCount = 8U;
2860 static constexpr unsigned int TwoBytesBitsCount = 16U;
2861 static constexpr unsigned int ThreeBytesBitsCount = 24U;
2862 static constexpr unsigned int ByteMask = 0xffU;
2863 };
2864
2865 class IsoImageEncoder : public ImageEncoderVisitor
2866 {
2867 public:
2875 std::vector<uint8_t> Encode()
2876 {
2877 // Get necessary image data for creating iso image.
2878 encoder.Accept(*this);
2879
2880 // Get image data in requested format.
2881 auto encodedImage = face.capture->image->EncodeIn(encoder);
2882
2883 return isoImage.FillIsoImage(encodedImage);
2884 }
2885
2886 void Visit(const WsqImageEncoder& /* encoder */) final
2887 {
2888 throw EnrollmentInvalidArgumentException("Could not create ISO image for WSQ image format");
2889 }
2890
2891 void Visit(const JpgImageEncoder& /* encoder */) final
2892 {
2893 throw EnrollmentInvalidArgumentException("Could not create ISO image for JPG image format");
2894 }
2895
2896 void Visit(const Jp2ImageEncoder& jp2Encoder) final
2897 {
2898 if (jp2Encoder.IsLossy())
2899 {
2900 // According to table of image data type codes, JPEG 2000 lossy has compression code 1.
2901 isoImage.SetCompressionType(1);
2902 }
2903 else
2904 {
2905 // According to table of image data type codes, JPEG 2000 lossless has compression code 2.
2906 isoImage.SetCompressionType(2);
2907 }
2908 }
2909
2910 void Visit(const PngImageEncoder& /* encoder */) final
2911 {
2912 // According to table of image data type codes, PNG has compression code 3.
2913 isoImage.SetCompressionType(3);
2914 }
2915
2916 void Visit(const IRawImageEncoder& /* encoder */) final
2917 {
2918 throw EnrollmentInvalidArgumentException("Could not create ISO image for IRAW image format");
2919 }
2920
2921 void Visit(const BmpImageEncoder& /* encoder */) final
2922 {
2923 throw EnrollmentInvalidArgumentException("Could not create ISO image for BMP image format");
2924 }
2925
2926 void Visit(const TiffImageEncoder& /* encoder */) final
2927 {
2928 throw EnrollmentInvalidArgumentException("Could not create ISO image for TIFF image format");
2929 }
2930
2931 void Visit(const WebpImageEncoder& /* encoder */) final
2932 {
2933 throw EnrollmentInvalidArgumentException("Could not create ISO image for WEBP image format");
2934 }
2935
2936 // We can use references because this is inner class of Print and we always know the usage.
2937 // The references will be valid in whole class lifetime.
2938 IsoImageEncoder(const Face& f, ImageEncoder& e)
2939 : face(f)
2940 , encoder(e)
2941 , isoImage(IsoImage(f))
2942 {
2943 }
2944 IsoImageEncoder() = delete;
2945 virtual ~IsoImageEncoder() = default;
2946 IsoImageEncoder(const IsoImageEncoder&) = delete;
2947 IsoImageEncoder(IsoImageEncoder&&) = delete;
2948 IsoImageEncoder& operator=(const IsoImageEncoder&) = delete;
2949 IsoImageEncoder& operator=(IsoImageEncoder&&) = delete;
2950
2951 private:
2952 const Face& face;
2953 ImageEncoder& encoder;
2954 IsoImage isoImage;
2955 };
2956
2957 std::shared_ptr<void> faceItem;
2958 Rectangle boundingBox;
2959 std::shared_ptr<FaceExecutor> exec;
2960 std::shared_ptr<Keypoints> keypoints;
2961
2962 friend class FaceDetector;
2963 };
2965 inline void ExtractedFace::WriteTo(Writer& writer) const
2966 {
2967 writer.Write("f", face);
2968 FaceTemplate::WriteTo(writer);
2969 }
2970
2971 inline std::ostream& operator<<(std::ostream& os, Face::AttributeID a)
2972 {
2973 switch (a)
2974 {
2976 os << "CONFIDENCE";
2977 break;
2979 os << "SHARPNESS";
2980 break;
2982 os << "BRIGHTNESS";
2983 break;
2985 os << "CONTRAST";
2986 break;
2988 os << "UNIQUE_INTENSITY_LEVELS";
2989 break;
2991 os << "SHADOW";
2992 break;
2994 os << "NOSE_SHADOW";
2995 break;
2997 os << "SPECULARITY";
2998 break;
3000 os << "EYE_GAZE";
3001 break;
3003 os << "RIGHT_EYE_STATUS";
3004 break;
3006 os << "LEFT_EYE_STATUS";
3007 break;
3009 os << "GLASS_STATUS";
3010 break;
3012 os << "HEAVY_FRAME";
3013 break;
3015 os << "MOUTH_STATUS";
3016 break;
3018 os << "BACKGROUND_UNIFORMITY";
3019 break;
3021 os << "AGE";
3022 break;
3024 os << "RIGHT_RED_EYE";
3025 break;
3027 os << "LEFT_RED_EYE";
3028 break;
3030 os << "GENDER";
3031 break;
3033 os << "EYE_DISTANCE";
3034 break;
3036 os << "ROLL_ANGLE";
3037 break;
3039 os << "PITCH_ANGLE";
3040 break;
3042 os << "YAW_ANGLE";
3043 break;
3045 os << "FACE_SIZE";
3046 break;
3048 os << "FACE_RELATIVE_AREA";
3049 break;
3051 os << "FACE_RELATIVE_AREA_IN_IMAGE";
3052 break;
3054 os << "TINTED_GLASSES";
3055 break;
3057 os << "WIDTH_HEIGHT_RATIO";
3058 break;
3059 }
3060 return os;
3061 }
3062
3063} // namespace inno
3064
3065namespace inno
3066{
3067 inline Rectangle FaceCapture::BoundingBoxesShape::GetFaceDetectionBox(const std::shared_ptr<Face>& face)
3068 {
3069 return face->DetectionRectangle();
3070 }
3071} // namespace inno
3072// NOLINTEND(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes,cppcoreguidelines-avoid-const-or-ref-data-members)
Represents a face cropped from the original face capture.
Definition Face.h:360
Rectangle GetCropRectangle() const
Gets the crop region of the face within the image.
Definition Face.h:423
std::shared_ptr< Image > FaceAreaMask() const
Creates an image representing the mask of the detected face in the original FaceCapture,...
Definition Face.h:456
std::shared_ptr< Image > FaceAreaSegment() const
Creates an image of the detected face in the original FaceCapture, with a transparent surrounding are...
Definition Face.h:535
bool IsCropRegionInsideImage() const
Checks if the crop region is entirely inside the image.
Definition Face.h:439
std::shared_ptr< FaceCapture > GetFaceCapture() const
Retrieves the face capture from the cropped region.
Definition Face.h:366
std::shared_ptr< Image > FaceAreaSegment(const RGB &color) const
Creates an image of the detected face in the original FaceCapture, with the surrounding area replaced...
Definition Face.h:495
Base exception for all enrollment-sdk invalid argument exceptions.
Definition EnrollmentException.h:96
ExtractedFace is ICF Template created by FaceExtractor with Face that was extracted.
Definition Face.h:291
void WriteTo(Writer &writer) const final
Function serializes ExtractedFace via provided Writer.
Definition Face.h:2964
const std::shared_ptr< Face > face
Face that is used to template extraction.
Definition Face.h:294
static std::vector< std::shared_ptr< FaceTemplate > > ToTemplates(const std::vector< std::shared_ptr< ExtractedFace > > &faces)
Converts a vector of ExtractedFace objects into a vector of FaceTemplate objects.
Definition Face.h:305
static std::shared_ptr< FaceCapture > Create(std::shared_ptr< Image > img, const FaceAttributes &fa=FaceAttributes())
Constructor of FaceCapture.
Definition FaceCapture.h:74
Face crop configuration.
Definition FaceCropConfiguration.h:23
FaceDetector implements detection by means of Innovatrics IFace.
Definition FaceDetector.h:31
It contains extraction configuration.
Definition Face.h:45
Type GetExtractor() const
Function gets extractor type.
Definition Face.h:85
void WriteTo(Writer &writer) const final
Function serializes configuration via provided Writer.
Definition Face.h:94
Type
Type of neural network extractor.
Definition Face.h:51
@ BALANCED
Face templates suitable for verification/identification of high accuracy are created when balanced mo...
Definition Face.h:65
@ ACCURATE
Face templates suitable for verification/identification of very high accuracy are created when accura...
Definition Face.h:58
@ FAST
Face templates suitable for verification of fairly good accuracy are created when fast mode is used.
Definition Face.h:71
static FaceExtractorConfig Default()
Provides default configuration.
Definition Face.h:105
void SetExtractor(Type value)
Function sets type of extractor.
Definition Face.h:77
FaceExtractorConfig()=default
Constructs default configuration.
FaceTemplate is Innovatrics proprietary face template.
Definition Face.h:132
FaceTemplate(const std::vector< uint8_t > &templ, std::shared_ptr< FaceExecutor > executor)
Construct a new FaceTemplate object, copy template data.
Definition Face.h:228
FaceTemplate(std::vector< uint8_t > &&templ)
Construct a new FaceTemplate object GlobalFaceExecutor is used.
Definition Face.h:209
void WriteTo(Writer &writer) const override
Function serializes FaceTemplate via provided Writer.
Definition Face.h:175
std::string GetVersion() const
Provides version information of Innovatrics proprietary algorithm used to create the face template.
Definition Face.h:159
const std::vector< uint8_t > data
Template data.
Definition Face.h:135
FaceTemplate(const std::vector< uint8_t > &templ)
Construct a new FaceTemplate object, copy template data GlobalFaceExecutor is used.
Definition Face.h:249
FaceSimilarityScore SimilarWith(const FaceTemplate &gallery) const
Calculates FaceSimilarityScore for given FaceTemplate.
Definition Face.h:143
FaceTemplate(std::vector< uint8_t > &&templ, std::shared_ptr< FaceExecutor > executor)
Construct a new FaceTemplate object.
Definition Face.h:188
It holds all attributes related to a facial key point.
Definition Face.h:602
void WriteTo(Writer &writer) const final
Write itself into writer.
Definition Face.h:630
float GetScore() const
Retrieve reliability score of the key point.
Definition Face.h:621
Point GetPosition() const
Retrieve position coordinates of the key point in the image.
Definition Face.h:610
It holds all facial keypoints detected on a FaceCapture image.
Definition Face.h:658
void WriteTo(Writer &writer) const final
Function serializes keypoints via provided Writer.
Definition Face.h:958
Keypoint LeftEyeOuterCorner()
Key point for evaluating reliability of outer corner of left eye.
Definition Face.h:733
Keypoint RightEyeOuterCorner()
Key point for evaluating reliability of right eye outer corner.
Definition Face.h:668
Keypoint RightEyeCentre()
Key point for evaluating reliability of right eye centre.
Definition Face.h:681
Keypoint RightEyebrowInnerEnd()
Key point for evaluating reliability of inner end of right eyebrow.
Definition Face.h:877
Keypoint LeftEyebrowOuterEnd()
Key point for evaluating reliability of outer end of left eyebrow.
Definition Face.h:903
Keypoint RightEyebrowOuterEnd()
Key point for evaluating reliability of outer end of right eyebrow.
Definition Face.h:864
std::shared_ptr< Image > GetImage() const
Get image related to the detected keypoints.
Definition Face.h:949
Keypoint MouthLeftCorner()
Key point for evaluating reliability of left corner of mouth.
Definition Face.h:829
Keypoint NoseBottom()
Key point for evaluating reliability of bottom of nose.
Definition Face.h:792
Keypoint MouthRightCorner()
Key point for evaluating reliability of right corner of mouth.
Definition Face.h:805
Keypoint NoseRightBottom()
Key point for evaluating reliability of right bottom of nose.
Definition Face.h:757
Keypoint LeftEyebrowInnerEnd()
Key point for evaluating reliability of inner end of left eyebrow.
Definition Face.h:890
Keypoint MouthCenter()
Key point for evaluating reliability of center of mouth.
Definition Face.h:816
Keypoint NoseRoot()
Key point for evaluating reliability of nose root.
Definition Face.h:744
Keypoint ChinTip()
Key point for evaluating reliability of tip of chin.
Definition Face.h:927
Keypoint NoseTip()
Key point for evaluating reliability of nose tip.
Definition Face.h:768
Keypoint RightEdge()
Key point for evaluating reliability of right edge of face.
Definition Face.h:916
Keypoint LeftEyeCentre()
Key point for evaluating reliability of left eye centre.
Definition Face.h:720
Keypoint LeftEdge()
Key point for evaluating reliability of left edge of face.
Definition Face.h:940
Keypoint RightEyeInnerCorner()
Key point for evaluating reliability of inner corner of right eye.
Definition Face.h:694
Keypoint LeftEyeInnerCorner()
Key point for evaluating reliability of inner corner of left eye.
Definition Face.h:707
Keypoint NoseLeftBottom()
Key point for evaluating reliability of left bottom of nose.
Definition Face.h:781
Keypoint MouthLowerEdge()
Key point for evaluating reliability of lower edge of mouth.
Definition Face.h:851
Keypoint MouthUpperEdge()
Key point for evaluating reliability of upper edge of mouth.
Definition Face.h:840
It holds all functions and data related to Face manipulation.
Definition Face.h:594
float GlassStatus()
Attribute for evaluating glasses presence.
Definition Face.h:1413
std::shared_ptr< ExtractedFace > Extract()
This function creates a template for the detected face with default FaceExtractorConfig.
Definition Face.h:1133
float BackgroundUniformity(uint8_t minimalBackgroundRatio)
Attribute used to measure background uniformity in the close area around the detected face in the ori...
Definition Face.h:1472
float Age(AgeEstimationMode mode)
Attribute for evaluating age of subject using the face.
Definition Face.h:1554
const std::shared_ptr< FaceCapture > capture
Provides the original FaceCapture.
Definition Face.h:1046
float EyeDistance()
Attribute used to measure the distance between the eyes in pixels for the detected face in the origin...
Definition Face.h:1664
void WriteTo(Writer &writer) const final
Function serializes Face via provided Writer.
Definition Face.h:1143
float RightRedEye()
Attribute for evaluating whether red-eye effect is not present on right eye.
Definition Face.h:1573
float Gender()
Attribute for evaluating gender of subject.
Definition Face.h:1630
std::shared_ptr< ExtractedFace > Extract(const FaceExtractorConfig &cfg)
This function creates a template for the detected face.
Definition Face.h:1102
AgeEstimationMode
Specifies the level of compromise between age estimation speed and accuracy.
Definition Face.h:1513
@ BALANCED
Provides the fastest processing speed but the lowest age estimation accuracy compared to ACCURATE mod...
Definition Face.h:1520
@ ACCURATE
Provides better age estimation accuracy compared to BALANCED mode.
Definition Face.h:1529
float NoseShadow()
Nose Shadow attribute for evaluating whether eyes or a nose don't cast sharp shadows.
Definition Face.h:1325
float Brightness()
Brightness attribute used to measure the brightness level of an area of the detected face in the orig...
Definition Face.h:1247
float BackgroundUniformity()
Attribute used to measure background uniformity in the close area around the detected face in the ori...
Definition Face.h:1503
std::shared_ptr< CroppedFace > Crop(FaceCropConfiguration cfg) const
Crops the detected face from the original face capture.
Definition Face.h:1063
std::vector< uint8_t > ToIsoImage(ImageEncoder &encoder) const
Function creates ISO image based on ISO/IEC 19794-5 (Face image data).
Definition Face.h:1089
float TintedGlasses()
Attribute for evaluating tinted glasses presence.
Definition Face.h:1760
float LeftRedEye()
Attribute for evaluating whether red-eye effect is not present on left eye.
Definition Face.h:1590
std::shared_ptr< Keypoints > GetKeypoints() const
Provides the facial keypoints detected on the face in the original face capture.
Definition Face.h:1039
float FaceRelativeAreaInImage()
Attribute representing the visible area of the detected face in the original face capture relative to...
Definition Face.h:1745
float RollAngle()
Attribute representing the head rotation angle around the Z-axis of the detected face in the original...
Definition Face.h:1680
float HeavyFrame()
Attribute for evaluating whether glasses with heavy frames are not present.
Definition Face.h:1431
float PitchAngle()
Attribute representing the head rotation angle around the X-axis of the detected face in the original...
Definition Face.h:1693
float PassiveLiveness(PassiveLivenessMode mode)
Attribute used to assess whether a detected face in the original face capture qualifies as live.
Definition Face.h:1840
bool operator!=(const Face &f) const
Compares if Face is not equal with other one.
Definition Face.h:1208
float Specularity()
Specularity attribute used to evaluate the presence of spotlights in an area of the detected face in ...
Definition Face.h:1345
float Gender(GenderEstimationMode mode)
Attribute for evaluating gender of subject.
Definition Face.h:1646
bool operator==(const Face &f) const
Compares if Face is equal with other one.
Definition Face.h:1191
float PassiveLiveness()
Attribute used to assess whether a detected face in the original face capture qualifies as live,...
Definition Face.h:1812
PassiveLivenessMode
Mode of passive liveness calculation.
Definition Face.h:1781
@ ACCURATE
Passive liveness mode with highest accuracy available but significantly slower as FAST mode.
Definition Face.h:1795
@ FAST
Passive liveness mode with best performance available but worse accuracy as ACCURATE mode.
Definition Face.h:1788
float WidthHeightRatio() const
Attribute representing width to height aspect ratio of the original face capture.
Definition Face.h:1774
float UniqueIntensityLevels()
Unique Intensity Levels attribute used to measure whether an area of the detected face in the origina...
Definition Face.h:1287
float Sharpness()
Sharpness attribute used to measure the sharpness level of an area of the detected face in the origin...
Definition Face.h:1227
float Shadow()
Shadow attribute used to evaluate whether an area of the detected face in the original face capture i...
Definition Face.h:1307
float LeftEyeStatus()
Attribute for evaluating left eye status.
Definition Face.h:1398
const unsigned int confidence
Provides confidence score of the face related to face detection.
Definition Face.h:1051
float RightEyeStatus()
Attribute for evaluating right eye status.
Definition Face.h:1381
float Contrast()
Contrast attribute used to measure the contrast level of an area of the detected face in the original...
Definition Face.h:1267
AttributeID
Face attributes IDs.
Definition Face.h:1852
@ EYE_DISTANCE
Attribute used to measure the distance between the eyes in pixels for the detected face in the origin...
Definition Face.h:1912
@ LEFT_RED_EYE
Attribute for evaluating whether red-eye effect is not present on left eye.
Definition Face.h:1906
@ LEFT_EYE_STATUS
Attribute for evaluating left eye status.
Definition Face.h:1885
@ BACKGROUND_UNIFORMITY
Attribute used to measure background uniformity in the close area around the detected face in the ori...
Definition Face.h:1897
@ BRIGHTNESS
Brightness attribute used to measure the brightness level of an area of the detected face in the orig...
Definition Face.h:1861
@ SHARPNESS
Sharpness attribute used to measure the sharpness level of an area of the detected face in the origin...
Definition Face.h:1858
@ TINTED_GLASSES
Attribute for evaluating tinted glasses presence.
Definition Face.h:1933
@ WIDTH_HEIGHT_RATIO
Attribute representing width to height aspect ratio of the original face capture.
Definition Face.h:1936
@ AGE
Attribute for evaluating age of subject using the face.
Definition Face.h:1900
@ YAW_ANGLE
Attribute representing the head rotation angle around the Y-axis of the detected face in the original...
Definition Face.h:1921
@ PITCH_ANGLE
Attribute representing the head rotation angle around the X-axis of the detected face in the original...
Definition Face.h:1918
@ GENDER
Attribute for evaluating gender of subject.
Definition Face.h:1909
@ MOUTH_STATUS
Attribute for evaluating mouth status.
Definition Face.h:1894
@ SHADOW
Shadow attribute used to evaluate whether an area of the detected face in the original face capture i...
Definition Face.h:1870
@ FACE_SIZE
Attribute representing face size - the maximum of eye distance and eye-mouth distance.
Definition Face.h:1924
@ CONFIDENCE
Provides confidence score of the face related to face detection.
Definition Face.h:1855
@ RIGHT_RED_EYE
Attribute for evaluating whether red-eye effect is not present on right eye.
Definition Face.h:1903
@ FACE_RELATIVE_AREA
Attribute representing the area of the detected face in the original face capture relative to the siz...
Definition Face.h:1927
@ FACE_RELATIVE_AREA_IN_IMAGE
Attribute representing the visible area of the detected face in the original face capture relative to...
Definition Face.h:1930
@ SPECULARITY
Specularity attribute used to evaluate the presence of spotlights in an area of the detected face in ...
Definition Face.h:1876
@ ROLL_ANGLE
Attribute representing the head rotation angle around the Z-axis of the detected face in the original...
Definition Face.h:1915
@ NOSE_SHADOW
Nose Shadow attribute for evaluating whether eyes or a nose don't cast sharp shadows.
Definition Face.h:1873
@ HEAVY_FRAME
Attribute for evaluating whether glasses with heavy frames are not present.
Definition Face.h:1891
@ UNIQUE_INTENSITY_LEVELS
Unique Intensity Levels attribute used to measure whether an area of the detected face in the origina...
Definition Face.h:1867
@ GLASS_STATUS
Attribute for evaluating glasses presence.
Definition Face.h:1888
@ EYE_GAZE
Eye Gaze attribute used to evaluate whether the gaze direction of the detected face in the original f...
Definition Face.h:1879
@ RIGHT_EYE_STATUS
Attribute for evaluating right eye status.
Definition Face.h:1882
@ CONTRAST
Contrast attribute used to measure the contrast level of an area of the detected face in the original...
Definition Face.h:1864
GenderEstimationMode
Specifies the level of compromise between age estimation speed and accuracy.
Definition Face.h:1599
@ BALANCED
Provides the fastest processing speed but the lowest gender estimation accuracy compared to ACCURATE ...
Definition Face.h:1607
float Age()
Attribute for evaluating age of subject using the face.
Definition Face.h:1541
float FaceSize()
Attribute representing face size - the maximum of eye distance and eye-mouth distance.
Definition Face.h:1717
float MouthStatus()
Attribute for evaluating mouth status.
Definition Face.h:1449
float FaceRelativeArea()
Attribute representing the area of the detected face in the original face capture relative to the siz...
Definition Face.h:1731
float EyeGaze()
Eye Gaze attribute used to evaluate whether the gaze direction of the detected face in the original f...
Definition Face.h:1364
bool IsSameAs(const Face &face) const
Returns true when argument is same object.
Definition Face.h:1179
Rectangle DetectionRectangle() const
Retrieves the bounding box of the detected face.
Definition Face.h:1076
float YawAngle()
Attribute representing the head rotation angle around the Y-axis of the detected face in the original...
Definition Face.h:1706
It provides functions with format specifier to compose and log message via provided Logger.
Definition FormattingLogger.h:601
Holds instance of FaceExecutor.
Definition FaceExecutor.h:1355
static std::shared_ptr< FaceExecutor > Get()
Provides current executor.
Definition FaceExecutor.h:1361
Holds instance of Logger.
Definition Logger.h:275
static std::shared_ptr< Logger > Get()
Provides current logger.
Definition Logger.h:281
The class is used to visit concrete encoder to get concrete data.
Definition ImageEncoder.h:81
Interface for image formatting converting to ImageType.
Definition ImageEncoder.h:106
static std::shared_ptr< Image > DecodeRawImage(const RawImage &raw, std::shared_ptr< ImageEncoder > originalEncoder=nullptr, std::shared_ptr< ImageExecutor > executor=GlobalImageExecutor::Get())
Creates Image from raw data.
Definition Image.h:200
When user uses not supported functionality.
Definition NotSupportedException.h:23
Null argument is not allowed.
Definition EnrollmentException.h:156
It holds X and Y coordinates of point.
Definition ImageAttribute.h:312
It holds RGB colors.
Definition ImageAttribute.h:862
unsigned char red
Red value of RGB color model. The value is in range <0,255>.
Definition ImageAttribute.h:865
unsigned char green
Green value of RGB color model. The value is in range <0,255>.
Definition ImageAttribute.h:867
unsigned char blue
Blue value of RGB color model. The value is in range <0,255>.
Definition ImageAttribute.h:869
Contains plain image data.
Definition ImageAttribute.h:135
@ GRAYSCALE
Raw data where image pixels are stored in grayscale format.
Definition ImageAttribute.h:146
@ BGR
Raw data where image pixels are stored in BGR format.
Definition ImageAttribute.h:153
@ BGRA
Raw data where image pixels are stored in BGR with alpha format.
Definition ImageAttribute.h:166
It holds rectangle vertexes, width, height.
Definition ImageAttribute.h:357
Provides interface for serialization of all classes.
Definition Writer.h:164
virtual void Write(const char *name, const Serializable &s)=0
Serialize serializable.
void WriteArray(const char *name, const std::vector< uint8_t > &value)
Serialize bytes from vector.
Definition Writer.h:233
static constexpr int FaceToIsoImageType(FaceImageType faceImageType)
Function converts FaceImageType to ISO face image type as defined in iso_19794-5_2011.
Definition FaceImageType.h:59
FaceImageType
Several face image types are introduced to define categories that satisfy requirements of some applic...
Definition FaceImageType.h:22
FaceCaptureDeviceTechnology
It indicates the class of device technology used to acquire the captured biometric sample iso_19794-5...
Definition FaceCaptureDeviceTechnology.h:21
static constexpr int FaceToIsoCaptureDeviceTechnology(FaceCaptureDeviceTechnology printCaptureDeviceTechnology)
Function converts FaceCaptureDeviceTechnology to ISO capture technology.
Definition FaceCaptureDeviceTechnology.h:48
unsigned int FaceSimilarityScore
It is similarity score between face Templates.
Definition SimilarityScore.h:69
@ FULL_NOT_ALIGNED
Crops bounding box provided by FaceCrop::FULL method as is from original FaceCapture.
Definition FaceCrop.h:41
@ TOKEN
Token Frontal Image cropping method defined in ISO/IEC 19794-5 standard.
Definition FaceCrop.h:38
@ FULL
Full Frontal Image cropping method defined in ISO/IEC 19794-5 standard.
Definition FaceCrop.h:32
@ TOKEN_FRONTAL
A Face Image Type that specifies frontal images with a specific geometric size and eye positioning ba...
Definition FaceImageType.h:42
@ FULL_FRONTAL
A Face Image Type that specifies frontal images with sufficient resolution for human examination as w...
Definition FaceImageType.h:34
@ BASIC
This is the fundamental Face Image Type that specifies a record format including header and represent...
Definition FaceImageType.h:26
int Y
Y coordinate.
Definition ImageAttribute.h:117
ImageDimension ImageHeight
Image Height.
Definition ImageAttribute.h:36
ImageDimension ImageWidth
Image Width.
Definition ImageAttribute.h:41
int X
X coordinate.
Definition ImageAttribute.h:112