Auto-enrollment add-on
The auto-enrollment add-on turns Face Matcher into a system that builds its own watchlist: every face that is seen but does not match anyone is evaluated against quality rules and, if it passes, registered as a new watchlist member automatically. It is an optional container that runs next to Face Matcher and uses only the public APIs, so it is a good example of how a stack built on top works. Typical uses are visitor counting where each person should be recognised on their next visit, and building a gallery of frequent visitors for later review.
How it works
- The add-on connects to the GraphQL API and subscribes to no-match notifications.
- For each unmatched face it checks the face against the configured conditions: face quality, size and area in the frame, pose angles, brightness and sharpness, how many faces the frame contains and whether the face is the largest one.
- It waits for the tracklet to end (or the configured timeout) so it can pick the best frame of the person rather than the first.
- It searches the target watchlists for a duplicate above
Config__DuplicateSearchThresholdto avoid enrolling the same person twice. - If everything passes, it registers the member through the REST API with the frame crop as the enrollment image, into the watchlists listed in
Config__WatchlistIds__*.
The add-on is available as a ready-to-run container image, integrations-auto-enroll, from the same registry as the platform images. Its source code is published by Innovatrics so you can fork it and adapt the rules when the configuration below is not enough.
Deployment
Add the service to a Compose file of your own and join face-matcher-network. Inside the network the GraphQL API is graphql-api:8080 and the REST API is api:8080. Start Face Matcher first.
services:
auto-enrollment:
image: ${REGISTRY}integrations-auto-enroll
container_name: auto-enrollment
restart: unless-stopped
environment:
- Source__GraphQL__Host=graphql-api
- Source__GraphQL__Port=8080
- Target__Host=api
- Target__Port=8080
- Config__WatchlistIds__0=00000000-0000-0000-0000-000000000000
networks:
default:
name: face-matcher-network
external: true
Replace the watchlist identifier with the id of a watchlist you created for automatic enrollment (see Enroll and identify via REST); add Config__WatchlistIds__1 and so on for more. Keep auto-enrolled members in their own watchlist, separate from curated lists, so that operators can review and clean it up and so that its threshold can be tuned independently.
Configuration
Connection
| Variable | Meaning |
|---|---|
Source__GraphQL__Host, Source__GraphQL__Port | GraphQL API the add-on subscribes to (graphql-api, 8080) |
Source__OAuth__Url, Source__OAuth__ClientId, Source__OAuth__ClientSecret, Source__OAuth__Audience | Token endpoint and client credentials when authentication is enabled on the APIs; leave unset otherwise |
Target__Host, Target__Port | REST API used for registration (api, 8080) |
Behaviour
| Variable | Meaning |
|---|---|
Config__WatchlistIds__N | Watchlists new members are enrolled into (N = 0, 1, 2, ...) |
Config__EnrollStrategy | How a candidate is chosen, for example FirstPassingCriteria |
Config__DuplicateSearchThreshold | Score (0-100) above which an existing member counts as the same person and no new member is created |
Config__TrackletTimeoutMs | How long to wait for more frames of the same tracklet before deciding |
Config__HardAbsoluteExpirationMs | Upper bound on how long a tracklet is kept in memory |
Config__MaxParallelActionBlocks | Number of tracklets processed in parallel |
Enrollment conditions
All conditions are prefixed Config__Conditions__. A face must satisfy every one of them to be enrolled.
| Condition | Default | Meaning |
|---|---|---|
FaceQuality__Min | 4500 | Minimum face quality score (0-10000) |
FaceSize__Min / FaceSize__Max | 70 / 450 | Face size in pixels |
FaceArea__Min / FaceArea__Max | 0.01 / 1.50 | Face area as a ratio of the frame |
FaceOrder__Max | 1 | Only the largest face (order 1) qualifies |
FacesOnFrameCount__Max | 2 | Skip frames with more faces than this |
TemplateQuality__Min | 80 | Minimum template quality (0-100) |
Brightness__Min / Brightness__Max | 0.001 / 1000 | Brightness range |
Sharpness__Min / Sharpness__Max | 0.001 / 1000 | Sharpness range |
YawAngle__Min / YawAngle__Max | -7 / 7 | Head turned left or right, degrees |
PitchAngle__Min / PitchAngle__Max | -25 / 25 | Head tilted up or down, degrees |
RollAngle__Min / RollAngle__Max | -15 / 15 | Head tilted sideways, degrees |
FramePaddingAbsolute | 50 | Pixels added around the face when cropping the enrollment image |
FramePaddingRelative | 0.15 | Padding as a ratio of the face size |
The defaults are stricter than the platform's own enrollment validation on purpose: an automatically enrolled image is never reviewed by a person, so it must be a frontal, sharp, well-lit face. See Enrollment image quality for why these limits matter.
Per-stream overrides
Any condition, and the target watchlists, can be overridden for a particular camera or edge stream with an indexed StreamConfigurations__N__ block, for example to accept smaller faces from a wide-angle overview camera:
environment:
- StreamConfigurations__0__StreamId=00000000-0000-0000-0000-000000000001
- StreamConfigurations__0__FaceSize__Min=40
- StreamConfigurations__1__StreamId=00000000-0000-0000-0000-000000000002
- StreamConfigurations__1__FaceSize__Min=50
- StreamConfigurations__1__WatchlistIds__0=11111111-1111-1111-1111-111111111111
StreamId is the camera or edge stream identifier from the REST API; every other key in the block uses the same names as the global conditions without the Config__Conditions__ prefix.