1 to N Identification¶
Overview¶
The 1 to N functions allow you to enroll face recognition templates (Faceprints) into a database of face templates called a collection, then allow you to efficiently search through these collections for an identity. Since the 1 to N functions are quite involved, it is highly recommended you read through all the information below, as well as reading through the FAQs.
Using Multiple SDK Instances in a Single Process¶
In order to avoid loading the same collection into memory multiple times (which becomes an issue when the collection sizes become very large),
instances of the SDK created within the same process will share the same collection in memory (RAM). This means when you enroll a Faceprint into the collection
using one instance of the SDK, it will be available in all other instances of the SDK in the same process.
For this same reason, applications which have multiple instances of the SDK in a single process only need to call createDatabaseConnection
and createLoadCollection
on a single instance of the SDK and all other instances will automatically be connected to the same database and collection.
For more information on createDatabaseConnection
and createLoadCollection
, refer to “How do createDatabaseConnection and createLoadCollection work?” on the FAQ page.
Database Management Systems and Collection Synchronization¶
The PostgreSQL backend option also has built in synchronization across multiple processes. Let’s take an example where you have two processes on different machines, A and B, connected to the same PostgreSQL backend. Each of these processes will initially connect to the same database and collection and therefore load all the Faceprints from the database into memory (RAM). If process A then enrolls a Faceprint into the collection, this will both add the Faceprint to the in-memory (RAM) collection of process A and will update the PostgreSQL database. In doing so, it will also automatically push out a notification to all the subscribed processes which are connected to the same database and collection. Any process connected to the same database and collection is automatically subscribed to updates, no additional action is required from the developer. Process B will therefore receive a notification that an update was made and will therefore automatically enroll the same Faceprint into its in-memory (RAM) collection. Process A and B therefore have synchronized collections in memory. Note, it can take up to 30 seconds for subscribed processes to receive the notification.
This sort of multi-process synchronization is not supported by the sqlite backend. With the sqlite backend, if process A makes a change to the database,
process B will not know of the changes. Process B must re-call createLoadCollection
in order to register the changes that were made to the database from process A.
Note doing so will not perform an incremental update, but will instead discard then re-load all the data into memory, which can be slow if the collection size is large.
This is why it is advised to use the sqlite backend option only for use cases which involve only a single process connecting to the database.
If multiple processes need to connect to a database (and require synchronization), it is advised to use the PostgreSQL backend.
Memory Requirements and Workarounds¶
With the frVectorCompression
flag enabled, at a conservative average, each FULL model Faceprint and corresponding metadata is roughly 750 bytes in size,
though this ultimately depends on the length of the identity
string you choose. You can therefore calculate approximately how much RAM is required for various collection sizes.
For example, a collection of size 1 million Faceprints will require 750 bytes * 1,000,000 Faceprints = 750Mb of RAM, a collection of size 10 million Faceprints will require 7.5Gb of RAM, and so on.
For most use cases, even embedded devices have enough RAM to search through collections of medium to even large sizes (ex. An RPI 4 can handle a few million Faceprints).
However, when running 1 to N identification on massive collections (10s or 100s of millions of Faceprints) on a lightweight embedded device, you may find the device does
not have sufficient RAM to store the entire collection in memory. In these situations, you will want to run the actual 1 to N search on a beefy server which has sufficient RAM.
Process the video streams on the embedded devices at the edge to generate feature vectors for the detected faces, then send these feature vectors to the server (or cluster of servers)
to run the actual 1 to N identification functions (ex. identifyTopCandidate
). The server should also handle enrolling and deleting Faceprints from the collection as required
(these functions can also be exposed to the edge devices as REST API endpoints). Hence, the edge devices only generate feature vectors, while only the beefy servers are connected to the database and perform the searches.
To simplify things (and avoid having to write your own REST API server), you can have your edge devices send the feature vectors to an instance of the Trueface Visionbox running on your server
to perform the matching.
Selecting the Best Enrollment Image¶
It is imperative that enrollment images are of high quality. Enrolling low quality images into a collection can result in false positives (incorrect identifications). For best performance, ensure the image meets the following criteria:
Face height - the face is at least 100 pixels in height - use the bounding box height from
FaceBoxAndLandmarks
Head orientation - the head yaw and pitch are close to neutral - use the
estimateHeadOrientation
functionImage blur - the face image has minimal blur - use the
estimateFaceImageQuality
functionObstructions to face - the subject is not wearing a mask, etc. - use the
detectMask
function
If the criteria above are not met, it is advised you reject the image and that you do not enroll it into a collection.
For more information on how to use these functions to filter images, refer to the identification.cpp
sample app which comes shipped in the download bundle.
We also advise you to save your enrollment images in a database of your own choosing (and map them to the UUID return by enrollFaceprint
).
That way if in the future we release a new improved face recognition model, you will be able to regenerate a face recognition Faceprint for all your enrollment images using the new model.
The Trueface SDK does not store your images, it was deliberately designed to remain lean.
-
ErrorCode
Trueface::SDK
::
createDatabaseConnection
(const std::string &databaseConnectionString)¶ Create a connection to a new or existing database. If the database does not exist, a new one will be created with the provided name. If the NONE DatabaseManagementSystem (memory only) configuration option is selected, this function does not need to be called (and is a harmless no-op).
- Return
error code, see ErrorCode.
- Parameters
databaseConnectionString
: If SQLITE DatabaseManagementSystem is selected, this should be the filepath to the database. ex. “/myPath/myDatabase.db” If POSTGRESQL DatabaseManagementSystem is selected, this should be a database connection string. For a list of PostgreSQL connection parameters, visit: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS ex. “hostaddr=192.168.1.0 port=5432 dbname=face_recognition user=postgres password=my_password” ex. “host=localhost port=5432 dbname=face_recognition user=postgres password=m_password”
-
ErrorCode
Trueface::SDK
::
createLoadCollection
(const std::string &collectionName)¶ Create a new collection, or load data from an existing collection into memory (RAM) if one with the provided name already exists in the database. Equivalent to calling createCollection then loadCollection.
- Return
error code, see ErrorCode.
- Parameters
[in] collectionName
: the name of the collection.
-
ErrorCode
Trueface::SDK
::
createCollection
(const std::string &collectionName)¶ Create a new collection in the database. Before enrolling Faceprints into newly created collection, must call loadCollection. If the collection with the provided name already exists, this is a harmless no-op.
- Return
error code, see ErrorCode.
- Parameters
[in] collectionName
: the name of the collection.
-
ErrorCode
Trueface::SDK
::
loadCollection
(const std::string &collectionName)¶ Loads the collection into memory. Must be called before enrolling Faceprints or calling identification functions.
- Return
error code, see ErrorCode. Will return an error if the collection does not exist.
- Parameters
[in] collectionName
: the name of the collection to load into memory.
-
ErrorCode
Trueface::SDK
::
deleteCollection
(const std::string &collectionName)¶ Deletes a collection from the current database.
- Return
error code, see ErrorCode. Will return an error if the collection does not exist.
- Parameters
[in] collectionName
: the name of the collection to delete.
-
ErrorCode
Trueface::SDK
::
getCollectionNames
(std::vector<std::string> &collectionNames)¶ Get a list of the names of all the collections in the database. Collection names can then be passed to getCollectionMetadata and getCollectionIdentities.
- Return
error code, see ErrorCode.
- Parameters
[out] collectionNames
: list of collection names in the database.
-
ErrorCode
Trueface::SDK
::
getCollectionMetadata
(const std::string &collectionName, CollectionMetadata &metadata)¶ Get the metadata for the specified collection in the database, loaded or unloaded.
- Return
error code, see ErrorCode.
- Parameters
[in] collectionName
: the name of the collection for which to retrieve the metadata.[out] metadata
: the metadata for the specified collection.
-
ErrorCode
Trueface::SDK
::
getCollectionIdentities
(const std::string &collectionName, std::unordered_multimap<std::string, std::string> &identities)¶ Get a map of identities and UUIDs for the specified collection in the database, loaded or unloaded. This can be a slow operation (especially for unloaded collections), call sparingly.
- Return
error code, see ErrorCode.
- Parameters
[in] collectionName
: the name of the collection for which to retrieve the identities.[out] identities
: a map of identities and corresponding UUIDs. There can be multiple UUIDs mapped to a single identity if multiple Faceprints were enrolled for that identity.
-
ErrorCode
Trueface::SDK
::
enrollFaceprint
(const Faceprint &faceprint, const std::string &identity, std::string &UUID)¶ Enroll a Faceprint for a new or existing identity in the collection.
-
ErrorCode
Trueface::SDK
::
removeByUUID
(const std::string &UUID)¶ Remove a Faceprint from the collection using the UUID.
- Return
error code, see ErrorCode.
- Parameters
[in] UUID
: the universally unique identifier corresponding to the Daceprint to be removed from the collection.
-
ErrorCode
Trueface::SDK
::
removeByIdentity
(const std::string &identity, unsigned int &numFaceprintsRemoved)¶ Remove all Faceprints in the collection corresponding to the identity.
- Return
error code, see ErrorCode.
- Parameters
[in] identity
: the identity to remove from the collection.[out] numFaceprintsRemoved
: the the number of Faceprints which were removed for that identity.
-
ErrorCode
Trueface::SDK
::
identifyTopCandidate
(const Faceprint &faceprint, Candidate &candidate, bool &found, float threshold = 0.3f)¶ Get the top candidate identity in the collection and the corresponding similarity score and match probability.
- Return
error code, see ErrorCode.
- Parameters
[in] faceprint
: the Faceprint to be identified.[out] candidate
: the top candidate identity.[out] found
: set to true if a match is found.[in] threshold
: the similarity score threshold above which it is considered a match. Higher thresholds may result in faster queries. Refer to https://performance.trueface.ai/ when selecting a threshold.
-
ErrorCode
Trueface::SDK
::
batchIdentifyTopCandidate
(const std::vector<Faceprint> &faceprints, std::vector<Candidate> &candidates, std::vector<bool> &found, float threshold = 0.3f)¶ Get the top candidate identity in the collection and the corresponding similarity score and match probability for each probe faceprint. Like identifyTopCandidate, but runs search queries in parallel and improves throughput.
- Return
error code, see ErrorCode.
- Parameters
[in] faceprints
: a vector of Faceprints to be identified.[out] candidates
: the top candidate identity for each probe faceprint.[out] found
: set to true if a match is found for the probe faceprint.[in] threshold
: the similarity score threshold above which it is considered a match. Higher thresholds may result in faster queries. Refer to https://performance.trueface.ai/ when selecting a threshold.
-
ErrorCode
Trueface::SDK
::
identifyTopCandidates
(const Faceprint &faceprint, std::vector<Candidate> &candidates, bool &found, unsigned int numCandidates, float threshold = 3.f)¶ Get a list of the top n candidate identities in the collection and their corresponding similarity scores and match probabilities. Ideal for investigation mode.
- Return
error code, see ErrorCode.
- Parameters
[in] faceprint
: the Faceprint to be identified.[out] candidates
: a list of the top n matches (or fewer), ordered by descending similarity score.[out] found
: set to true if at leaset one match is found.[in] numCandidates
: max number of candidate identities to return.[in] threshold
: the similarity score threshold above which it is considered a match. Higher thresholds may result in faster queries. Refer to https://performance.trueface.ai/ when selecting a threshold.
-
struct
Trueface
::
Candidate
¶