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(s) 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 Trueface::SDK::createDatabaseConnection() and Trueface::SDK::loadCollection() 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 Trueface::SDK::createDatabaseConnection() and Trueface::SDK::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. By default, each node will check for notifications every 30 seconds, though this period can be modified by the DB_NOTIFICATION_CHECK_FREQUENCY environment variable.

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 Trueface::SDK::loadCollection() or Trueface::SDK::loadCollections() 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.

Collection Memory Requirements

Using the following table, you can compute roughly how much RAM is required for storage of Faceprint templates (this does not include memory required for extracting Faceprints). Although the following estimates are very conservative, realize that the exact size ultimately depends on the length of the identity string you choose.

Faceprint Storage RAM Requirements

Num Faceprint

TFV5_2/TFV6/TFV7

TFV5_2*/TFV6*/TFV7*

LITE

LITE*

1

2250 Bytes

1250 Bytes

762 Bytes

506 Bytes

1,000

2.15 Mb

1.19 Mb

0.73 Mb

0.48 Mb

1,000,000

2.10 Gb

1.16 Gb

0.71 Gb

0.47 Gb

10,000,000

20.96 Gb

11.64 Gb

7.07 Gb

4.71 Gb

100,000,000

209.55 Gb

116.42 Gb

70.97 Gb

47.12 Gb

*Trueface::ConfigurationOptions.frVectorCompression flag enabled

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. Trueface::SDK::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 PTOP 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 guidance on how to select the best image for enrollment, please visit our FAQ Page.

