Enrollment 28.2.0
Loading...
Searching...
No Matches
FaceCapture.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "enrollment/Export.h"
18#include <algorithm>
19#include <memory>
20#include <vector>
21
22// cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes: This is not a
23// problem because we are using them only as read only.
24// cppcoreguidelines-avoid-const-or-ref-data-members: We design te API with const member variables instead of
25// implementing getter methods. This is nicely transformed in C# to properties. Usually our objects are immutable by
26// intention to have no problem in multithreaded applications.
27// NOLINTBEGIN(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes,cppcoreguidelines-avoid-const-or-ref-data-members)
28namespace inno
29{
30 class Logger;
31 class FaceCapture;
32 class Face;
33
34 // Internal interface to overcome cyclic includes between this header and FaceDetector.
35 // It is introduced to be possible to add convenient function FaceCapture::DetectWith(().
36 class FaceCaptureSegmentation
37 {
38 public:
44 virtual std::vector<std::shared_ptr<Face>> Detect(std::shared_ptr<FaceCapture> capture) = 0;
45
46 FaceCaptureSegmentation() = default;
47 virtual ~FaceCaptureSegmentation() = default;
48 FaceCaptureSegmentation(const FaceCaptureSegmentation&) = delete;
49 FaceCaptureSegmentation(FaceCaptureSegmentation&&) = delete;
50 FaceCaptureSegmentation& operator=(const FaceCaptureSegmentation&) = delete;
51 FaceCaptureSegmentation& operator=(FaceCaptureSegmentation&&) = delete;
52 };
53
57 */
58 class FaceCapture
59 : public Serializable
60 , public std::enable_shared_from_this<FaceCapture>
61 {
62 public:
64 const std::shared_ptr<Image> image;
67
74 */
75 [[nodiscard]] static std::shared_ptr<FaceCapture> Create(std::shared_ptr<Image> img,
76 const FaceAttributes& fa = FaceAttributes())
77 {
78 if (img == nullptr)
79 {
80 throw NullArgumentException("Could not create FaceCapture due to image can not be null");
81 }
82 return std::shared_ptr<FaceCapture>(new FaceCapture(std::move(img), fa));
83 }
84
88 */
89 void WriteTo(Writer& writer) const final
90 {
91 writer.Write("i", image);
92 writer.Write("a", faceAttributes);
93 }
94
102 */
103 [[nodiscard]] static std::shared_ptr<FaceCapture> FromIsoImage(const std::vector<uint8_t>& isoImage)
104 {
105 static constexpr size_t SizeOfIdentifier = 4UL;
106 static constexpr size_t SizeOfVersion = 4UL;
107 if (isoImage.size() < SizeOfIdentifier + SizeOfVersion)
108 {
109 throw EnrollmentInvalidArgumentException("Fail to decode face ISO image (fail to read header)");
110 }
111 if (const std::vector<uint8_t> id = { 'F', 'A', 'C', '\0' };
112 std::search(isoImage.begin(), isoImage.end(), id.begin(), id.end()) == isoImage.end())
113 {
114 throw EnrollmentInvalidArgumentException("Fail to decode face ISO image (invalid id)");
115 }
116 static constexpr size_t VersionIndex = SizeOfIdentifier;
117 if (const std::vector<uint8_t> ver = { '0', '3', '0', '\0' };
118 std::search(isoImage.begin() + VersionIndex, isoImage.end(), ver.begin(), ver.end()) == isoImage.end())
119 {
120 throw EnrollmentInvalidArgumentException("Fail to decode face ISO image (invalid version)");
121 }
122 static constexpr size_t QualityBlocksCountIndex = 35UL;
123 static constexpr size_t SizeOfQualityBlocksCount = 1UL;
124 if (isoImage.size() < (QualityBlocksCountIndex + SizeOfQualityBlocksCount))
125 {
127 "Fail to decode face ISO image (fail to read quality blocks count)");
128 }
129 static constexpr size_t QualityBlockSize = 5UL;
130 const auto qualityBlocksCount = isoImage[QualityBlocksCountIndex];
131 const auto qualityBlocksSize = qualityBlocksCount * QualityBlockSize;
132 const auto landmarkPointsCountIndex =
133 QualityBlocksCountIndex + qualityBlocksSize + SizeOfQualityBlocksCount;
134 static constexpr size_t SizeOfLandmarkPointsBlocksCount = 2UL;
135 if (isoImage.size() < (landmarkPointsCountIndex + SizeOfLandmarkPointsBlocksCount))
136 {
138 "Fail to decode face ISO image (fail to read landmark points blocks count)");
139 }
140 const auto landmarkPointsCount =
141 (isoImage[landmarkPointsCountIndex] << 8UL) + isoImage[landmarkPointsCountIndex + 1];
142 static constexpr size_t LandmarkPointBlockSize = 8UL;
143 const auto landmarkPointsSize = landmarkPointsCount * LandmarkPointBlockSize;
144 static constexpr size_t ImageInformationSize = 11UL;
145 static constexpr size_t FacialInformationSize = 17UL;
146 const auto imageLengthIndex = QualityBlocksCountIndex + SizeOfQualityBlocksCount + qualityBlocksSize +
147 FacialInformationSize + landmarkPointsSize + ImageInformationSize;
148 static constexpr size_t SizeOfImageLength = 4UL;
149 if (isoImage.size() < (imageLengthIndex + SizeOfImageLength))
150 {
151 throw EnrollmentInvalidArgumentException("Fail to decode face ISO image (fail to read image length)");
152 }
153 const size_t imageLength = (isoImage[imageLengthIndex] << 24U) + (isoImage[imageLengthIndex + 1] << 16U) +
154 (isoImage[imageLengthIndex + 2] << 8U) + isoImage[imageLengthIndex + 3];
155 const auto imageDataIndex = imageLengthIndex + SizeOfImageLength;
156 if (isoImage.size() < (imageDataIndex + imageLength))
157 {
158 throw EnrollmentInvalidArgumentException("Fail to decode face ISO image (fail to read image data)");
159 }
160 const std::vector<uint8_t> encodedImageData =
161 std::vector<uint8_t>(std::next(isoImage.begin(), static_cast<ptrdiff_t>(imageDataIndex)),
162 std::next(isoImage.begin(), static_cast<ptrdiff_t>(imageDataIndex + imageLength)));
163
164 static constexpr size_t EquipmentIDIndex = 31UL;
165 const unsigned int captureEquipmentID = (isoImage[EquipmentIDIndex] << 8U) + isoImage[EquipmentIDIndex + 1];
166 static constexpr size_t CaptureDeviceTypeIDIndex = 33UL;
167 const unsigned int captureDeviceTypeID =
168 (isoImage[CaptureDeviceTypeIDIndex] << 8U) + isoImage[CaptureDeviceTypeIDIndex + 1];
169
171 static constexpr size_t CaptureDeviceTechnologyIndex = 30UL;
172 fa.SetCaptureDeviceTechnology(IsoToFaceCaptureDeviceTechnology(isoImage[CaptureDeviceTechnologyIndex]));
174 fa.SetCaptureDeviceTypeID(FaceCaptureDeviceTypeID(captureDeviceTypeID));
175
176 return Create(Image::Decode(encodedImageData), fa);
177 }
178
189 */
190 [[nodiscard]] std::vector<std::shared_ptr<Face>> DetectWith(FaceCaptureSegmentation& detector)
191 {
192 auto capture = shared_from_this();
193 return detector.Detect(capture);
194 }
195
202 */
203 [[nodiscard]] std::shared_ptr<Image> CropFace(const Rectangle& rectangle, const RGBA& backgroundColor) const
204 {
205 auto croppedImage = image->CropRectangle(rectangle, backgroundColor);
206 return croppedImage;
207 }
208
215 */
216 [[nodiscard]] bool IsWholeCroppedRectangleInside(const Rectangle& rectangle) const
217 {
218 auto intersectionType = image->RectangleIntersection(rectangle);
219 return intersectionType == Image::Intersection::INSIDE || intersectionType == Image::Intersection::SAME;
220 }
221
227 */
228 [[nodiscard]] std::shared_ptr<Image> Draw(const std::vector<std::shared_ptr<Face>>& faces,
229 const ImageShapeAttributes& attr) const
230 {
232 log.LogInfo("Draw faces %v with attributes %v", faces, attr);
233 const BoundingBoxesShape rbs(faces, attr);
234 return image->DrawShape(rbs);
235 }
236
244 */
245 [[nodiscard]] std::shared_ptr<FaceCapture> ResizeToMaxDimension(ImageDimension maxDimension)
246 {
247 if (std::max(image->Width(), image->Height()) <= maxDimension)
248 {
249 return shared_from_this();
250 }
251
252 auto resizedImage = image->ResizeToMaxDimension(maxDimension);
253 return Create(std::move(resizedImage));
254 }
255
259 */
260 [[nodiscard]] ImageDimension MaxImageDimension() const
261 {
262 return std::max(image->Width(), image->Height());
263 }
269 */
270 [[nodiscard]] std::shared_ptr<Image> Draw(const Rectangle& boundingBox, const ImageShapeAttributes& attr) const
271 {
273 log.LogInfo("Draw rectangle %v with attributes %v", boundingBox, attr);
274 const RectangleShape rb(boundingBox, attr);
275 return image->DrawShape(rb);
276 }
277
278 FaceCapture(const FaceCapture&) = delete;
279 FaceCapture(FaceCapture&& c) = delete;
280 FaceCapture& operator=(const FaceCapture&) = delete;
281 FaceCapture& operator=(FaceCapture&& c) = delete;
282 virtual ~FaceCapture() = default;
283 FaceCapture() = delete;
284
285 private:
291 FaceCapture(std::shared_ptr<Image> i, FaceAttributes fa)
292 : image(std::move(i))
293 , faceAttributes(std::move(fa))
294 {
295 }
296
297 class BoundingBoxesShape final : public ImageShape
298 {
299 public:
300 void DrawIn(ImageShapeDrawer& drawer) const final
301 {
302 for (const auto& f : faces)
303 {
304 auto rs = RectangleShape(GetFaceDetectionBox(f), attr);
305 rs.DrawIn(drawer);
306 }
307 }
308
309 BoundingBoxesShape(const std::vector<std::shared_ptr<Face>>& fs, ImageShapeAttributes a)
310 : faces(fs)
311 , attr(std::move(a))
312 {
313 }
314 BoundingBoxesShape() = delete;
315 virtual ~BoundingBoxesShape() = default;
316 BoundingBoxesShape(const BoundingBoxesShape&) = delete;
317 BoundingBoxesShape(BoundingBoxesShape&&) = delete;
318 BoundingBoxesShape& operator=(const BoundingBoxesShape&) = delete;
319 BoundingBoxesShape& operator=(BoundingBoxesShape&&) = delete;
320
321 private:
322 const std::vector<std::shared_ptr<Face>>& faces;
323 ImageShapeAttributes attr;
324 static Rectangle GetFaceDetectionBox(const std::shared_ptr<Face>& face);
325 };
326 };
327} // namespace inno
328// NOLINTEND(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes,cppcoreguidelines-avoid-const-or-ref-data-members)
Base exception for all enrollment-sdk invalid argument exceptions.
Definition EnrollmentException.h:96
Face attributes Holds the face attributes.
Definition FaceAttributes.h:33
void SetCaptureDeviceTypeID(FaceCaptureDeviceTypeID type)
Sets capture device type ID.
Definition FaceAttributes.h:174
void SetCaptureDeviceVendorID(FaceCaptureDeviceVendorID vendor)
Sets capture device vendor ID.
Definition FaceAttributes.h:154
void SetCaptureDeviceTechnology(FaceCaptureDeviceTechnology technology)
Sets capture device technology.
Definition FaceAttributes.h:134
Capture device type identifier The capture device type identifier shall identify the biometric organi...
Definition FaceCaptureDeviceTypeID.h:24
Capture device vendor identifier The capture device vendor identifier shall identify the biometric or...
Definition FaceCaptureDeviceVendorID.h:24
Face capture can contains one or group of people, faces or full body.
Definition FaceCapture.h:60
std::shared_ptr< Image > Draw(const std::vector< std::shared_ptr< Face > > &faces, const ImageShapeAttributes &attr) const
It draws rounding boxes into FaceCapture.
Definition FaceCapture.h:227
void WriteTo(Writer &writer) const final
Write itself into writer.
Definition FaceCapture.h:88
std::shared_ptr< Image > Draw(const Rectangle &boundingBox, const ImageShapeAttributes &attr) const
It draws bounding box into FaceCapture.
Definition FaceCapture.h:269
std::shared_ptr< FaceCapture > ResizeToMaxDimension(ImageDimension maxDimension)
Returns new FaceCapture with resized image to given max dimension.
Definition FaceCapture.h:244
std::vector< std::shared_ptr< Face > > DetectWith(FaceCaptureSegmentation &detector)
Detects faces in the current face capture.
Definition FaceCapture.h:189
std::shared_ptr< Image > CropFace(const Rectangle &rectangle, const RGBA &backgroundColor) const
It crops image with given rectangle and background color.
Definition FaceCapture.h:202
ImageDimension MaxImageDimension() const
Returns max dimension of image in FaceCapture.
Definition FaceCapture.h:259
static std::shared_ptr< FaceCapture > Create(std::shared_ptr< Image > img, const FaceAttributes &fa=FaceAttributes())
Constructor of FaceCapture.
Definition FaceCapture.h:74
const std::shared_ptr< Image > image
Provides FaceCapture Image.
Definition FaceCapture.h:63
const FaceAttributes faceAttributes
Provides FaceAttributes.
Definition FaceCapture.h:65
static std::shared_ptr< FaceCapture > FromIsoImage(const std::vector< uint8_t > &isoImage)
Function creates Face object from ISO image based on ISO/IEC 19794-5 (Face image data).
Definition FaceCapture.h:102
bool IsWholeCroppedRectangleInside(const Rectangle &rectangle) const
Calculates intersection of image and cropping rectangle.
Definition FaceCapture.h:215
It holds all functions and data related to Face manipulation.
Definition Face.h:594
It provides functions with format specifier to compose and log message via provided Logger.
Definition FormattingLogger.h:601
void LogInfo(const char *format, Args &&... args) const
Formats and logs message as info message.
Definition FormattingLogger.h:611
static std::shared_ptr< Logger > Get()
Provides current logger.
Definition Logger.h:281
It holds shape attributes such as color and line width.
Definition ImageShape.h:22
static std::shared_ptr< Image > Decode(const std::vector< uint8_t > &imageData)
Creates Image from image data with 500 DPI.
Definition Image.h:48
@ INSIDE
Object is fully in Image.
Definition Image.h:129
@ SAME
Image has same dimensions and vertices coordinates as Object.
Definition Image.h:135
Interface for library logging.
Definition Logger.h:45
Null argument is not allowed.
Definition EnrollmentException.h:156
It holds RGB color with transparency.
Definition ImageAttribute.h:908
It holds rectangle and draws it.
Definition ImageShape.h:163
It holds rectangle vertexes, width, height.
Definition ImageAttribute.h:357
Provides interface for serialization of all classes.
Definition Writer.h:164
static constexpr FaceCaptureDeviceTechnology IsoToFaceCaptureDeviceTechnology(int isoCaptureDeviceTechnology)
Function converts ISO capture technology to FaceCaptureDeviceTechnology.
Definition FaceCaptureDeviceTechnology.h:80
unsigned int ImageDimension
Image dimension.
Definition ImageAttribute.h:31