Concepts
Ported from the IDKit SDK v9.2.3 documentation (chapter "Notes"). Topics are ordered as in the original manual. For exact function signatures, see the API Reference.
Buffers (C++)
C++ API functions in IDKit SDK use a two-phase buffer retrieval algorithm. Some functions return their result in two phases — the application calls them twice: the first call retrieves only the required buffer length, the second retrieves the data. This gives the application a chance to allocate a buffer of sufficient size.
The SDK differentiates between the two calls by the value of the length parameter: if length is zero
or too small, or the data buffer is NULL, only the length is returned; if the buffer is not NULL
and the length is sufficient, data is written into the buffer.
int length = 0;
int err = IEngine_GetFingerprintImage(user, 0, IENGINE_FORMAT_BMP, NULL, &length);
if (err) return -1;
unsigned char *data = new unsigned char[length];
err = IEngine_GetFingerprintImage(user, 0, IENGINE_FORMAT_BMP, data, &length);
if (err) return -1;
Applies to: IEngine_GetFingerprintImage, IEngine_GetCustomData, IEngine_GetMinutiaePoints,
IEngine_GetMinutiaeImage, IEngine_SerializeUser, IEngine_ExportUserTemplate,
IEngine_GetStringTag, IEngine_GetTagName, IEngine_GetCollectionIDs,
IEngine_ConvertRawToImage, IEngine_ConvertImageToRaw.
Connections
IDKit SDK supports concurrent database connections and several sets of global parameters.
There is always one default connection, used by applications that don't need multiple connections. The SDK also supports constructing several connections (execution contexts or sessions), useful for:
- multi-threaded applications that need thread-local parameters (like DPI or maximum rotation),
- multi-threaded application servers that need one connection per client session, non-blocking concurrency between connections, and thread-local parameters,
- applications using multiple databases that need to access them all without repeatedly reconnecting.
API: IEngine_InitConnection, IEngine_SelectConnection, IEngine_CloseConnection (C++);
IDKit.Connection class (.NET); IDKit constructor, IDKit.selectConnection, IDKit.close (Java).
Connections exist independently from threads — every thread can access every connection. Operations on the same connection are safely serialized by internal locks. There can be only one direct connection per database (SQLite). The licensed user limit applies to the sum of sizes of all directly connected databases.
Connection string
Specifies the location of the biometric database. Connection types:
- SQLite — flat-file database on the local computer.
- Memory — virtual database that exists only in memory.
Since IDKit SDK version 8, ODBC and JDBC databases and the ExpressID AFIS service connection are not available and unsupported.
The connection string consists of parameter–value pairs followed by a semicolon: [<param>=<value>;]*.
Values may be enclosed in quotation marks to prevent parsing errors when they contain ; or =.
SQLite — if the specified database file does not exist, it is created automatically:
| Parameter | Value |
|---|---|
type | sqlite |
file | File name of the database file, optionally with a directory path (which must exist). May contain Unicode characters (UTF-8 in C++). |
type=sqlite; file=idkit.db;
Simplified form (assumes SQLite): idkit.db
Memory — one memory database per connection. All data is lost when IEngine_TerminateModule or
IEngine_CloseConnection is called. If many user records are to be stored, turn off image storage
(parameter CFG_STORE_IMAGES):
type=memory
Corresponding fingerprints
Two fingerprints are considered to correspond to each other if they have the same finger position, or
if at least one of them has an unknown finger position. Only corresponding fingerprints are compared
during identification and verification.
Change finger position with IEngine_SetFingerPosition / IEngine_GetFingerPosition.
Custom data string
An arbitrary piece of data that the application can attach to every user record — a simple byte array with no size restriction. The SDK doesn't process it in any way; it is stored as a BLOB in the database together with the user record. Unlike tags, it can store binary data (photos, documents) and has unlimited size. It is not cached in memory — it is always loaded on demand from the database.
Common scenarios:
- interlink the application database and the IDKit database by a table key stored in the custom data string,
- store user identity (name, ID, …) serialized into an XML (or any other) document,
- store a list of this user's successful identifications, including time and other data.
API: IEngine_SetCustomData / IEngine_GetCustomData (C++); IDKit.SetCustomData /
IDKit.GetCustomData (.NET); User.setCustomData / User.getCustomData (Java).
External database
A biometric database that is not controlled by IDKit SDK. The integrated database support is optional — it is possible to identify and verify user templates coming from an external database: the application loads all relevant templates into memory and calls an identification or verification function that works with the external database.
Functions that can work with external-database templates: IEngine_FindUserInMemory,
IEngine_FindFingerprintInMemory, IEngine_MatchUsers, IEngine_MatchFingerprints (C++), and their
.NET / Java counterparts.
To create or update the external database, the application extracts templates for all added users,
exports the template data with IEngine_ExportUserTemplate, and saves it in the external database.
Licensing works differently with an external database: the user limit is checked before every identification, and applies to the whole database — not just the part submitted to the identification function.
FAR and Threshold
False Acceptance Rate (FAR) describes the probability at which the matching algorithm makes false acceptance errors — identifying a matching fingerprint in the database even though the two fingerprints do not belong to the same person.
Similarity scores returned by the library are normalized; the approximate relationship between similarity score and FAR (also called False Match Rate) is:
similarity score = -10 * log10(FAR)
The normalization formula is only an approximation — score distribution varies with scanner surface area, finger placement, finger quality, and finger positions (index fingers tend to give higher scores compared to little fingers).
FAR depends predominantly on the selected threshold. Increasing the threshold reduces FAR but can also increase FRR. FAR is influenced by the quality of the database being searched and the quality of the probe fingerprint.
Verification threshold
For verification with a single finger, the threshold corresponds to −10·log₁₀(FAR). Corresponding threshold values per FAR, depending on the number of fingerprints per probe and enrolled user:
| Probe fingers | Enrolled fingers | FAR = 1% | FAR = 0.1% | FAR = 0.01% | FAR = 0.001% | FAR = 0.0001% |
|---|---|---|---|---|---|---|
| 1 | 1 | 20 | 30 | 40 | 50 | 60 |
| 1 | 10 | 30 | 40 | 50 | 60 | 70 |
| 2 | 2 | 1 | 5 | 18 | 31 | 43 |
| 4 | 4 | 1 | 1 | 16 | 31 | 48 |
| 10 | 10 | 1 | 1 | 27 | 66 | 76 |
These values are for verification only and can vary for data sets of different quality or captured with a different sensor. The default threshold is 40, corresponding to FAR of 0.01% (1:10 000).
Evaluation parameters: rotation 60; scanner Futronic FS88; 1-print = right index; 2-prints = right + left index; 4-prints = both thumbs + both indexes; 10-prints = all 10 fingers.
Identification threshold
In identification, the threshold varies with FAR, database size, and the number of fingerprints per probe and gallery user. Recommended identification thresholds:
| Probe fingers | DB size | Enrolled fingers | FAR = 1% | FAR = 0.1% | FAR = 0.01% | FAR = 0.001% | FAR = 0.0001% |
|---|---|---|---|---|---|---|---|
| 1 | 100 | 1 | 35 | 47 | 59 | 72 | 87 |
| 1 | 1000 | 1 | 44 | 57 | 70 | 85 | 94 |
| 1 | 10000 | 1 | 52 | 66 | 80 | 93 | 128 |
| 1 | 100 | 10 | 42 | 54 | 67 | 80 | 88 |
| 1 | 1000 | 10 | 50 | 63 | 76 | 87 | 96 |
| 1 | 10000 | 10 | 59 | 73 | 86 | 99 | 128 |
| 2 | 100 | 2 | 1 | 12 | 24 | 39 | 46 |
| 2 | 1000 | 2 | 6 | 21 | 35 | 49 | 56 |
| 2 | 10000 | 2 | 14 | 29 | 44 | 61 | 102 |
| 4 | 100 | 4 | 1 | 10 | 28 | 43 | 60 |
| 4 | 1000 | 4 | 1 | 19 | 38 | 53 | 71 |
| 4 | 10000 | 4 | 9 | 28 | 47 | 67 | 82 |
| 10 | 100 | 10 | 1 | 21 | 56 | 87 | 114 |
| 10 | 1000 | 10 | 1 | 37 | 78 | 113 | 139 |
| 10 | 10000 | 10 | 9 | 54 | 94 | 127 | 142 |
Evaluation parameters: speed 4; candidates count 2; rotation 60; scanner Futronic FS88; finger sets as in the verification table above.
Biometric template
A biometric template (or user template) is a data structure containing biometric information about one or more fingerprints. Templates are extracted from fingerprint images. Templates do not contain the original biometric images.
Compatibility: Innovatrics proprietary templates were backward compatible up to IDKit SDK version 7.1
(templates extracted with an older version could be imported or loaded from the database with a newer
version). This functionality was removed in IDKit SDK version 7.2.0 — since version 7.2.0 only
ICRS23 templates are supported. The same applies to the previously available ICRS21 downgrade export
(CFG_ICS_TEMPLATE_VERSION), removed in 7.2.0.
Fingerprint template
A data structure containing biometric information about one fingerprint. Depending on the template format, fingerprint templates can contain a combination of minutiae and pattern data. The template does not contain the original fingerprint image. The same ICRS23-only compatibility rules apply as above.
FRR
False Rejection Rate (FRR) describes the probability at which the matching algorithm makes false rejection errors — failing to identify a probe user in the database even though the database contains biometric data of the same person.
FRR primarily depends on the quality of the database being searched and the quality of the probe biometric data. FRR is somewhat influenced by the threshold: decreasing the threshold reduces FRR but can significantly increase FAR.
Identification (one-to-many)
One-to-many (1:N) identification compares a single probe user to a number of users in the database. It can be thought of as a sequence of 1:1 verifications executed against every user in the database — but it is several orders of magnitude faster than a loop of verifications. The identification algorithm sorts database users by similarity score and returns one or more users with the highest score.
Influencing parameters:
- Similarity threshold —
CFG_SIMILARITY_THRESHOLD - Maximum permitted rotation —
CFG_MAX_ROTATION - Identification speed —
CFG_IDENTIFICATION_SPEED
In-memory license
A buffer in memory that contains license data, in the same format as a file license.
Provide it with IEngine_InitWithLicense (instead of IEngine_InitModule), IDKit.InitWithLicense
(.NET), or IDKit.initWithLicense (Java).
An in-memory license allows more flexible deployment — the license can live in application-specific folders, the system registry, or together with the application license. If the provided in-memory license is not valid for any reason, the SDK continues searching for a valid license in the other locations.
License
IDKit SDK checks a digital license for the purchased user limit. The license may be stored in memory,
in a license file, or on a USB dongle. The license contains the purchased user limit for the local
database — query it with IEngine_GetUserLimit.
For an external database and a memory database, the user limit applies to the size of the whole database, not just the part visible to the SDK at any given moment. With multiple connections, the limit applies to the sum of sizes of all databases. When the user limit is reached, no further user registrations are allowed.
License search order on Windows (7 and higher):
- In-memory license
- USB dongle
- User's private application data folder — usually
C:\Users\<user>\AppData\Local\Innovatrics\iengine.lic - System-wide application data folder — usually
C:\ProgramData\Innovatrics\iengine.lic - Current directory
License search order on Linux:
- In-memory license
- USB dongle
$HOME/.innovatrics/iengine.lic/etc/innovatrics/iengine.lic$HOME/.idkit/iengine.lic/etc/idkit/iengine.lic- Current directory
On Android and embedded systems, initializing with an in-memory license is recommended.
Fingerprint quality and presence
Quality — a value between 0 (lowest) and 100 (highest), calculated during template extraction and
recorded in the fingerprint template; linked to the total number of distinctive features found in the
fingerprint image. Higher-quality fingerprints are more likely to result in a higher recognition rate.
Generally, quality above 40 is good enough for matching — the application should reject scanned
fingerprints with quality below 40 during registration. A low-quality probe can still be submitted to
identification, but it increases FAR and FRR; quality above 30 should be sufficient for reliable
identification. Query with IEngine_GetFingerprintQuality.
Presence — an additional quality indicator between 0 and 100, calculated directly from the
fingerprint image as the area where presence of a fingerprint is detected (it does not measure quality
of the fingerprint pattern itself). It is very fast and is intended for fingerprint presence detection
and as an auto-capture trigger in a real-time capture process. Presence above 15 should be sufficient
for reliable placement detection; above 40 is sufficient for enrollment and identification. Query with
IEngine_GetFingerprintPresence.
Score consolidation
The process of combining similarity scores of several corresponding fingerprint pairs into one common similarity score for the whole user pair. It is capped at the maximum similarity score value (1000).
The consolidation function cannot be expressed by a simple formula — it is optimized for the best possible accuracy for a given number of consolidated individual scores. If a user record contains multiple instances of the same fingerprint position (e.g. three right-index templates for better accuracy), all scores of corresponding pairs are grouped by fingerprint position, the maximum is taken per position set, and the consolidated score is calculated as a function of those maximums.
Selection
Selections specify database subsets where identification will be performed. If an application manages several logical databases, it doesn't need several AFIS systems — IDKit SDK can identify over application-specified subsets of one shared database. Subsets are simply arrays of user IDs. They are similar in purpose to tag queries but more flexible — e.g. an SQL query to an application database can generate the list of IDs.
API: IEngine_FindUserInSelection, IEngine_FindFingerprintInSelection (C++), and the .NET / Java
counterparts.
Similarity score
Quantifies the level of biometric similarity between two fingerprints. Returned by identification and verification functions as a number in the range 0 (lowest) to 1000 (highest). A score above the similarity threshold indicates a matching pair.
When a user pair has more than one corresponding fingerprint pair, the individual scores are automatically consolidated into one common score for the whole user pair.
Tag query
A tag query filters users by tag values. It is a subset of SQL defining queries over tag values and user IDs, evaluated with wire-level performance (contrary to standard database queries). Tag queries narrow the set of users included in identification, or can be used alone to retrieve user IDs by tag values. They are similar to selections but save network bandwidth when selecting large subsets.
Use cases: binning (narrowing identification requests); marking some user records as special; merging several partial AFIS systems into one global AFIS; retrieving user IDs with matching tag values or IDs in a certain range.
Supported SQL subset:
- All queries have the form
SELECT USERID FROM TAG_CACHE WHERE condition. - Table
TAG_CACHEcontains one row per user record; columns includeUSERIDand one column per tag name. - Operators:
AND,OR,NOT,=,<>,<,>,<=,>=,IS [NOT] NULL,[NOT] IN (constant list),( sub-condition ). - Operands: string constant, integer constant, column name (including
USERID). - Conversions between strings and 32-bit integers are automatic.
- A column has value
NULLif the corresponding tag was not set on the user record. - Unicode is not supported directly; applications can encode Unicode tag values in UTF-7.
Performance: the tag cache exists as a table in memory, sized proportionally to columns × rows. Query
implementation is a brute-force filter evaluating the WHERE clause for every row. Used together with
identification, a tag query typically consumes less than 10 % of total identification time, filtering
typically over 50 million rows per second per core.
Examples:
-- Users with IDs in a range
SELECT USERID FROM TAG_CACHE WHERE USERID >= 3000001 AND USERID <= 4000000
-- All users except one (useful when the identified user is already registered)
SELECT USERID FROM TAG_CACHE WHERE USERID <> 1234567
-- Filter by tag values
SELECT USERID FROM TAG_CACHE WHERE GENDER = 'male'
SELECT USERID FROM TAG_CACHE WHERE AGE <= 30
SELECT USERID FROM TAG_CACHE WHERE DATE_OF_BIRTH < 19800101
SELECT USERID FROM TAG_CACHE WHERE SCORE >= 13000
SELECT USERID FROM TAG_CACHE WHERE TOWN IN ('CityA', 'CityB', 'CityC')
SELECT USERID FROM TAG_CACHE WHERE TOWN IS NULL
SELECT USERID FROM TAG_CACHE WHERE QUALITY < 40
API: IEngine_FindUserByQuery, IEngine_FindFingerprintByQuery, IEngine_GetUserIDsByQuery (C++),
and the .NET / Java counterparts.
Tags
User records can have persistent tags containing strings or numbers — application-defined information attached to user records. Compared to the custom data string, tags are more structured, cached in memory, stored in an application-readable format, and usable in a tag query.
Restrictions:
- A tag name is any combination of letters, numbers, and underscores starting with a letter; names are case-insensitive (returned in uppercase).
- A tag value is an arbitrary non-empty ASCII string. Unicode values can be encoded in UTF-7 by the application.
- Integers are stored as strings, but tag queries can compare them like integers.
- Dates are best stored as numbers in
YYYYMMDDformat, which allows date comparison with integer operators.
Use cases: tag-query filters; recording information about the user (ID card number, application-specific IDs, personal details); recording results of previous identifications (e.g. a de-duplication application storing best-match ID and score with every user record).
Database structure: tags are stored in table IENGINE_TAGS, one name–value pair plus user ID per row.
Changes made directly to the table are not visible through the SDK until the database is reopened and
reloaded. Tags should be modified only through Innovatrics APIs — manual modification can harm the
database.
Template cache
An area of memory containing biometric modality templates. The SDK pre-loads all templates from the database into memory to improve identification speed. Images and custom data strings are not pre-loaded. Connections to a memory database need no pre-loading, because all templates are already in memory.
Template extraction
The process of converting a fingerprint image into a template. Extraction is a lengthy procedure (about 300 ms for a fingerprint), but it saves time during subsequent identification and verification — and memory and disk space, because templates are much smaller than images.
Extraction is performed by IEngine_AddFingerprint (C++) and its .NET / Java counterparts. Raw
template data can be obtained with IEngine_ExportUserTemplate.
Threads
IDKit SDK is thread-safe. API calls generally run in parallel when executed from multiple threads; internal locks serialize calls that require write access to the same resource (notably the same connection). Identification is automatically parallelized on multi-core processors. Template extraction — the second most expensive operation — is not parallelized automatically, but the application may execute several extractions in parallel.
In C++, one type of operation is not thread-safe: deallocation of objects (IEngine_FreeUser,
IEngine_FreeCollection). The application is responsible for ensuring the object is no longer used by
any thread when its deallocation function executes. In .NET and Java this is handled automatically.
Set the environment variable OMP_NUM_THREADS to limit the number of threads of the IEngine core used
during identification, matching, or extraction.
Verification (one-to-one)
One-to-one (1:1) verification compares two users or two fingerprints and calculates the similarity score between the two.
Fingerprint verification tries to find the overlapping area between two fingerprints and compares their features (minutiae and patterns) in this area. Verification of two users compares each fingerprint of one user with each corresponding fingerprint of the other, and consolidates the resulting set of partial scores into a global user score.
Influencing parameters:
- Similarity threshold —
CFG_SIMILARITY_THRESHOLD - Maximum permitted rotation —
CFG_MAX_ROTATION
Similarity threshold
Defines the minimum similarity score considered a match. While the similarity score provides degree-of-certainty information, most applications eventually have to decide whether a particular score means a match or not — the threshold divides the similarity spectrum into matching and non-matching ranges.
Configure with CFG_SIMILARITY_THRESHOLD. Identification and verification functions only return
matches above the current threshold. The default setting is suitable for most applications; adjust it
to control FAR and FRR using the approximate FAR-to-threshold mapping in
FAR and Threshold.