We also advise you to save your enrollment images in a database of your own choosing (and map them to the UUID returned by Trueface::SDK::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 Trueface::DatabaseManagementSystem::NONE (memory only) configuration option is selected, this function does not need to be called (and is a harmless no-op).

If connecting to a hosted PostgreSQL database (AWS, Digital Ocean, etc), see the HOSTED_DATABASE environment variable on the environment variable page.

If connecting to a PostgreSQL database, use the “host” parameter to specify the host name url (ex. mydatabase.us-east-1.rds.amazonaws.com, localhost, etc).

If connecting to a PostgreSQL database and you only have the numeric IP address of the server, then you must use the “hostaddr” parameter. Using the “hostaddr” parameter instead of “host” will avoid a host name look-up.

Note, the database name cannot contain uppercase characters.

Parameters:

databaseConnectionString[in] If Trueface::DatabaseManagementSystem::SQLITE is selected, this should be the filepath to the database. ex. “/myPath/myDatabase.db”. If Trueface::DatabaseManagementSystem::POSTGRESQL is selected, this should be a database connection string. Here

is a list of all supported PostgreSQL connection parameters. ex. “hostaddr=192.168.1.0 port=5432 dbname=face_recognition user=postgres

password=my_password”. ex. “host=mydatabase.us-east-1.rds.amazonaws.com port=5432

dbname=face_recognition user=postgres password=m_password”. To enable ssl, add “sslmode=require” to the connection string.

Returns:

Error code, see ErrorCode.

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. Will unload any collections previously loaded into memory. Equivalent to calling createCollection() then loadCollection(). Collection name cannot be a reserved key word.

Parameters:

collectionName[in] The name of the collection.

Returns:

Error code, see ErrorCode.

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() or loadCollections(). If a collection with the provided name already exists, this is a harmless no-op. Collection name cannot be a reserved key word.

Parameters:

collectionName[in] The name of the collection.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::loadCollection(const std::string &collectionName)

Loads the specified collection into memory, while unloading any collections previously loaded into memory. Must be called before enrolling Faceprints or calling identification functions. Refer to our FAQ page for more information on this method.

Parameters:

collectionName[in] The name of the collection to load into memory.

Returns:

Error code, see ErrorCode. Will return an error if the collection does not exist.

ErrorCode Trueface::SDK::loadCollectionPersist(const std::string &collectionName)

Loads the specified collection into memory. Does not unload any collections previously loaded into memory. Must be called before enrolling Faceprints or calling identification functions. Refer to our FAQ page for more information on this method.

Parameters:

collectionName[in] The name of the collection to load into memory.

Returns:

Error code, see ErrorCode. Will return an error if the collection does not exist.

ErrorCode Trueface::SDK::loadCollections(const std::vector<std::string> &collectionNames)

Load the specified collections into memory, while unloading any collections previously loaded into memory. Must be called before enrolling Faceprints or calling identification functions.

Parameters:

collectionNames[in] The name of the collections to load into memory.

Returns:

Error code, see ErrorCode. Will return an error if one or more of the specified collections does not exist.

ErrorCode Trueface::SDK::deleteCollection(const std::string &collectionName)

Deletes a collection from the current database.

Parameters:

collectionName[in] The name of the collection to delete.

Returns:

Error code, see ErrorCode. Will return an error if the collection does not exist.

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().

Parameters:

collectionNames[out] List of collection names in the database.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::getLoadedCollectionNames(std::vector<std::string> &collectionNames)

Returns a list of collections which are currently loaded in memory.

Parameters:

collectionNames[out] List of collections in memory.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::getCollectionMetadata(const std::string &collectionName, CollectionMetadata &metadata)

Get the metadata for the specified collection in the database, loaded or unloaded.

Parameters:
  • collectionName[in] The name of the collection for which to retrieve the metadata.

  • metadata[out] The metadata for the specified collection.

Returns:

Error code, see ErrorCode.

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.

Parameters:
  • collectionName[in] The name of the collection for which to retrieve the identities.

  • identities[out] 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.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::enrollFaceprint(const Faceprint &faceprint, const std::string &identity, std::string &UUID, const std::string &collectionName = "")

Enroll a Faceprint for a new or existing identity in the collection.

Parameters:
  • faceprint[in] The Faceprint to enroll in the collection.

  • identity[in] The identity corresponding to the Faceprint.

  • UUID[out] Universally unique identifier corresponding to the Faceprint.

  • collectionName[in] The name of the collection in which to enroll the Faceprint. If only a single collection has been loaded into memory, this can remain an empty string (in order to maintain backwards compatibility). If multiple collections are loaded in memory, then the collection name parameter must be specified.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::removeByUUID(const std::string &UUID, const std::string &collectionName = "")

Remove a Faceprint from the collection using the UUID.

Parameters:
  • UUID[in] The universally unique identifier returned by enrollFaceprint().

  • collectionName[in] The name of the collection from which to remove the Faceprint. If only a single collection has been loaded into memory, this can remain an empty string (in order to maintain backwards compatibility). If multiple collections are loaded in memory, then the collection name parameter must be specified.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::removeByIdentity(const std::string &identity, unsigned int &numFaceprintsRemoved, const std::string &collectionName = "")

Remove all Faceprints in the collection corresponding to the identity.

Parameters:
  • identity[in] The identity to remove from the collection.

  • numFaceprintsRemoved[out] The the number of Faceprint which were removed for that identity.

  • collectionName[in] The name of the collection from which to remove the Faceprint. If only a single collection has been loaded into memory, this can remain an empty string (in order to maintain backwards compatibility). If multiple collections are loaded in memory, * then the collection name parameter must be specified.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::identifyTopCandidate(const Faceprint &faceprint, Candidate &candidate, bool &found, float threshold = 0.4f, const std::string &collectionName = "")

Get the top match Candidate in the collection and the corresponding similarity score and match probability.

Parameters:
  • faceprint[in] The Faceprint to be identified.

  • candidate[out] The top match Candidate.

  • found[out] Set to true if a match is found.

  • threshold[in] The similarity score threshold above which it is considered a match. Higher thresholds may result in faster queries. Refer to our ROC curves when selecting a threshold.

  • collectionName[in] The name of the collection which should be searched. If only a single collection has been loaded into memory, this can remain an empty string (in order to maintain backwards compatibility). If multiple collections are loaded in memory, then the collection name parameter must be specified.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::batchIdentifyTopCandidate(const std::vector<Faceprint> &faceprints, std::vector<Candidate> &candidates, std::vector<bool> &found, float threshold = 0.4f, const std::string &collectionName = "")

Get the top match Candidate 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.

Parameters:
  • faceprints[in] A vector of Faceprint to be identified.

  • candidates[out] The top match Candidate for each probe Faceprint.

  • found[out] Set to true if a match is found for the probe Faceprint.

  • threshold[in] The similarity score threshold above which it is considered a match. Higher thresholds may result in faster queries. Refer to out ROC curves when selecting a threshold.

  • collectionName[in] The name of the collection which should be searched. If only a single collection has been loaded into memory, this can remain an empty string (in order to maintain backwards compatibility). If multiple collections are loaded in memory, then the collection name parameter must be specified.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::identifyTopCandidates(const Faceprint &faceprint, std::vector<Candidate> &candidates, bool &found, unsigned int numCandidates, float threshold = 0.4f, const std::string &collectionName = "")

Get a list of the top n match Candidate in the collection and their corresponding similarity scores and match probabilities. Ideal for investigation mode.

Parameters:
  • faceprint[in] The Faceprint to be identified.

  • candidates[out] A list of the top n matches (or fewer) Candidate, ordered by descending similarity score.

  • found[out] Set to true if at leaset one match is found.

  • numCandidates[in] Max number of Candidate identities to return.

  • threshold[in] The similarity score threshold above which it is considered a match. Higher thresholds may result in faster queries. Refer to out ROC curves when selecting a threshold.

  • collectionName[in] The name of the collection which should be searched. If only a single collection has been loaded into memory, this can remain an empty string (in order to maintain backwards compatibility). If multiple collections are loaded in memory, then the collection name parameter must be specified.

Returns:

Error code, see ErrorCode.

ErrorCode Trueface::SDK::registerDatabaseDisconnectionCallback(std::function<void()> callback)

The PostgreSQL DatabaseManagementSystem has synchronization built-in, in which the database will propagate any notifications to to any of the connected clients.

Even if the network connection is interrupted, any notifications which were sent out during this period will be received when the network connection is reestablished, ensuring the client collection remains synchronized.

Under rare circumstances, the connection to the database may be broken entirely. If any notifications are sent out during this period, the client will not know about them, and will still not know about them when database connection is reestablished.

In this rare occurrence, it is possible for a client collection to go out of sync with the database (only if another client made any collection modifications during the time when the connection was broken).

Therefore, you can choose to register a callback method which is called any time the connection to the database is broken. We advise capturing a flag or conditional variable by reference and setting it within the method you define, and then check for the flag in your application and respond appropriately.

You could for example then choose to reload the collection into memory, ensuring that it is fully up to date with the database in-case a database notification was missed. If you do choose to register a callback method, then when a disconnect is detected, the callback method will be called, and the SDK will not try to reconnect to the database.

Parameters:

callback[in] The callback method which is called anytime the database is disconnected.

Returns:

Error code, see ErrorCode.

struct Candidate

Public Members

float similarityMeasure

The computed similarity measure.

float matchProbability

The probability the two face feature vectors are a match.

std::string identity

The identity of the match.

std::string UUID

The UUID of the matching Faceprint.

struct CollectionMetadata

Collection metadata.

Public Members

std::string collectionName = ""

The name of the collection.

uint64_t numIdentities = 0

The number of unique identities in the collection.

uint64_t numFaceprints = 0

The total number of Faceprint enrolled in the collection.

std::string modelName = ""

The name of the face recognition model used to generate the Faceprint enrolled in the collection.

uint16_t featureVectorSizeBytes = 0

The size of the Faceprint feature vector in bytes.

ModelOptions modelOptions = {}

Additional options which were used to generate Faceprint enrolled in the collection.

bool encrypted = false

Indicates if the collection is encrypted.