Welcome to FindFace Enterprise Server SDK’s documentation!¶
FindFace Enterprise Server SDK provides professional face recognition services based on neural networks. Implement these services to your ecosystem to take full advantage of them.
Features:
- Fast and robust face detection and database enrollment. Possibility of enrolling faces in bulk.
- Intelligent video face detection and analytics.
- Fast and accurate face identification and verification based on neural networks.
- Gender, age and emotions recognition.
- Dynamic person creation and ‘friend or foe’ identification.
- Almost infinite scalability due to integration with Tarantool.
- Truly RESTful API available in an embedded user friendly framework.
- Possibility of formatting API-responses.
- Highly intuitive web user interface.
- Network or on-premise licensing.
Tip
To read a release changelog, execute:
$ dpkg-parsechangelog -l /usr/share/doc/findface-repo/changelog.Debian.gz --all
FindFace Enterprise Server SDK will be of interest to independent software vendors (ISVs), system integrators, enterprise IT customers, and original equipment manufacturers (OEMs). It can be harnessed in numerous areas, such as retail, banking, social networking, entertainment, sports, event management, dating services, video surveillance, public safety, homeland security, etc.
Being integrated into specific solutions or Android applications, FindFace Enterprise Server SDK empowers businesses to accomplish such goals as biometric identification and access control, customer analytics, customer offer tailoring, offline retargeting, managing white and black lists, sorting and optimizing media libraries, borrower scoring, fraud prevention, employee productivity control, and many more.
This guide is intended for developers and system integration engineers who are going to integrate face recognition services into their systems. Prior to deploying a development environment, explore the 9 steps to face recognition. This will give you a general idea of the deployment process.
Let’s get started!
Get Started¶
Here you can see a typical biometric system based on FindFace Enterprise Server SDK:
FindFace Enterprise Server SDK consists of the Biometric Data Analysis and Recognition Server (FindFace Server or Server hereinafter) and, optionally, the video face detector and other additional components.
The FindFace Server functioning is provided by interaction of the following components:
Component | Description |
---|---|
findface-facenapi |
Python daemon which runs HTTP API. This daemon executes face detection functions, interfaces with MongoDB and findface-nnapi and tarantool@FindFace daemons. |
tntapi (tarantool@FindFace as a shard) |
Daemon which enables interaction with the face descriptors index. |
findface-nnapi |
Daemon extracts a feature vector (based on neural network). Requires the packages with models <findface-data>.deb. |
MongoDB | Database which stores faces metadata, galleries details, settings, etc. |
findface-upload |
Nginx web server used to receive images using WebDAV. |
NTLS |
Local license server which interfaces with NtechLab Global License Server (for network licensing) or a USB dongle (for on-premise licensing) and passes a license to licensable components. |
Follow the 9 steps below to start delivering face recognition services to your customers:
System Requirements¶
In this chapter:
General Requirements¶
Hosts¶
Prior to installing FindFace Enterprise Server SDK, ensure that the host(s) meet the following minimum requirements:
Note
Standalone installation of FindFace Enterprise Server SDK is recommended when the number of faces in the database does not exceed some 1,000,000
. Otherwise you should install Findface Enterprise Server SDK in a cluster environment and configure fast index search.
Requirement | Description |
---|---|
CPU | x86-64 CPU (Intel), >2.0 Ghz, >2 cores. The CPU AVX support is required for operation of all the components, except findface-upload. |
RAM | RAM consumption depends on the number of faces in your dataset.
Use the benchmark results below to calculate
the memory size you need.
Note that if there are 2 or more galleries with facens, you have to
multiply the given MongoDB and Tarantool RAM consumption by the relevant
number of galleries.
As a rule, 10,000,000 faces require 20Gb RAM for Tarantool. MongoDB
does not need much RAM as it uses HDD as RAM when needed. |
HDD | 10,000,000 faces require ~20x[number of snapshots for each shard] GB
for Tarantool (by default 20x3=60 GB) and 24 GB for MongoDB.
To store all uploaded images via findface-upload:
size of all uploaded images + 10% |
Operating system | Ubuntu 16.04 LTS. The 32-bit version is not supported. |
Virtual machine support | VMware: vSphere 5.0 or later. |
Here you can see the FindFace Enterprise Server SDK memory usage benchmark results. Use these data to calculate the RAM size you need.
Note
Memory usage may slightly vary from test to test.
Note
Depending on your needs, adjust the Tarantool maximum memory usage at /etc/tarantool/instances.enabled/FindFace.lua
.
The testing setup is the following:
- Facen model:
apricot_320
- Models for gender, age and emotions recognition (GAE in the table):
fr_1_gender0
,fr_1_age0
,emotion_1
- Models used in extraction-api:
apricot_320
,fr_1_gender0
,fr_1_age0
,emotion_1
MongoDB
,Tarantool
: facens are stored in one gallery. If there are 2 or more galleries with facens, multiply the given RAM amount by the relevant number of galleries.
Number of faces | RAM consumption by components, MB | ||||
---|---|---|---|---|---|
MongoDB | Tarantool | nnapi | nnapi + GAE | extraction-api | |
0 (own needs) | ~70 | ~77 | ~265 | ~1000 | ~1GB (1 Core)/~7GB (8 Cores) (up to 10,5 under load) |
50,000 | ~181 | ~189 | ~400 | ~1400 | |
100,000 | ~294 | ~263 | ~400 | ~1400 | |
500,000 | ~1190 | ~1013 | ~400 | ~1400 | |
1,000,000 | ~2310 | ~1943 | ~400 | ~1400 |
Supported Images¶
FindFace Enterprise Server SDK supports the following image formats:
- JPEG,
- PNG,
- WebP.
The maximum image size is 10 MB. The minimum distance between pupils is 40 px.
Video Face Detection¶
Video Face Detector Host¶
A host for the video face detection component must meet the following requirements (given that a video stream is 1 x 720p (1280×720) at 25FPS playback speed):
Note
Requirements depend on motion activity and the number of faces in video, the video face detector settings and FindFace Enterprise Server SDK overall load. To select an optimal configuration, contact our experts by info@ntechlab.com.
Requirement | Description |
---|---|
CPU | ≥ INTEL Core i5 6400 (2 physical core CPU). AVX support required. |
RAM | 4 GB in the real-time mode. |
Operating system | Ubuntu 16.04 LTS (only x64). |
Supported Video File Formats and Codecs¶
The fkvideo_detector component supports all video file formats and codecs that can be decoded by FFmpeg.
FindFace Web User Interface¶
To process video in the FindFace Enterprise Server SDK web user interface, its host should meet the same requirements as for the video face detector.
Choose Deployment Architecture¶
FindFace Enterprise Server SDK is delivered in the following distributable packages:
- A package with components <findface-repo>.deb.
- Several packages with neural network models <findface-data>.deb. Each model is delivered in a separate package.
Depending on your system characteristics and performance requirements, there are 2 FindFace Enterprise Server SDK deployments:
Deployment | Recommendation |
---|---|
Standalone | You can deploy FindFace Enterprise Server SDK on a single host (standalone) if the number of faces in the database does not exceed some 1,000,000. |
Cluster | If the number of faces in the database does exceed 1 million, deploy FindFace Enterprise Server SDK in a cluster environment and configure fast index search. This is a medium and large deployment which can be scaled almost infinitely. It will also suit professional high load projects with severe requirements to performance. |
Standalone Architecture¶
FindFace Enterprise Server SDK components and neural network models can be deployed on a single host (standalone) making it easier to start deployment and cater to basic requirements of your applications. A typical standalone installation of FindFace Server is shown on the diagram below.
Tip
In addition to FindFace Server, you can also harness the advanced features.
Note
Standalone installation can be done step-by-step or from a developer-friendly installer.

Service | Description |
---|---|
findface-facenapi |
Python daemon which runs HTTP API. This daemon executes face detection functions, interfaces with MongoDB and findface-nnapi and tarantool@FindFace daemons. |
tntapi (tarantool@FindFace as a shard) |
Daemon which enables interaction with the face descriptors index. |
findface-nnapi |
Daemon extracts a feature vector (based on neural network). Requires the packages with models <findface-data>.deb. |
MongoDB | Database which stores faces metadata, galleries details, settings, etc. |
findface-upload |
Nginx web server used to receive images using WebDAV. |
NTLS |
Local license server which interfaces with NtechLab Global License Server (for network licensing) or a USB dongle (for on-premise licensing) and passes a license to licensable components. |
Cluster Architecture¶
To meet high load requirements of your application, FindFace Enterprise Server SDK enables distributed installation of components in a cluster environment enhanced with Tarantool. The following diagram shows the typical network topology of FindFace Server:
Tip
In addition to FindFace Server, you can also harness the advanced features.

Service | Description |
---|---|
findface-facenapi |
Python daemon which runs HTTP API. This daemon executes face detection functions, interfaces with MongoDB and findface-nnapi and tarantool@FindFace daemons. |
tntapi (tarantool@FindFace as a shard) |
Daemon which enables interaction with the face descriptors index. |
findface-nnapi |
Daemon extracts a feature vector (based on neural network). Requires the packages with models <findface-data>.deb. |
MongoDB | Database which stores faces metadata, galleries details, settings, etc. |
findface-upload |
Nginx web server used to receive images using WebDAV. |
NTLS |
Local license server which interfaces with NtechLab Global License Server (for network licensing) or a USB dongle (for on-premise licensing) and passes a license to licensable components. |
Extra Functionality¶
In addition to FindFace Server (installed on a single or several hosts), you can also harness advanced features provided by the following components from the <findface-repo>.deb package:
Component | Description |
---|---|
fkvideo_detector | The video face detection component fkvideo_detector extracts faces from a RTSP camera stream or a video file on-the-fly and sends them via REST API to findface-facenapi for further processing. Licensable. |
findface-extraction-api | With the findface-extraction-api component, you can flexibly configure the format of API responses to extract various face data, including the bounding box coordinates, normalized face, gender, age, and emotions, as well as the face feature vector (facen). Implementing this feature to your system can remarkably broaden the scope of analytic tasks it is capable of fulfilling. You can also use the component as an extractor of the face feature vector, i. e. as a findface-nnapi alternative. Licensable. |
findface-mass-enroll | The findface-mass-enroll component allows for enrolling faces to findface-facenapi from images in bulk. |
findface-ui | A web user interface which generally duplicates the functionality available via REST API. To be installed on the findface-facenapi host. |
findface-tarantool-build-index | The findface-tarantool-build-index component creates a fast index for galleries with the number of faces over 1,000,000. |
Deploy FindFace Server¶
Prerequisite Software¶
In order to run successfully, FindFace Server needs the following software:
Prerequisite software | Usage | Installation |
---|---|---|
MongoDB | Internal database that provides proper functioning of FindFace Server. Stores faces metadata, galleries details, settings and other internal data. | Manually, before installing the FindFace Server components |
Tarantool | Stores faces vector data. | Automatically along with the tntapi component. |
In this section:
MongoDB¶
Prior to installing FindFace Server, set up a database for it. You may install MongoDB either on the application host where the findface-facenapi component resides, or on a dedicated host. For the standalone architecture, we recommend you the first option. FindFace Enterprise Server SDK is compatible with MongoDB 3.2 or later.
Install MongoDB on Application Host¶
To install the latest stable version of MongoDB (3.4 at the moment) on the application host, do the following:
Note
To install a different version of MongoDB, please refer to that version’s documentation. For example, see version 3.2.
Import the public key used by the package management system:
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
Create a list file (/etc/apt/sources.list.d/mongodb-org-3.4.list ) for MongoDB:
echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
Reload the local package database:
sudo apt-get update
Install the latest stable version of MongoDB:
sudo apt-get install -y mongodb-org
Start the
mongod
service:sudo service mongod start
Install MongoDB on Dedicated Host¶
To install MongoDB on a dedicated host, do the following:
On the dedicated host, install MongoDB in the same manner as on the application host.
Open the MongoDB configuration file:
sudo vi /etc/mongod.conf
To allow for incoming connections, comment out the line bind_ip = 127.0.0.1. This will allow MongoDB to accept connections from any IP address. Ensure that the only access to the host is from the LAN:
#bind_ip = 127.0.0.1
Restart the
mongod
service:sudo service mongod restart
Connect to Existing MongoDB¶
If you wish to establish connection to an existing MongoDB instance, specify its IP address in the network settings.
Install FindFace Server¶
This section will guide you through the FindFace Server step-by-step installation process. Follow the instructions below minding the sequence.
Tip
Standalone installation can also be done from a developer-friendly installer.
In this section:
Prepare Packages for Installation¶
FindFace Enterprise Server SDK can be installed from a local repository. You can receive the FindFace Enterprise Server SDK distributable packages from your NTechLab manager. To prepare the packages for installation, do the following:
Warning
The ntech
user will be automatically created at this stage. To avoid a conflict, make sure that such a user does not already exist in the system.
Unpack the package with components on each designated host.
sudo dpkg -i <findface-repo>.deb
Unpack the packages with models (face, gender, age, and emotions). In the cluster environment, models are installed only on the
findface-nnapi
hosts.sudo dpkg -i findface-data*
Add a signature key on each designated host.
sudo apt-key add /var/findface-repo/public.key
Licensing¶
You receive a license file from your NTechLab manager along with the FindFace Enterprise Server SDK distributable packages. If you opt for on-premise licensing, we will also send you a Guardant USB dongle. The licensing scheme for FindFace Enterprise Server SDK is shown on the diagram below.

To provide the FindFace Enterprise Server SDK licensing, follow the steps below:
- Install and configure the local license server NTLS.
- If the licensable components (
findface-nnapi
,tntapi
,fkvideo_detector
,extraction-api
) are installed on remote hosts, specify the NTLS host IP address in their configuration files.
To install and configure NTLS, do the following:
Install the NTLS component:
sudo apt-get update sudo apt-get install ntls
Tip
In the NTLS configuration file, you can change the license folder and specify your proxy server IP address if necessary. You can also change the NTLS web interface remote access settings. To open the NTLS configuration file, execute:
sudo vi /etc/ntls.cfg
If necessary, change the license folder in the
license-dir
parameter. By default, license files are stored at/ntech/license
:license-dir = /ntech/license
If necessary, uncomment the
proxy
line and specify your proxy server IP address:proxy = http://192.168.1.1:12345
By default, you can access the NTLS web interface from any remote host (
ui = 0.0.0.0:3185
). To indicate that accessing the NTLS web interface must originate from a specific IP address, edit theui
parameter:ui = 127.0.0.1:3185
Enable the NTLS service autostart and launch the service:
sudo systemctl enable ntls && sudo systemctl start ntls
Upload the license file via the NTLS web interface
http://<NTLS_IP_address>:3185/#/
. You can also use the NTLS web interface to consult your license information, and upgrade or extend the license.For on-premise licensing, insert the Guardant dongle into a USB port.
Important
If the licensable components (findface-nnapi
, tntapi
, fkvideo_detector
, extraction-api
) are to be installed on remote hosts, keep in mind that you have to specify the IP address of the NTLS host in their configuration files after installation.
Install Components¶
Now that you have prepared the FindFace Enterprise Server SDK packages and provided the licensing, install the Server components on designated host(s) according to your architecture outline.
Install facenapi¶
Install and configure the findface-facenapi
component as follows:
Install the component.
sudo apt-get update sudo apt-get install python3-facenapi
If MongoDB is installed on a remote host, specify its IP address in the
findface-facenapi
configuration file.sudo vi /etc/findface-facenapi.ini mongo_host = '192.168.113.1'
Check if the component is runnable. To do so, invoke the
findface-facenapi
application by executing the command below. As the application is invoked, hold 1 minute, and if no errors display, hitCtrl+C
.If MongoDB is installed on the same host, execute:
findface-facenapi
If MongoDB is installed on a remote host, execute:
sudo findface-facenapi --config=/etc/findface-facenapi.ini
Check if the
findface-facenapi
service autostart at system startup is disabled.systemctl list-unit-files | grep findface-facenapi
Enable the service autostart and launch the service.
sudo systemctl enable findface-facenapi.service && sudo service findface-facenapi start
Make sure that the service is up and running. The command will return a service description, a status (should be Active), path and running time.
sudo service findface-facenapi status
Tip
You can view the findface-facenapi
logs by executing:
sudo tail -f /var/log/syslog | grep facenapi
Install nnapi¶
Install and configure the findface-nnapi
component as follows:
Tip
You may also want to learn about gender, age and emotions recognition.
Install the component.
sudo apt-get update sudo apt-get install findface-nnapi
If NTLS is installed on a remote host, specify its IP address in the
findface-nnapi
configuration file.sudo vi /etc/findface-nnapi.ini license_ntls_server = 192.168.113.2:3133
Check if the component is runnable. To do so, invoke the
findface-nnapi
application by executing the command below. As the application is invoked, hold 1 minute, and if no errors display, hitCtrl+C
.findface-nnapi
Check if the
findface-nnapi
service autostart at system startup is disabled.systemctl list-unit-files | grep findface-nnapi
Enable the service autostart and launch the service.
sudo systemctl enable findface-nnapi.service && sudo service findface-nnapi start
Make sure that the service is up and running. The command will return a service description, a status (should be Active), path and running time.
sudo service findface-nnapi status
Install findface-upload¶
To store all original images which have been processed by Server, as well as such Server artifacts as face thumbnails and normalized images, install and configure the findface-upload
component.
Tip
Skip this procedure if you do not want to store these data on the FindFace Enterprise Server SDK host. In this case, only face features vectors (facens) will be stored (in MongoDB and Tarantool databases).
Do the following:
Install the component:
sudo apt-get update sudo apt-get install findface-upload
By default the original images, thumbnails and normalized images are stored at
/var/lib/ffupload/uploads/
. You can view this folder content athttp://127.0.0.1:3333/uploads/
in your browser. Make sure that this address is available.curl -I http://127.0.0.1:3333/uploads/ ##HTTP/1.1 200 OK
Important
You will have to specify it when configuring network.
Install tntapi¶
The tntapi component connects the Tarantool database and the facenapi component, transferring search results from the database to facenapi for further processing. To increase search speed, multiple tntapi shards can be created on each Tarantool host. Their running concurrently leads to a remarkable increase in performance. Each shard can handle up to approximately 10,000,000 faces. In the case of standalone deployment, you need only one shard (created by default), while in a cluster environment the number of shards has to be calculated depending on several parameters (see below).
Install tntapi standalone¶
Install and configure the tntapi
component as follows:
Install
tntapi
. Tarantool will be installed automatically along with it.sudo apt-get update sudo apt-get install findface-tarantool-server
Disable the Tarantool example service autostart and stop the service.
sudo systemctl disable tarantool@example && sudo systemctl stop tarantool@example
For a small-scale project, the
tntapi
shard created by default (tarantool@FindFace
) would suffice as 1 shard can handle up to 10,000,000 faces. Configuration settings of the default shard are defined in the file/etc/tarantool/instances.enabled/FindFace.lua
. We strongly recommend you not to add or edit anything in this file, except the maximum memory usage (memtx_memory
), the NTLS IP address required for thetntapi
licensing, and the remote access setting. The maximum memory usage should be set in bytes, depending on the number of faces the shard handles, at the rate roughly 1280 byte per face.Open the configuration file:
sudo vi /etc/tarantool/instances.enabled/FindFace.lua
Edit the value due to the number of faces the shard handles. The value
1.2*1024*1024*1024
corresponds to 1,000,000 faces:memtx_memory = 1.2 * 1024 * 1024 * 1024,
Specify the NTLS IP address if NTLS is remote:
FindFace.start(“127.0.0.1”, 8001, {license_ntls_server=“192.168.113.2:3133”})
With standalone deployment, you can access Tarantool by default only locally (
127.0.0.1
). If you want to access Tarantool from a remote host, either specify the remote host IP address in theFindFace.start
section, or change127.0.0.1
to0.0.0.0
there to allow access to Tarantool from any IP address. In the case-study below, you allow access only from192.168.113.10
:FindFace.start("192.168.113.10", 8001, {license_ntls_server=“192.168.113.2:3133”})
Now you allow access from any IP address:
FindFace.start("0.0.0.0", 8001, {license_ntls_server=“192.168.113.2:3133”})
Configure the
tntapi
shard to autostart and start the shard.sudo systemctl enable tarantool@FindFace && sudo systemctl start tarantool@FindFace
Retrieve the shard status. The command will return a service description, a status (should be Active), path and running time.
sudo systemctl status tarantool@FindFace
The
tntapi.json
file containing the tntapi shard parameters is automatically installed along withtntapi
into the/etc/
folder.Important
You will have to uncomment the path to
tntapi.json
when configuring network.
Install tntapi cluster¶
Install and configure the tntapi
component as follows:
Install
tntapi
on designated hosts. Tarantool will be installed automatically along it.sudo apt-get update sudo apt-get install findface-tarantool-server
Create
tntapi
shards on eachtntapi
host. To learn how to shard, let’s consider a case-study of a cluster environment containing 4 database hosts. We’ll create 4 shards on each.Important
When creating shards in large installations, observe the following rules:
- 1
tntapi
shard can handle approximately 10,000,000 faces. - The number of shards on a single host should not exceed the number of its physical processor cores minus 1.
- 1
Disable the Tarantool example service autostart and stop the service. Do so for all the 4 hosts.
sudo systemctl disable tarantool@example && sudo systemctl stop tarantool@example
Disable the shard created by default. Do so for all the 4 hosts.
sudo systemctl disable tarantool@FindFace
Write a bash script
shard.sh
that will automatically create configuration files for all shards on a particular host. Do so for the 4 hosts. Use the following script as a base for your own code. The exemplary script creates 4 shards listening to the ports: tntapi33001..33004
and http8001..8004
.Important
The script below creates configuration files based on the default configuration settings stored in the file
/etc/tarantool/instances.enabled/FindFace.lua
. We strongly recommend you not to add or edit anything in the default file, except the maximum memory usage (memtx_memory
) and the NTLS IP address required for thetntapi
licensing. The maximum memory usage should be set in bytes for each shard, depending on the number of faces a shard handles, at the rate roughly 1280 byte per face.Open the configuration file:
sudo vi /etc/tarantool/instances.enabled/FindFace.lua
Edit the value due the number of faces a shard handles. The value
1.2*1024*1024*1024
corresponds to 1,000,000 faces:memtx_memory = 1.2*1024*1024*1024,
Specify the NTLS IP address if NTLS is remote:
FindFace.start(“127.0.0.1”, 8001, {license_ntls_server=“192.168.113.2:3133”})
#!/bin/sh set -e for I in `seq 1 4`; do TNT_PORT=$((33000+$I)) && HTTP_PORT=$((8000+$I)) && sed " s#/opt/ntech/var/lib/tarantool/default#/opt/ntech/var/lib/tarantool/shard_$I#g; s/listen = .*$/listen = '127.0.0.1:$TNT_PORT',/; s/\"127.0.0.1\", 8001,/\"0.0.0.0\", $HTTP_PORT,/; " /etc/tarantool/instances.enabled/FindFace.lua > /etc/tarantool/instances.enabled/FindFace_shard_$I.lua; mkdir -p /opt/ntech/var/lib/tarantool/shard_$I/snapshots mkdir -p /opt/ntech/var/lib/tarantool/shard_$I/xlogs mkdir -p /opt/ntech/var/lib/tarantool/shard_$I/index chown -R tarantool:tarantool /opt/ntech/var/lib/tarantool/shard_$I echo "Shard #$I inited" done;
Tip
Download the
exemplary script
.Run the script from the home directory.
sudo sh ~/shard.sh
Check the configuration files created.
ls /etc/tarantool/instances.enabled/ ##example.lua FindFace.lua FindFace_shard_1.lua FindFace_shard_2.lua FindFace_shard_3.lua FindFace_shard_4.lua
Launch all the 4 shards. Do so on each host.
for I in `seq 1 4`; do sudo systemctl enable tarantool@FindFace_shard_$I; done; for I in `seq 1 4`; do sudo systemctl start tarantool@FindFace_shard_$I; done;
Retrieve the shards status.
sudo systemctl status tarantool@FindFace*
You should get the following output:
tarantool@FindFace_shard_3.service - Tarantool Database Server Loaded: loaded (/lib/systemd/system/tarantool@.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2017-01-10 16:22:07 MSK; 32s ago ... tarantool@FindFace_shard_2.service - Tarantool Database Server Loaded: loaded (/lib/systemd/system/tarantool@.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2017-01-10 16:22:07 MSK; 32s ago ... tarantool@FindFace_shard_1.service - Tarantool Database Server Loaded: loaded (/lib/systemd/system/tarantool@.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2017-01-10 16:22:07 MSK; 32s ago ... tarantool@FindFace_shard_4.service - Tarantool Database Server Loaded: loaded (/lib/systemd/system/tarantool@.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2017-01-10 16:22:07 MSK; 32s ago ...
Tip
You can view the
tntapi
logs by executing:sudo tail -f /var/log/tarantool/FindFace_shard_{1,2,3,4}.log
On the
findface-facenapi
host, create a filetntapi_cluster.json
containing the addresses and ports of all the shards. Distribute available shards evenly over ~1024 cells in one line. Click here to see the file for 4 hosts with 4 shards on each.Tip
You can create
tntapi_cluster.json
as follows:Create a file that lists all the shards, each shard with a new line (click here to view the example).
sudo vi s.txt
Run the script below (click here to view the script). As a result, a new file
tntapi_cluster.json
will be created and contain a list of all shards distributed evenly over 1024 cells.
cat s.txt | perl -lane 'push(@s,$_); END{$m=1024; $t=scalar @s;for($i=0;$i<$m;$i++){$k=int($i*$t/$m); push(@r,"\"".$s[$k]."\"")} print "[[".join(", ",@r)."]]"; }' > tntapi_cluster.json
Move
tntapi_cluster.json
to the directory/etc/
.Important
You will have to uncomment and specify the path to
tntapi_cluster.json
when configuring network.
Configure Network¶
After you install the FindFace Server components, configure their interaction with each other. Do the following:
Open the
findface-facenapi.ini
configuration file:sudo vi /etc/findface-facenapi.ini
Uncomment and/or edit the settings to align with your network specifications, substituting the suggested values with actual location:
ffupload_url = 'http://127.0.0.1:3333' mongo_host = '127.0.0.1' nnapi_url = 'http://127.0.0.1:18088' tntapi_servers_file = '/etc/tntapi.json'
Warning
The
findface-facenapi.ini
content must be correct Python code.Note
Do not specify
ffupload_url
if thefindface-upload
component is not installed.By default, if one or several tntapi shards are out of service during face identification, findface-facenapi returns an error. If necessary, uncomment the
tntapi_ignore_search_error
parameter and assign itTrue
. In this case findface-facenapi will use available tntapi shards to obtain face identification results, indicating the number of available servers vs the total number of servers in the response:tntapi_ignore_search_errors = True
Restart all the FindFace Enterprise Server SDK services and nginx (for
findface-upload
) on the relevant host(s).sudo service 'findface*' restart sudo service nginx restart
Check the services status. The command will return the services description, status (should be Active), path and running time.
sudo service 'findface*' status sudo service nginx status
Standalone Installer¶
To install FindFace Enterprise Server SDK in a standalone configuration, you can use the <findface-server-xxx>.run file. Do the following:
Warning
The .run file cannot be used for FindFace Enterprise Server SDK update from version 2.3 or earlier.
Put the .run file into some directory on the designated host (for example, /home/username).
From this directory, make the .run file executable.
chmod +x <findface-server-xxx>.run
Execute the .run file.
Warning
The
ntech
user will be automatically created at this stage. To avoid a conflict, make sure that such a user does not already exist in the system.sudo ./<findface-server-xxx>.run
The installer will perform several automated checks to ensure that the host meets the system requirements. After that, FindFace Enterprise Server SDK components will be automatically installed, configured and/or started in the following configuration:
Component Details findface-facenapi Installed and started with enabled and configured dynamic person creation and “friend or foe” identification. findface-nnapi Installed and started with the number of instances N = min(cores, RAM/2Gb)/2
and enabled and configured gender, age and emotions recognition.findface-server-tarantool (tntapi) Installed and started with the number of tntapi shards: N = min(cores, RAM/2Gb)/2
findface-tarantool- build-index Installed. Before use, consult the component documentation. ffupload Installed and started. fkvideo_detector Only installed. Use the command line interface or FindFace Web UI to manually start it. Before use, consult the component documentation. Extraction API Only installed. Exclusively for experienced users. Before use, be sure to consult the component documentation. NTLS Installed and started. FindFace Web UI Installed and started. findface-mass-enroll Only installed. Use the command line interface to work with it. Before use, consult the component documentation. nginx Installed and started. MongoDB Installed and started. Tarantool Database Installed and started. jq Installed. Used to pretty-print API responses from FindFace Server. Once the installation is complete, the following output will be shown in the console:
Tip
Be sure to save this data: you will need it later.
############################################### # Installation is complete # ############################################### - upload your license to http://172.16.213.249:3185/ login: admin password: fZh9-zZDX - user interface: http://172.16.213.249:8000/ - token for UI: fZh9-zZDX - documentation: http://172.16.213.249:8000/v1/docs/v1/overview.html Should you forget your password, recover it by executing findface-facenapi.token user@ubuntu:~$
Upload a license file via the NTLS web interface
http://<Host_IP_address>:3185/#/
. To access the NTLS web interface, use the credentials provided in the console.Note
Depending on whether the host belongs to a network, the host IP address in the links to FindFace web services is provided either as
127.0.0.1
, orIP address in the network
.
Create Authentication Token¶
Once the FindFace Server сomponents installed, create a token in the long or short format, depending on your preference. Either format, this token will be valid to authenticate your FindFace Enterprise Server SDK instance in API requests.
To create a long token, execute:
findface-facenapi.token
##0123456789_abcdefghijklmnopqrstuvw
To create a short token, execute:
findface-facenapi.token --short
##A0B1-C2D3
If MongoDB is installed on a remote host, you have to indicate the path to the findface-facenapi.ini
configuration file in the token generation command.
sudo findface-facenapi.token --config=/etc/findface-facenapi.ini
Test Requests¶
Before you can proceed with development and deliver face recognition services to your customers, make sure that the FindFace Server components are working. To do so, run the test requests below, minding the sequence. To pretty-print responses, we recommend you to use jq.
Note
The request messages here are provided only for reference. To create valid requests out of the examples below, replace the token in the messages with the actual one.
Tip
To proceed with development, find more code samples (in C#, PHP, Java and Python) on our GitHub.
In this section:
How to Pretty-Print Responses¶
Use jq to parse JSON data in responses. To install jq, execute:
sudo apt-get install jq
List Galleries¶
This request returns the name of the only gallery existing at the present moment. It is the default
gallery. Relevant REST API method: /galleries GET.
Request
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" http://localhost:8000/v0/galleries | jq
Response
{
"results": [
"default"
]
}
Create New Gallery¶
This request creates a new gallery testgal
. Relevant REST API method: /galleries/new POST.
Request
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" -X POST http://localhost:8000/v0/galleries/testgal | jq
Response
{
"name": "testgal"
}
Detect Face in Image¶
This request detects faces in a sample image on the Internet and returns coordinates of the rectangle around a detected face (bbox). Relevant REST API method: /detect POST.
Request
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" -F "photo=http://static.findface.pro/sample.jpg" http://localhost:8000/v0/detect | jq
Response
{
"faces": [
{
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
],
"orientation": 1
}
Add Face to Gallery¶
This request processes the same sample image as in the previous request, detects a face and adds the detected face to the default gallery with a unique meta tag. Relevant REST API method: /face POST.
Request
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" -F "photo=http://static.findface.pro/sample.jpg" -F "meta=Sam Berry" http://localhost:8000/v0/face | jq
Response
{
"results": [
{
"friend": false,
"galleries": [
"default"
],
"id": 3827229391220303,
"meta": "Sam Berry",
"normalized": "http://192.168.113.88:3333/uploads//20170517/1495011480937809.jpeg",
"person_id": 5,
"photo": "http://192.168.113.88:3333/uploads//20170517/14950114809306293.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.88:3333/uploads//20170517/149501148093593.jpeg",
"timestamp": "2017-05-17T08:58:00.930572",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
]
}
The following request also adds a face to a gallery but this time the face is extracted from a local image, and the gallery is custom (‘testgal’).
Request
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" -F "photo=@sample.jpg" -F "meta=sample" -F "galleries=testgal" http://localhost:8000/v0/face | jq
Response
{
"results": [
{
"friend": false,
"galleries": [
"default",
"testgal"
],
"id": 3827229578000564,
"meta": "sample",
"normalized": "http://192.168.113.88:3333/uploads//20170517/14950115538997407.jpeg",
"person_id": 5,
"photo": "http://192.168.113.88:3333/uploads//20170517/14950115538939695.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.88:3333/uploads//20170517/14950115538985784.jpeg",
"timestamp": "2017-05-17T08:59:13.893921",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
]
}
Compare Face with Those from Gallery¶
The following 2 requests process an image on the Internet (#1) and a local image (#2), detect a face and compare it with those from the default gallery. Return data of most similar faces and their similarity index. Relevant REST API method: /identify POST.
Request #1
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" -F "photo=http://static.findface.pro/sample2.jpg" http://localhost:8000/v0/identify | jq
Response
{
"results": {
"[515, 121, 821, 427]": [
{
"confidence": 0.9373,
"face": {
"age": 26.0483455657959,
"emotions": [
"neutral",
"sad"
],
"friend": false,
"galleries": [
"default"
],
"gender": "female",
"id": 3827062458772442,
"meta": "Sam Berry",
"normalized": "http://192.168.113.88:3333/uploads//20170516/1494946272949371.jpeg",
"person_id": 5,
"photo": "http://192.168.113.88:3333/uploads//20170516/14949462729435823.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.88:3333/uploads//20170516/14949462729480093.jpeg",
"timestamp": "2017-05-16T14:51:12.943000",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
}
]
}
}
Request #2
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" -F "photo=@Pictures/sample.jpg" http://localhost:8000/v0/identify | jq
Response
{
"results": {
"[595, 127, 812, 344]": [
{
"confidence": 0.9999,
"face": {
"age": 26.0483455657959,
"emotions": [
"neutral",
"sad"
],
"friend": false,
"galleries": [
"default"
],
"gender": "female",
"id": 3827062458772442,
"meta": "Sam Berry",
"normalized": "http://192.168.113.88:3333/uploads//20170516/1494946272949371.jpeg",
"person_id": 5,
"photo": "http://192.168.113.88:3333/uploads//20170516/14949462729435823.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.88:3333/uploads//20170516/14949462729480093.jpeg",
"timestamp": "2017-05-16T14:51:12.943000",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
}
]
}
}
Compare Two Faces¶
This request compares a face in a local image and that on the Internet. Relevant REST API method: /verify POST.
Request
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" -F "photo1=@Pictures/sample.jpg" -F "photo2=http://static.findface.pro/sample2.jpg" http://localhost:8000/v0/verify | jq
Response
{
"results": [
{
"bbox1": {
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
},
"bbox2": {
"x1": 515,
"x2": 821,
"y1": 121,
"y2": 427
},
"confidence": 0.9373794198036194,
"verified": true
}
],
"verified": true
}
List Faces from Galleries¶
The following requests return the list of all faces stored in galleries, both default and custom (#1), and only custom (#2). Relevant REST API method: /faces GET.
Request #1
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" http://localhost:8000/v0/faces | jq
Response
{
"next_page": "/v0/faces?max_id=3827058103081960",
"prev_page": null,
"results": [
{
"friend": false,
"galleries": [
"default",
"testgal"
],
"id": 3827229578000564,
"meta": "sample",
"normalized": "http://192.168.113.88:3333/uploads//20170517/14950115538997407.jpeg",
"person_id": 5,
"photo": "http://192.168.113.88:3333/uploads//20170517/14950115538939695.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.88:3333/uploads//20170517/14950115538985784.jpeg",
"timestamp": "2017-05-17T08:59:13.893000",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
},
{
"friend": false,
"galleries": [
"default"
],
"id": 3827229391220303,
"meta": "Sam Berry",
"normalized": "http://192.168.113.88:3333/uploads//20170517/1495011480937809.jpeg",
"person_id": 5,
"photo": "http://192.168.113.88:3333/uploads//20170517/14950114809306293.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.88:3333/uploads//20170517/149501148093593.jpeg",
"timestamp": "2017-05-17T08:58:00.930000",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
},
{
"age": 26.0483455657959,
"emotions": [
"neutral",
"sad"
],
"friend": false,
"galleries": [
"default"
],
"gender": "female",
"id": 3827227793957831,
"meta": "Sam Berry",
"normalized": "http://192.168.113.88:3333/uploads//20170517/14950108570078573.jpeg",
"person_id": 5,
"photo": "http://192.168.113.88:3333/uploads//20170517/14950108570022256.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.88:3333/uploads//20170517/14950108570066717.jpeg",
"timestamp": "2017-05-17T08:47:37.002000",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
]
}
Request #2
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" http://localhost:8000/v0/faces/gallery/testgal | jq
Response
{
"next_page": "/v0/faces/gallery/testgal?max_id=3827059994026334",
"prev_page": null,
"results": [
{
"friend": false,
"galleries": [
"default",
"testgal"
],
"id": 3827229578000564,
"meta": "sample",
"normalized": "http://192.168.113.88:3333/uploads//20170517/14950115538997407.jpeg",
"person_id": 5,
"photo": "http://192.168.113.88:3333/uploads//20170517/14950115538939695.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.88:3333/uploads//20170517/14950115538985784.jpeg",
"timestamp": "2017-05-17T08:59:13.893000",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
},
{
"galleries": [
"default",
"testgal"
],
"id": 3827059994026334,
"meta": "sample",
"normalized": "http://127.0.0.1:3333/uploads//20170516/14949453101653092.jpeg",
"photo": "http://127.0.0.1:3333/uploads//20170516/14949453101581762.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://127.0.0.1:3333/uploads//20170516/14949453101640306.jpeg",
"timestamp": "2017-05-16T14:35:10.158000",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
]
}
Recognize Gender, Age and Emotions¶
This request detects faces in a sample image on the internet and returns coordinates of the rectangle around a detected face (bbox) along with gender, age and emotions information. Relevant REST API method: /detect POST. API version: v1.
Note
First, you need to configure gender, age and emotions recognition.
Request
curl -H "Authorization: Token t3WGNhZbyaE_GFyQaywYllFoR2QkHXi-" -F 'photo=https://static.findface.pro/sample2.jpg' -F 'gender=true' -F 'emotions=true' -F 'age=true' http://localhost:8000/v1/detect | jq
Response
{
"faces": [
{
"age": 29.057680130004883,
"emotions": [
"neutral",
"happy"
],
"gender": "female",
"x1": 515,
"x2": 821,
"y1": 121,
"y2": 427
}
],
"orientation": 1
}
Video Face Detection¶
About Video Face Detection¶
To add video face detection to your FindFace Server Enterprise SDK instance, you need the fkvideo_detector component. This component extracts faces from video and posts them to FindFace Server over API for further processing. It can work with both live streams and files, and supports all video file formats and codecs that can be decoded by FFmpeg.
In this section:
Installation¶
Install fkvideo_detector from the <findface-repo>.deb package on one of the FindFace Server hosts or on a separate host:
Tip
Click here for the package preparation instruction.
sudo apt-get update
sudo apt-get install fkvideo-detector
How It Works¶
Motion Detection and Face Tracking¶
When processing video, fkvideo_detector consequently uses the following algorithms:
Motion detection. This algorithm is aimed to reduce system resources consumption. Only when the motion detector recognizes motion of certain intensity in video that the face tracker can be triggered.
Face tracking. The face tracker tracks, detects and captures faces from video, and posts them to FindFace Server. It can simultaneously process several faces.
Tip
Configure the maximum number of processed faces in the fkvideo_detector configuration file.
Each captured face is posted as a snapshot and a bbox in a request
/face
or/identify
, depending on the configuration settings. If there are several active trackers, the face tracker sends the same number of requests with a unique snapshot and bbox in each.
Best Face Search¶
When tracking a face, the face tracker searches for its best snapshot before posting it to FindFace Server.
The best face can be found in one of the following modes:
- Real-time
- Offline
Real-Time Mode¶
The real-time mode allows posting a face immediately after it appears in a camera field of view. In this mode, the face tracker searches for the best face snapshot dynamically:
- First, the face tracker estimates whether the quality of a face snapshot exceeds a pre-defined threshold value. If so, the snapshot is posted to FindFace Server.
- The threshold value increases after each post. Each time the face tracker gets a higher quality snapshot of the same face, it is posted.
- When the face disappears from the camera field of view, the threshold value resets to default.
Offline Mode¶
The offline mode is less storage intensive than the real-time one as it allows posting only one snapshot per face, but of the highest quality. In this mode, the face tracker buffers a video stream with a face in it until the face disappears from the camera field of view. Then the face tracker picks up the best face snapshot from the buffered video and posts it to FindFace Server.
Configuration and Usage¶
To configure fkvideo_detector, you can specify its options in any of the following ways:
As command line arguments upon starting fkvideo_detector.
fkvideo_detector [options]
As parameters in the fkvideo_detector configuration file.
Warning
The default fkvideo_detector configuration file is
/etc/fkvideo.ini
. Avoid editing/etc/fkvideo.ini
, especially if fkvideo_detector and FindFace Web UI are running on the same host, as FindFace Web UI also uses this configuration file. Instead, make a copy of this file, edit the copy and specify it in the option-c
when starting fkvideo_detector.## Make a copy of fkvideo.ini sudo cp /etc/fkvideo.ini /etc/fkvideo_example.ini ## Use this copy when starting fkvideo_detector fkvideo_detector -c /etc/fkvideo_example.ini
See Configuration Parameters for the full option list.
Video Stream Management¶
You can specify video streams to be processed by fkvideo_detector as follows:
- A single stream can be specified directly by using the
--camid
and--source
options when configuring fkvideo_detector. - A list of streams has first to be posted to FindFace Server by applying the /camera POST method to each stream. When posting, all streams in the list have to be assigned a common user-defined string, so called
detector
. This string should then be specified as the--detector-name
option when configuring fkvideo_detector. In this case, fkvideo_detector will retrieve the list of streams from FindFace Server, based on theirdetector-name
, and begin to process each stream individually. It will also be periodically updating the list of cameras from FindFace Server with a polling interval defined by thereload-timeout
parameter.
Configure and Start Video Face Detection¶
This section will guide you through the fkvideo_detector deployment process. Follow the steps below minding the sequence.
Note
The fkvideo_detector component has to be installed.
In this section:
Specify Video Streams¶
To specify video streams for face detection, do the following:
Make a copy of the configuration file
/etc/fkvideo.ini
. Open the new file for editing.sudo cp /etc/fkvideo.ini /etc/fk_local_config.ini sudo vi /etc/fk_local_config.ini
If you have only one camera, you can add it in the new configuration file.
[General] ; Host settings api-host=127.0.0.1 ; Put your token here api-token=RczGgVEMizR1njHHQegNH_g9mwGl6-A1 api-port=8000 ; Camera params ; If params doesn't set detector ask cameras list from server by key ; Key for receiving cameras list ;detector-name=detec1 ; Camera ID camid=local ; Stream path ; Example: rtsp:// - network stream; /dev/video0 - webcam; file@FPS:PATH - file with configurable FPS source=rtsp://admin:qwert1234@192.168.104.199:554/Streaming/Channels/1 ; Maximum cameras detectors-max=20 ; Motion detector scale coefficient for best performance scale=0.3 ; In realtime mode detector posts many frames wih increasing quality ; Else it sends only best frame realtime=1 ; URL that will receive frames request-url=/v1/face/ ; You can add custom head and body params to HTML POST request head= body=mf_selector=all,meta=User Meta ; ; Address of ntls server license-ntls-server=127.0.0.1:3133
Tip
You can find an example of the configuration file here.
If you have more than one camera, use the Server to store all your cameras. Add your camera to server by POST request v1/camera. For example, add camera to detector=detec1:
Request
curl -H 'Authorization: Token 1234567890qwertyuiop' -F "detector=detec1" -F "url=rtsp://user:pass@192.168.1.1:554/Streaming/Channels/1" -F "meta=test" http://localhost:8000/v1/camera
Response
{"detector": "detec1", "id": "0e663c00-b945-4676-bb0e-032c1dcf353a", "meta": "test", "url": "rtsp:// user:pass@192.168.1.1:554/Streaming/Channels/1"}
Now edit your configuration file. For example, detector will connect to server, and get all cameras with detector=detec1
[General] ; Host settings api-host=127.0.0.1 ; Put your token here api-token=RczGgVEMizR1njHHQegNH_g9mwGl6-A1 api-port=8000 ; Camera params ; If params doesn't set detector ask cameras list from server by key ; Key for receiving cameras list detector-name=detec1 ; Camera ID ;camid= ; Stream path ; Example: rtsp:// - network stream; /dev/video0 - webcam; file@FPS:PATH - file with configurable FPS ;source= ; Maximum cameras detectors-max=20 ; Motion detector scale coefficient for best performance scale=0.3 ; In realtime mode detector posts many frames wih increasing quality ; Else it sends only best frame realtime=1 ; URL that will receive frames request-url=/v1/face/ ; You can add custom head and body params to HTML POST request head= body=mf_selector=all,,meta=UserMeta ; ; Address of ntls server license-ntls-server=127.0.0.1:3133
Tip
You can find an example of the configuration file here.
Start Component as Application¶
To start fkvideo_detector as an application, execute:
fkvideo_detector -c /etc/fk_local_config.ini
Use this method for testing purposes.
Start Component as Service¶
To run the face detection component as a service, do the following:
Execute the following command:
sudo service fkvideo_detector@fk_local_config start
Check service status. The command will return a service description, a status should be active (running).
sudo service fkvideo_detector@fk_local_config status
Note
You can get the list of your cameras by the following request:
curl -H 'Authorization: Token 1234567890qwertyuiop' http://localhost:8000/v1/camera | jq
Configuration Parameters¶
To configure fkvideo_detector, you can specify its options in any of the following ways:
As command line arguments upon starting fkvideo_detector.
fkvideo_detector [options]
As parameters in the fkvideo_detector configuration file.
Warning
The default fkvideo_detector configuration file is
/etc/fkvideo.ini
. Avoid editing/etc/fkvideo.ini
, especially if fkvideo_detector and FindFace Web UI are running on the same host, as FindFace Web UI also uses this configuration file. Instead, make a copy of this file, edit the copy and specify it in the option-c
when starting fkvideo_detector.## Make a copy of fkvideo.ini sudo cp /etc/fkvideo.ini /etc/fkvideo_example.ini ## Use this copy when starting fkvideo_detector fkvideo_detector -c /etc/fkvideo_example.ini
In this section:
Command Line Arguments¶
Usage:
fkvideo_detector [options]
Allowed options:
Warning
The following parameters are mandatory: api-host
, api-port
, api-token
, --license-ntls-server
.
Option | Description | Argument | Example |
---|---|---|---|
-c [ ‑‑config ] arg | Invokes fkvideo_detector with a given configuration file (.ini ). The command line parameters and those in the configuration file have the same names and meaning, but if a parameter is set either way, the command line value has priority. |
Path to the .ini configuration file. If you specify the file name alone (without the full path), fkvideo_detector will search for the file in the fkvideo_detector working directory. The default fkvideo_detector configuration file is /etc/fkvideo.ini . If fkvideo_detector and FindFace Web UI are running on the same host, avoid editing /etc/fkvideo.ini as it is also used by FindFace Web UI. Instead, make a copy of this file, edit the copy and specify it in the option -c when starting fkvideo_detector. |
$ fkvideo_detector -c /etc/fkvideo_example.ini |
‑‑license-ntls-server arg | Mandatory. Defines the IP address and port of NTLS. Edit only if NTLS is remote. | NTLS IP address:port | ‑‑license-ntls-server 192.168.10.1:3133 |
-n [ ‑‑detector-name ] arg | Applies fkvideo_detector to a given list of cameras. | Unique video detector identifier (hostname by default) which corresponds to a particular list of cameras stored on FindFace Server. | ‑‑detector-name detec1 |
-d [ ‑‑detectors-max ] arg | Defines the maximum number of video streams to be processed by fkvideo_detector. | Maximum number of video streams simultaneously processed by fkvideo_detector (5 by default). | ‑‑detectors-max 7 |
-t [ ‑‑reload-timeout ] arg | Defines the interval between 2 consecutive requests fkvideo_detector sends to FindFace Server to update the list of cameras. | Interval in seconds between 2 consecutive camera list updates (15 s by default). | -t 20 |
‑‑camid arg | Defines a video stream to be processed by fkvideo_detector, as the relevant camera id (see also --source ). If a video stream is not specified, fkvideo_detector requests the list of cameras from FindFace Server with a polling interval defined by the reload-timeout parameter. |
Camera id. | ‑‑camid b28a898b-6334 |
‑‑api-host arg | Mandatory. Defines the FindFace Server host fkvideo_detector will be sending API requests to. | FindFace Server host IP address. | ‑‑api-host 127.0.0.1 |
‑‑api-port arg | Mandatory. Defines the FindFace Server host port for API requests. | Port number. | ‑‑api-port 8000 |
‑‑api-token arg | Mandatory. Defines the authentication token for FindFace Server. | Authentication token. | ‑‑api-token c9FsRNDAt |
-S [ ‑‑source ] arg | Defines a video stream to be processed by fkvideo_detector, as the relevant camera address (see also --camid ). If a video stream is not specified, fkvideo_detector requests the list of cameras from FindFace Server with a polling interval defined by the reload-timeout parameter. |
Camera address: rtsp://... - network stream, /dev/video0 – webcam, file@FPS:PATH - file with configurable FPS. |
‑‑source rtsp://192.168.120.55:500 |
‑‑source-params arg | Defines ffmpeg options for a video stream. | List of ffmpeg options with their values. | ‑‑source-params rtsp_transport=tcp, rtsp_flags=prefer, timeout=-1 |
‑‑md-threshold arg | Defines the minimum motion intensity to be detected by the motion detector. The threshold value is to be fitted empirically. | Motion intensity in empirical units (zero and positive rational numbers). Milestones: 0 = detector disabled, 0.002 = default value, 0.05 = minimum intensity is too high to detect motion. | ‑‑md-threshold 0.003 |
‑‑scale arg | Defines a video frame scaling coefficient for the motion detector. Scale down in the case of high resoultion cameras, or close up faces, or if the CPU load is too high, to reduce the system resources consumption. Make sure that the scaled face size exceeds the min-face-size value. |
Video frame scaling coefficient. | ‑‑scale 0.3 |
‑‑request-url arg | Defines the request fkvideo_detector sends to FindFace Server when posting a face. | /v0/face/ or /v0/identify/. | ‑‑request-url /v0/identify |
‑‑camera-url arg | Defines the request fkvideo_detector sends to FindFace Server to obtain the list of cameras. | /v0/camera (default) or /v1/camera. | ‑‑camera-url /v1/camera |
‑‑img-arg arg | Defines the name of the argument containing a bbox with a face, in an API request. | Argument name (photo by default). | ‑‑img-arg picture |
‑‑req-timeout arg | Defines a timeout for a FindFace Server response to a fkvideo_detector API request. | API response timeout in seconds (3 s by default). | ‑‑req-timeout 2 |
‑‑headers arg | Creates an additional header field in a POST request when posting a face. | Additional header field in a POST request. | ‑‑headers xxx = yyy ‑‑headers kkk = ppp |
‑‑body arg | Creates additional body fields in the request body when posting a face. | Additional body field(s). | ‑‑body galleries=testgal ‑‑body gender=true ‑‑body age=true ‑‑body emotions=true ‑‑body meta=video.mp4 |
‑‑bbox-scale | Defines a bbox scaling coefficient. | Bbox scaling coefficient (1 by default). | ‑‑bbox-scale 1.3 |
‑‑post-uniq arg | Enables posting only a certain number of faces belonging to one person, during a certain period of time. In this case, if fkvideo_detector posts a face to FindFace Server and then tracks another one within the time period uc-max-time-diff , and the distance between the two faces doesn’t exceed uc-max-avg-shift , fkvideo_detector estimates their similarity. If the faces are similar and the total number of similar faces during the uc-max-time-diff period does not exceed the number uc-max-dup , fkvideo_detector posts the other face. Otherwise, the other face is not posted. |
Boolean: 1 = only a certain number of faces belonging to one person are posted, 0 = all captured faces are posted. | ‑‑post-uniq 1 |
‑‑uc-max-time-diff arg | Defines the maximum time period during which a number of similar faces are considered as belonging to one person. | Maximum time period in seconds. | ‑‑uc-max-time-diff 1 |
‑‑uc-max-dup arg | Defines the maximum number of faces during the uc-max-time-diff period that is posted for a person. |
Maximum number of faces. | ‑‑uc-max-dup 3 |
‑‑uc-max-avg-shift arg | Defines the distance within which a number of similar faces are considered as belonging to one person. | Distance in pixels. | ‑‑uc-max-avg-shift 10 |
-r [ ‑‑realtime ] [=arg(=1)] | Enables the real-time mode of fkvideo_detector. | Mode of fkvideo_detector: 1 = real-time, 0 = off-line. -r and -r 1 are equal. | -r or -r 1, -r 0 |
‑‑min-score arg | Defines the minimum threshold value for a face image quality. A face is posted if it has better quality. The threshold value is to be fitted empirically. | Minimum threshold value for the face quality in empirical units (negative rational numbers to zero). Milestones: 0 = poor quality, -10 = satisfactory quality, -15 = good quality etc. The default value is -7. | ‑‑min-score -11.5 |
‑‑min-dir-score arg | Defines the maximum deviation of a face from its frontal position. A face is posted if its deviation is less than this value. The deviation is to be fitted empirically. | Maximum deviation of a face from its frontal position in empirical units (negative rational numbers to zero). Milestones: -20 = satisfactory deviation, -10 = close to the frontal position, 0 = frontal face. The default value is -1000. | ‑‑min-dir-score -12 |
‑‑rt-refresh arg | Only for the real-time mode. Defines the time interval for the best face score auto-refresh during the better snapshot dynamic search. | Time period in milliseconds. The default value is 0 (disabled). | ‑‑rt-refresh 10 |
‑‑rt-score-step arg | Only for the real-time mode. Defines the threshold increase step for the better snapshot dynamic search. | Threshold increase step (positive rational numbers). | ‑‑rt-score-step 3.4 |
‑‑rt-delay arg | Only for the real-time mode. Defines the minimum time period between 2 posts of the same face with increased quality. | Time period in milliseconds between 2 posts of the same face with increased quality. | ‑‑rt-delay 100 |
‑‑rot arg | Enable detecting and tracking faces only inside a clipping rectangle. You can use this option to reduce fkvideo_detector load. | Clipping rectangle: WxH+X+Y (see the specification of X geometry). | ‑‑rot 150x123+300+155 |
‑‑roi arg | Enable posting faces detected only inside a region of interest. | Region of interest: WxH+X+Y (see the specification of X geometry). | ‑‑roi 123x122+159+220 |
‑‑draw-track [=arg(=1)] | Enable drawing a face motion track in a bbox. | Boolean: 1 = tracks are enabled, 0 = tracks are disabled. ‑‑draw-track and ‑‑draw-track 1 are equal. | ‑‑draw-track |
‑‑min-face-size arg | Defines the minimum size of a face. Undersized faces are not posted. | Minimum size of a bbox minor side in pixels. | ‑‑min-face-size 50 |
‑‑max-face-size arg | Defines the maximum size of a face. Oversized faces are not posted. | Maximum size of a bbox major side in pixels. | ‑‑max-face-size 120 |
‑‑max-persons arg | Defines the maximum number of faces simultaneously tracked by the face tracker. This parameter severely affects performance. | Maximum number of simultaneously tracked faces. | ‑‑max-persons 4 |
‑‑single-pass [=arg(=1)] | Disables periodical updates of the list of cameras. Use this option if fkvideo_detector should process a video file. In this case, fkvideo_detector will request the list of cameras only once. | Boolean: 1 = updates are disabled, 0 = updates are enabled. ‑‑ single-pass and ‑‑single-pass 1 are equal. | ‑‑ single-pass 0 |
‑‑start-ts arg | Adds a frame timestamp into a face posting request. | Boolean: 1 = timestamps are added, 0 = timestamps are disabled. | ‑‑start-ts 1 |
‑‑disable-drops [=arg(=1)] | Enables posting all appropriate faces without drops. By default, if fkvideo_detector does not have enough resources to process all frames with faces, it drops some of them. If this option is active, fkvideo_detector puts odd frames on the waiting list to process them later. | Boolean: 1 = drops are disabled, 0 = drops are enabled. ‑‑disable-drops and ‑‑disable-drops 1 are equal. | ‑‑disable-drops |
‑‑sink-url arg | Only if fkvideo_detector processes 1 camera defined in the configuration file or in command line arguments. Defines the nginx video server IP address for the output video stream (it is there further redirected to FindFace Web UI). | Nginx video server IP address. | ‑‑sink-url 192.168.15.1:3222 |
‑‑sink-res arg | Defines the output video stream resolution. | Resolution WхH | ‑‑sink-res 1280x720 |
‑‑tracker-threads arg | Defines the number of tracking threads for the face tracker. This value should be less or equal to the max-persons value. We recommend you to set them equal. If the number of tracking threads is less than the maximum number of tracked faces, resource consumption is reduced but so is the tracking speed. |
Number of tracking threads | ‑‑tracker-threads 4 |
-h [ ‑‑help ] | Produce the fkvideo_detector help message. | ─ | ─ |
Configuration File Format¶
[General]
| long-arg=option ; long-arg from command line arguments
| ...
| license-ntls-server=192.168.10.1:3133
| source-params=rtsp_transport=tcp,rtsp_flags=prefer,timeout=-1
| body=galleries=testgal,gender=true,age=true,emotions=true,meta=video.mp4
Render Detection Results¶
The fkvideo_detector component does not process FindFace Server responses to face identification and camera operation API requests. You should write your own proxy script that will manage communication between fkvideo_detector and FindFace Server and redirect API responses to an application that can process and render them. A typical rendering topology is shown on the diagram below:

When writing the proxy script, hold to the following logic:
A request from fkvideo_detector transparently goes to FindFace Server in the following format:
curl -X POST -H 'Authorization: Token ntech' -F "gender=true" -F "emotions=true" -F "age=true" -F "cam_id=1b19a189-26b9-42e5-8cd8-6cabde79dc7e" -F "timestamp=2017-08-25T13:09:54" -F "bbox=[[620,380,1383,1143]]" -F "photo=@15036665986531599.jpeg" -F "face0=@15036665986766284_norm.png" -F 'detectorParams={"score": -0.000911839, "direction_score": -0.568228}' http://192.168.104.184:8000/v1/face
As FindFace Server replies to fkvideo_detector, your proxy script should redirect the response to your application for further processing.
Note
FindFace Server responses to requests sent directly or by fkvideo_detector are same. They may contain a link to a face thumbnail and other data which can be parsed in your application.
Increase Performance¶
Load Balancing with NginX¶
To enhance throughput and reduce latency in highload installations with severe requirements to resource optimization, we recommend you to set up nginx load balancing.
With load balancing, traffic, instead of being directed to a single instance of a component, is proxied via nginx and distributed across multiple instances of the component in a round-robin fashion. As a result, you remarkably reduce latency and improve overall performance, scalability and reliability of your system.
Load balancing can be set up for the following components:
Component | Recommended number of instances per host |
---|---|
findface-facenapi |
1 is usually enough. When it comes to findface-facenapi, load balancing is usually set up only in a cluster environment with several findface-facenapi hosts, 1 findface-facenapi instance running on each host. In this case, traffic is distributed across these hosts. |
findface-nnapi |
Number of CPU cores minus 1. Gives a significant performance gain. |
extraction-api |
1, automatically load-balanced. Set up load balancing only across extraction-api instances located on different physical hosts. |
The following step-by-step instructions demonstrate how to set up nginx load balancing for 2 findface-nnapi
instances on a host. The other
components can be load-balanced by analogy.
Do the following:
If necessary, install nginx on the findface-nnapi host (nginx is installed automatically along with the
findface-upload
component).sudo apt-get install nginx
Copy the content of the
/lib/systemd/system/findface-nnapi.service
file into a new file/etc/systemd/system/findface-nnapi@.service
.sudo cp /lib/systemd/system/findface-nnapi.service /etc/systemd/system/findface-nnapi@.service
Stop all the
findface-nnapi
services and disable their autostart. Edit the new filefindface-nnapi@.service
by appending--listen 127.0.0.1:%i
to theExecStart
line.sudo service findface-nnapi stop && sudo systemctl disable findface-nnapi sudo vi /etc/systemd/system/findface-nnapi@.service ExecStart=/usr/bin/findface-nnapi -c /etc/findface-nnapi.ini --listen 127.0.0.1:%i
Create a new nginx configuration file.
sudo vi /etc/nginx/sites-available/nnapi
Insert the following text into the configuration file. In the text, substitute provided ports for findface-nnapi instances (‘upstream nnapibackends’) and the findface-nnapi listening port (‘listen’) with their actual values. Port numbers should be unique for each component on the host.
upstream nnapibackends { server 127.0.0.1:18090; server 127.0.0.1:18091; } server { listen 18088; server_name nnapi; client_max_body_size 64m; location / { proxy_pass http://nnapibackends; proxy_next_upstream error; } access_log /var/log/nginx/nnapi.access_log; error_log /var/log/nginx/nnapi.error_log; }
Enable the load balancer in nginx.
sudo ln -s /etc/nginx/sites-available/nnapi /etc/nginx/sites-enabled/
Restart nginx.
sudo service nginx restart
For each findface-nnapi instance, enable autostart.
sudo systemctl enable findface-nnapi@18090 sudo systemctl enable findface-nnapi@18091
Start the findface-nnapi instances.
sudo systemctl start findface-nnapi@18090 sudo systemctl start findface-nnapi@18091
From now on, requests sent to findface-nnapi will be distributed over 2 findface-nnapi instances in the round-robin mode. You can view the process of requests distribution in the findface-nnapi log file /var/log/syslog (look for different process_id values).
sudo tail -f /var/log/syslog | grep nnapi Jul 7 03:53:05 ubuntu findface-nnapi[49606]: (2017-07-07 10:53:05) [INFO ] Request: 127.0.0.1:34494 0x7fb100000960 HTTP/1.0 POST /facen Jul 7 03:53:06 ubuntu findface-nnapi[49606]: (2017-07-07 10:53:06) [INFO ] Response: 0x7fb100000960 /facen?x2=0&y1=0&x1=0&y2=0 200 0 Jul 7 03:53:06 ubuntu findface-nnapi[49624]: (2017-07-07 10:53:06) [INFO ] Request: 127.0.0.1:52960 0x7f9cf8000960 HTTP/1.0 POST /facen Jul 7 03:53:06 ubuntu findface-nnapi[49624]: (2017-07-07 10:53:06) [INFO ] Response: 0x7f9cf8000960 /facen?x2=0&y1=0&x1=0&y2=0 200 0 Jul 7 03:53:32 ubuntu findface-nnapi[49606]: (2017-07-07 10:53:32) [INFO ] Request: 127.0.0.1:34502 0x7fb100001ec0 HTTP/1.0 POST /facen Jul 7 03:53:32 ubuntu findface-nnapi[49606]: (2017-07-07 10:53:32) [INFO ] Response: 0x7fb100001ec0 /facen?x2=0&y1=0&x1=0&y2=0 200 0 Jul 7 03:53:32 ubuntu findface-nnapi[49624]: (2017-07-07 10:53:32) [INFO ] Request: 127.0.0.1:52968 0x7f9cf8001ec0 HTTP/1.0 POST /facen Jul 7 03:53:33 ubuntu findface-nnapi[49624]: (2017-07-07 10:53:33) [INFO ] Response: 0x7f9cf8001ec0 /facen?x2=0&y1=0&x1=0&y2=0 200 0
Tip
You can use this method to set up load balancing across instances on several physical hosts.
Fast Index¶
For galleries with the number of faces over 1,000,000
, we recommend you to speed up search by using a fast index. To prepare the fast index, you will need the findface-tarantool-build-index
utility from your distribution package. This utility is independent of the tntapi
component and can be installed either on a localhost or on a remote host with access to Tarantool.
To prepare the fast index, do the following:
Install the
findface-tarantool-build-index
utility.sudo apt-get install findface-tarantool-build-index
Create the fast index for your gallery (
testgal
in the case-study). First, connect to the Tarantool console.Note
You have to repeat the fast index creation on each
tntapi
shard.tarantoolctl connect 127.0.0.1:33001
Run
prepare_preindex
. Each element of the gallery will be moved from thelinear
space topreindex
:127.0.0.1:33001> FindFace.Gallery.new("testgal"):prepare_preindex() --- ...
Prepare a file for generating the index:
127.0.0.1:33001> FindFace.Gallery.new("testgal"):save_preindex("/tmp/preindex.bin") --- ...
Launch index generation with the
findface-build-index
utility (see--help
for additional options). Depending on the number of elements, this process can take up to several hours and can be done on a separate, more powerful machine (for huge galleries we recommend c4.8xlarge amazon, for example spot-instance).sudo findface-build-index --input /tmp/preindex.bin --facen_size 320 --out /opt/ntech/var/lib/tarantool/default/index/testgal.idx 0% 10 20 30 40 50 60 70 80 90 100% |----|----|----|----|----|----|----|----|----|----| ************************************************** 0% 10 20 30 40 50 60 70 80 90 100% |----|----|----|----|----|----|----|----|----|----| ************************************************** [Benchmark] create_index took 29.994ms Index saved at /opt/ntech/var/lib/tarantool/default/index/testgal.idx
Delete the
preindex.bin
file.sudo rm /tmp/preindex.bin
Enable the fast index for the gallery.
Note
If Tarantool works as a replica set, copy the index file (
.idx
) from the master instance to the same path on the replica before enabling the fast index for the master instance (:use_index
).Tip
Do not forget to remove obsolete index files on the replica in order to avoid unnecessary index transitions, should the master instance and replica be heavily out of sync.
127.0.0.1:33001> FindFace.Gallery.new("testgal"):preindex_to_index() --- ... 127.0.0.1:33001> FindFace.Gallery.new("testgal"):use_index("/opt/ntech/var/lib/tarantool/default/index/testgal.idx") --- ...
Search through the gallery should now be significantly faster. Information about the index remains in the service space, so when you restart Tarantool, index will also be uploaded.
Warning
Do not move the index file to another location!
FindFace Web User Interface¶
FindFace Enterprise Server SDK is equipped with a web user interface which generally duplicates the functionality available via REST API.
To install the web interface, execute on the findface-facenapi
host:
Note
First install nginx if you do not already have it. You can do this as such:
sudo apt-get install nginx
sudo apt-get install findface-ui
To open the web interface, do the following:
In the address bar of your browser, enter
http://<facenapi_ip>:8000/#/
.To log in, specify the authentication token for your FindFace Enterprise Server SDK instance. The web interface home page will appear.
The web interface has a highly intuitive and handy design and provides the following functionality:
Note
To work with gender, age and emotions recognition (GAE) in the web interface, you need to configure it in the settings.
Note
Working with photos requires configured findface-upload.
Note
Working with persons requires configured dynamic person creation.
Note
To allow the web interface to run Flash in Chrome, add its IP address to the relevant list: http://<facenapi_ip>:8000/#/
. Restart Chrome.
Galleries. Create and delete galleries here.
Faces. In this section, you can view, add and delete faces from the galleries.
Use the Batch upload option to upload image files in bulk.
Tip
You may also want to use its console alternative.
Select multiple files or a directory, and then configure the automatic meta description for the enrolled faces. Use MF selector to specify behavior in case if multiple faces are detected in an image: enroll all faces, only the biggest one, or reject enrollment.
Tip
You can configure the automatic face meta by appending a custom prefix and/or postfix to the image file name. To avoid merging the 3 words into one, use underscore or another symbol in the prefix and postfix.
Tip
To select photos in the icons mode, click on them as you hold down the
CTRL
key.Persons. View and filter persons here.
Photo processing. Select this section to detect faces in static images, recognize gender, age and emotions, search a face in the database (identification), and compare two faces (verification).
Video processing. Here you can work with video streams from rtsp and web cameras, and video files. Detect, enroll (add to a gallery) and identify faces in video with gender, age and emotions recognition. Generate enrollment and face identification reports in HTML by clicking on the Save demo report button.
Note
The video processing functionality in the web interface is great for tests. In production mode, use fkvideo_detector.
Advanced Features¶
Gender, Age and Emotions Recognition¶
In this section:
Configure Gender, Age and Emotions Recognition¶
Note
Gender, age and emotions recognition uses around 2 GB of RAM in addition to the FindFace Server general requirements.
To configure gender, age and emotions recognition, do the following:
Enable gender, age and emotions recognition by uncommenting and editing the line
gae = False
in thefindface-facenapi
configuration file. Restartfindface-facenapi
.Warning
The
findface-facenapi.ini
content must be correct Python code.sudo vi /etc/findface-facenapi.ini → gae = True sudo service findface-facenapi restart
Enable relevant recognition models by uncommenting the
model_*
lines in thefindface-nnapi
configuration file. Restartfindface-nnapi
.sudo vi /etc/findface-nnapi.ini → model_emotions = emotion_1 → model_age = fr_1_age0 → model_gender = fr_1_gender0 sudo service findface-nnapi restart
API Requests for Gender, Age and Emotions Recognition¶
An exemplary API request for recognizing gender, age and emotions of a person, and the corresponding response are shown below.
Request #1
POST /v1/detect/ HTTP/1.1
Host: 192.168.113.76:8000
Connection:close
Authorization: Token BpdNA6eaUlN9bPhXVSK1r92_SFOODPOU
Content-Type: application/json
Content-Length: 108
{
"photo": "https://static.findface.pro/sample.jpg",
"emotions": true,
"gender": true,
"age": true
}
Response
HTTP/1.1 200 OK
Date: Thu, 06 Apr 2017 12:38:40 GMT
Server: TornadoServer/4.4.2
Content-Length: 120
Content-Type: application/json; charset=UTF-8
{
"faces": [
{
"age": 26,
"emotions": [
"neutral",
"sad"
],
"gender": "female",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
]
}
To add a face to the database with its gender, age and emotions information, send a POST request to v1/face.
Request #2
POST /v1/face/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"meta": "Jane Berry",
"photo": "http://static.findface.pro/sample.jpg",
"galleries": ["gal1", "niceppl"],
"emotions": true,
"gender": true,
"age": true
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 06:04:02 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: [length]
{
"results": [
{
"galleries": ["default", "gal1", "niceppl"]
"id": 2334,
"meta": "Jane Berry",
"photo": "http://static.findface.pro/sample.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:11:29.425339",
"age": 26,
"emotions": [
"neutral",
"sad"
],
"gender": "female",
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
}
]
}
Dynamic Person Creation¶
You can tailor FindFace Enterprise Server SDK to work in video surveillance and video analytics systems. To do so, harness the Dynamic Person Creation feature.
In this section:
How it works¶

- An image containing a face (for example, extracted from a RTSP video stream by the video face detector) is sent via a
/face POST
request to FindFace Server for identification. - When identifying a person, the system uses a face property
person_id
. For each person in the database, the value of this property should be unique. - FindFace Server takes the new face and searches for the most similar one in the database (the so-called reference face). If similarity between the faces is equal or exceeds the threshold specified in the
findface-facenapi.ini
configuration file (person_identify_threshold
), the new face is added to the database and assigned the sameperson_id
value as the reference face. It also inherits some other reference face properties. This means that the new face has been identified as belonging to an existing person. - If similarity between the faces does not exceed the given threshold, the system considers the new face as unidentified. In this case, the new face is added to the database as belonging to a new person, with a new
person_id
. - In either case, FindFace Server returns a response containing the
person_id
value assigned to the added face. This value can be then used in analysis.
Warning
On account of the very logic of dynamic person creation, resembling faces of different people can be identified as belonging to one person and get the same person_id
. To avoid this situation, we recommend you to periodically inspect the person database and manually resolve each identity conflict.
Configure Dynamic Person Creation¶
By default, dynamic person creation is disabled. This means that all newly added faces are not assigned the person_id property and the system does not discern persons.
To enable dynamic person creation, do the following:
Open the
findface-facenapi.ini
configuration file for editing.sudo vi /etc/findface-facenapi.ini
Edit the settings.
Warning
The
findface-facenapi.ini
content must be correct Python code.Uncomment and edit the line
person_identify = False
. This will enable dynamic person creation.→ person_identify = True
By default, dynamic person creation is performed independently for each camera. To merge person identification results across all cameras, uncomment and edit the line
person_identify_global = False
. This option works well only in small-scale systems with less than 5 cameras. Otherwise, leave it deactivated.→ person_identify_global = True
Uncomment and set the threshold for person identification between 0 and 1.
→ person_identify_threshold = 0.75
Restart the service.
sudo service findface-facenapi restart
REST API Sequence for Person Dataset Analysis¶
There are many ways to harness the dynamic person creation feature in analytics. A typical REST API sequence to identify a person and then work with their data is the following:
# | Method | Description |
---|---|---|
1 | /face POST | Add a face to the database and receive a JSON representation of it, including the person_id value. |
2 | /history/search POST | Retrieve all events from the history of cameras, related to the person whose person_id was received in the /face POST response. |
Method /face POST¶
Request
POST /v0/face/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"photo": "http://static.findface.pro/sample.jpg"
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results": {
"[595, 127, 812, 344]": [
{
"confidence": 1,
"face": {
"friend": false,
"galleries": [
"default"
],
"id": 2,
"meta": "Jack Smith",
"normalized": "http://192.168.113.76:3333/uploads/20170418/1492509569217098.jpeg",
"person_id": 2,
"photo": "http://192.168.113.76:3333/uploads/20170418/14925095692111893.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.76:3333/uploads/20170418/14925095692159095.jpeg",
"timestamp": "2017-04-18T09:59:29.211000",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
}
]
}
}
Method /history/search POST¶
Request
POST /v0/history/search HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"person_id": 2,
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"next_page": "/v0/history/search?max_id=4",
"results":[
{
"friend":false,
"meta":"Jack Smith",
"photo_hash":"9fda49f2444f93c33ad8aa914e20e53b",
"cam_id":"12345678123456781234567812345678",
"person_id":2,
"timesamp":"2016-10-11T14:36:27.450000",
"photo":"http://192.168.113.76:3333/uploads/20170418/149250956922566.jpeg",
"id":20146,
"y1":77,
"x1":285,
"x2":552,
"y2":345
},
{
"friend":false,
"meta":"Jack Smith",
"photo_hash":"dc7ac54590729669ca869a18d92cd05e",
"cam_id":"12345678123456781234567812345678",
"person_id":2,
"timesamp":"2016-10-12T12:57:07.509000",
"photo":"http://192.168.113.76:3333/uploads/20170418/14925095692111596.jpeg",
"id":20147,
"x1":236,
"y1":345,
"x2":311,
"y2":419
}
]
}
Other API Methods to Work with Persons¶
Add and change person_id
¶
To add or change the person_id
value for a particular face, use the method PUT /face/id/<face_id>
.
Warning
Since the person_id
property is assigned only to newly added faces, old faces in the database are excluded from the person identification process. Use the method PUT /face/id/<face_id>
to solve the problem.
Request
PUT /v0/face/id/5/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"person_id": "4"
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"id": 5,
"meta": "Jane Richardson",
"person_id": "4",
"photo": "http://static.findface.pro/sample2.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:06:42.075754",
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
}
Retrieve person history¶
To retrieve all events from the history of cameras, related to the person with a given person_id
, you can use the method GET /person/history/id/<person_id>
(equally with /history/search POST
).
Request
GET v0/person/history/id/2001 HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"cam_ids": [1, 25, 26, 27],
"start": "2016-06-13T11:00:00.000000",
"end": "2016-06-14T11:00:00.000000"
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results":
[
{
"person_id": 2001,
"face_id": 240344,
"cam_id": 25,
"meta": "Sam Berry",
"screenshot":"https://static.findface.pro/57726179d6946f02f3763824/dc7ac54590729669ca869a18d92cd05e_thumb.j
pg",
"timestamp": "2016-06-13T11:06:42.075754",
},
{
"person_id": 2001,
"face_id": 240422,
"cam_id": 25,
"meta": "Sam Berry",
"screenshot": "https://static.findface.pro/57726179
d6946f02f3763824/dc7ac54590729669ca869a18d92cd05e_thumb.j
pg",
"timestamp": "2016-06-13T11:08:44.073452",
}
]
}
List persons¶
To get the list of all existing persons, use the method GET /persons
.
Request
GET /v0/persons HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results": [
{
"id": 2,
"meta": ""
}
]
}
‘Friend or Foe’ Identification¶
As you configure Dynamic Person Creation, you can also enable ‘friend or foe’ identification in order to further enhance your video analytics.
In this section:
About Friends and Foes¶
The ‘friend or foe’ identification system of FindFace Enterprise Server SDK can positively identify only friends, not foes. A friend is a person whose face has been captured a certain number of days by the same camera during a certain period of time. In all other cases, a person is just considered to be ‘not a friend’.
Enable ‘Friend or Foe’ Identification¶
To enable ‘friend or foe’ identification, do the following:
Configure and tryout dynamic person creation.
Open the
findface-facenapi.ini
configuration file for editing.sudo vi /etc/findface-facenapi.ini
Edit the settings.
Warning
The
findface-facenapi.ini
content must be correct Python code.A friend is a person that has been seen a certain number of days by the same camera during an interval
[now() - $interval ; now()]
. Uncomment and edit the number of days a person has to be seen to befriend your system.→ friend_count = 5
Interval in seconds during which a person has to be seen a certain number of days (1 week by default):
→ friend_interval = (3600*24*7)
Restart the service.
sudo service findface-facenapi restart
‘Friend or Foe’ Identification in REST API¶
The example below demonstrates a POST /face
request and the
corresponding response containing the ‘friend’ parameter ("friend": true
or "friend": false
).
Request
POST /v0/face/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"photo": "http://static.findface.pro/sample.jpg"
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results": {
"[595, 127, 812, 344]": [
{
"confidence": 1,
"face": {
"friend": true,
"galleries": [
"default"
],
"id": 2,
"meta": "Jack Smith",
"normalized": "http://192.168.113.76:3333/uploads/20170418/1492509569217098.jpeg",
"person_id": 2,
"photo": "http://192.168.113.76:3333/uploads/20170418/14925095692111893.jpeg",
"photo_hash": "53477c4a72f52c6efc951d9c7ece42bc",
"thumbnail": "http://192.168.113.76:3333/uploads/20170418/14925095692159095.jpeg",
"timestamp": "2017-04-18T09:59:29.211000",
"x1": 595,
"x2": 812,
"y1": 127,
"y2": 344
}
}
]
}
}
Extraction API¶
With the Extraction API
component, you can flexibly configure the format of API responses to extract various face data, including the
bounding box coordinates, normalized face, gender, age, and emotions, as well as the face feature vector (facen). Implementing this feature to
your system can remarkably broaden the scope of analytic tasks it is capable of fulfilling.
Note
Being a findface-facenapi
counterpart when it comes to data extraction via API, Extraction API
is more resource-demanding. The component cannot fully substitute findface-facenapi
as it doesn’t allow adding faces and working with the database.
Note
You can also use Extraction API
as a facen extractor, i. e. as an alternative to findface-nnapi
.
Tip
Encoded in base64 normalized images received from the Extraction API component are qualified for posting to findface-facenapi.
In this section:
Install Extraction API¶
To install and configure the Extraction API
component, do the following:
Note
Extraction API
requires the packages with models <findface-data>.deb. Make sure they have been installed.
Install the component.
sudo apt-get install findface-extraction-api
Open the
findface-extraction-api.ini
configuration file.sudo vi /etc/findface-extraction-api.ini
If NTLS is remote, specify its IP address.
license_ntls_server: 192.168.113.2:3133
Configure other parameters if needed. For example, enable or disable fetching Internet images.
fetch: enabled: true size_limit: 10485760
The
min_face_size
andmax_face_size
parameters do not work as filters. They rather indicate the guaranteed detection interval. Pick up their values carefully as these parameters affect performance.nnd: min_face_size: 30 max_face_size: .inf
The
model_instances
parameter indicates how many instances of each enabled face detector (nnd
,legacy
orprenormalized
) and each enabled model (facen
,gender
,age
,emotions
) run concurrently. The default value (0) means that this number is equal to the number of CPU cores. If it severely affects RAM consumption (for example, extraction-api fails), adjust the parameter value.model_instances: 2
To estimate the face quality, enable the
quality_estimator
. In this case,extraction-api
will return the quality score in the detection_score parameter.Tip
Interpret the quality score further in analytics. Upright faces in frontal position are considered the best quality. They result in values around
0
, mostly negative (such as-0.00067401276
, for example). Inverted faces and large face angles are estimated with negative values some-5
and less.quality_estimator: true
Enable the
Extraction API
service autostart and lauch the service.sudo systemctl enable findface-extraction-api && sudo systemctl start findface-extraction-api
API Requests¶
The Extraction API component accepts POST requests to http://127.0.0.1:18666/.
There are 2 ways to format the request body:
application/json
: the request body contains only JSON.multipart/form-data
: the request body contains a JSON part with the request itself, other body parts are used for image transfer.
The JSON part of the request body contains a set of requests:
{
"requests": [request1, request2, .., requestN]
}
Each request in the set applies to a specific image or region in the image and accepts the following parameters:
"image"
: an uploaded image (usemultipart:part
to refer to a relevant request bodypart
), or a publicly accessible image URL (http:
,https:
)."roi"
: a region of interest in the image. If the region is not specified, the entire image is processed."detector"
: a face detector to apply to the image (legacy
,nnd
orprenormalized
). Theprenormalized
mode accepts normalized face images and omits detecting faces. Usennd
if you need to estimate the face quality ("quality_estimator": true
)."need_facen"
: if true, the request returns a facen in the response."need_gender"
: returns gender."need_emotions"
: returns emotions."need_age"
: returns age."need_normalized"
: returns a normalized face image encoded in base64. The normalized image can then be posted again to theExtraction API
component as “prenormalized”."auto_rotate"
: if true, auto-rotates an original image to 4 different orientations and returns faces detected in each orientation. Works only if"detector": "nnd"
and"quality_estimator": true
.
{
"image": "http://static.findface.pro/sample.jpg",
"roi": {"left": 0, "right": 1000, "top": 0, "bottom": 1000},
"detector": "nnd",
"need_facen": true,
"need_gender": true,
"need_emotions": true,
"need_age": true,
"need_normalized": true,
"auto_rotate": true
}
API Response Format¶
A typical response from the Extraction API component contains a set of responses to the requests wrapped into the main API request:
{
"response": [response1, response2, .., responseN]
}
Each response in the set contains the following JSON data:
"faces"
: a set of faces detected in the provided image or region of interest."error"
: an error occurred during processing (if any). The error body includes the error code which can be interpreted automatically ("code"
) and a human-readable description ("desc"
).
{
"faces": [face1, face2, .., faceN],
"error": {
"code": "IMAGE_DECODING_FAILED",
"desc": "Failed to decode: reason"
}
}
Each face in the set is provided with the following data:
"bbox"
: coordinates of a bounding box with the face."detection_score"
: either the face detection accuracy, or the face quality score (depending on whetherquality_estimator
isfalse
ortrue
at/etc/findface-extraction-api.ini
). Upright faces in frontal position are considered the best quality. They result in values around0
, mostly negative (such as-0.00067401276
, for example). Inverted faces and large face angles are estimated with negative values some-5
and less."facen"
: the face feature vector."gender"
: gender information (MALE or FEMALE) with recognition accuracy if requested."age"
: age estimate if requested."emotions"
: all available emotions in descending order of probability if requested."normalized"
: a normalized face image encoded in base64 if requested.
{
"bbox": { "left": 1, "right": 2, "top": 3, "bottom": 4},
"detection_score": -0.0004299,
"facen": "...",
"gender": {
"gender": "MALE",
"score": "1.123"
},
"age": 23.59,
"emotions": [
{ "emotion": "neutral", "score": 0.95 },
{ "emotion": "angry", "score": 0.55 },
...
],
"normalized": "...",
}
Examples¶
Request #1
curl -X POST -F sample=@sample.jpg -F 'request={"requests":[{"image":"multipart:sample","detector":"nnd", "need_gender":true, "need_normalized": true, "need_facen": true}]}' http://127.0.0.1:18666/| jq
Response
{
"responses": [
{
"faces": [
{
"bbox": {
"left": 595,
"top": 127,
"right": 812,
"bottom": 344
},
"detection_score": -0.0012599,
"facen": "qErDPTE...vd4oMr0=",
"gender": {
"gender": "FEMALE",
"score": -2.6415858
},
"normalized": "iVBORw0KGgoAAAANSUhE...79CIbv"
}
]
}
]
}
Request #2
curl -X POST -F 'request={"requests": [{"need_age": true, "need_gender": true, "detector": "nnd", "roi": {"left": -2975, "top": -635, "right": 4060, "bottom": 1720}, "image": "https://static.findface.pro/sample.jpg", "need_emotions": true}]}' http://127.0.0.1:18666/ |jq
Response
{
"responses": [
{
"faces": [
{
"bbox": {
"left": 595,
"top": 127,
"right": 812,
"bottom": 344
},
"detection_score": 0.9999999,
"gender": {
"gender": "FEMALE",
"score": -2.6415858
},
"age": 26.048346,
"emotions": [
{
"emotion": "neutral",
"score": 0.90854686
},
{
"emotion": "sad",
"score": 0.051211596
},
{
"emotion": "happy",
"score": 0.045291856
},
{
"emotion": "surprise",
"score": -0.024765536
},
{
"emotion": "fear",
"score": -0.11788454
},
{
"emotion": "angry",
"score": -0.1723868
},
{
"emotion": "disgust",
"score": -0.35445923
}
]
}
]
}
]
}
Request #3. Auto-rotation
curl -s -F 'sample=@/path/to/your/photo.png' -F 'request={"requests":[{"image":"multipart:sample","detector":"nnd", "auto_rotate": true, "need_normalized": true }]}' http://192.168.113.79:18666/
Response
{
"responses": [
{
"faces": [
{
"bbox": {
"left": 96,
"top": 99,
"right": 196,
"bottom": 198
},
"detection_score": -0.00019264,
"normalized": "iVBORw0KGgoAAAANSUhE....quWKAAC"
},
{
"bbox": {
"left": 205,
"top": 91,
"right": 336,
"bottom": 223
},
"detection_score": -0.00041600747,
"normalized": "iVBORw0KGgoAAAANSUhEUgAA....AByquWKAACAAElEQVR4nKy96XYbybIdnF"
}
]
}
]
}
Extract Facens¶
By default, findface-facenapi
detects faces in images and sends them to findface-nnapi
for a facen extraction. Then findface-facenapi
saves the obtained facen to MongoDB and Tarantool databases. You can use Extraction API
as a better alternative to findface-nnapi
in this pipeline.
The main advantage of Extraction API
in contrast with findface-nnapi
is its built-in ability to clone into multiple instances and automatically balance the traffic across them, while for findface-nnapi
, load balancing has to be manually set up via NginX.
To extract facens via Extraction API
, do the following:
Open the
findface-facenapi.ini
configuration file:sudo vi /etc/findface-facenapi.ini
Uncomment and edit the
extractor
parameter in the following way:extractor = 'extraction-api'
Warning
The
findface-facenapi.ini
content must be correct Python code.Uncomment and/or edit
extraction_api_url
to align with your network specification:extraction_api_url = 'http://localhost:18666'
Start
Extraction API
and enable its autostart.sudo service findface-extraction-api start && sudo systemctl enable findface-extraction-api
Restart
findface-facenapi
.sudo service findface-facenapi restart
Stop
findface-nnapi
and disable its autostart.sudo service findface-nnapi stop && sudo systemctl disable findface-nnapi
Check the services status. The command will return the services description, status (should be Active), path and running time.
sudo service 'findface*' status
Bulk Face Enrollment¶
The Bulk Face Enrollment feature allows for enrolling faces to findface-facenapi from images in bulk.
In this section:
General Information¶
You can bulk-enroll faces in one of the following ways:
- from images in a current directory,
- from images in a given subdirectory,
- from images from all subdirectories.
To install the Bulk Face Enrollment component, execute:
sudo apt-get install findface-mass-enroll
To display the component help message, execute:
findface-mass-enroll --help
## $ findface-mass-enroll --help
Usage: findface-mass-enroll [OPTIONS] COMMAND [ARGS]...
Options:
--job PATH Job file (default: ffmassenroll.job)
--help Show this message and exit.
Commands:
prepare Prepare upload job
print Print contents of job file as JSON
run Run upload job
$ findface-mass-enroll prepare --help
Usage: findface-mass-enroll prepare [OPTIONS] [IMAGES]...
This subcommand is used to prepare one or more job files for subsequent
runs.
Examples:
Enrolling all *.jpg files in current directory with meta 'Phillip J. Fry':
$ ls
photo1.jpg photo2.jpg photo3.jpg
$ findface-mass-enroll prepare --meta-const='Phillip J. Fry' '*.jpg'
Enrolling all JPEGs and PNGs from a subdirectory with meta from accompanying TXT files:
$ ls subdir
photo1.jpg photo1.txt photo2.png photo2.txt photo3.jpeg photo3.txt
$ findface-mass-enroll prepare --meta-companion='txt' 'subdir/*.jpg' 'subdir/*.png' 'subdir/*.jpeg'
Enrolling JPEGs from all subdirectories with meta from CSV file:
$ cat meta.csv
"Phillip J. Fry","dir1/photo1.jpg"
"Phillip J. Fry","dir1/photo2.jpg"
"Phillip J. Fry","dir1/photo3.jpg"
"Turanga Leela","dir2/photo1.jpg"
"Turanga Leela","dir2/photo2.jpg"
"Turanga Leela","dir2/photo3.jpg"
$ ls -R
.:
meta.csv
./dir1:
photo1.jpg photo2.jpg photo3.jpg
./dir2:
photo1.jpg photo2.jpg photo3.jpg
$ findface-mass-enroll prepare --meta-csv=meta.csv '**/*.jpg' '**/*.jpeg'
Options:
--meta-const TEXT Shared metadata string
--meta-companion TEXT Extension of metadata files accompanying the images
(e.g. txt)
--meta-csv PATH Name of the CSV file containing metadata
--meta-filename Use file name (without extension) as metadata string
--split INTEGER Split job file into N parts (default: don't split)
--help Show this message and exit.
## $ findface-mass-enroll print --help
Usage: findface-mass-enroll print [OPTIONS]
Print contents of job file as JSON
Options:
--failed Show only failed images
--help Show this message and exit.
## $ findface-mass-enroll run --help
Usage: findface-mass-enroll run [OPTIONS]
Run upload job
Options:
--parallel INTEGER Number of enroll threads (default: 10)
--api TEXT API url (default: http://127.0.0.1:8000/)
[required]
--token TEXT API token [required]
--gallery TEXT Enroll faces into specified gallery
(default: default)
--failed Include failed images
--mf-selector [all|biggest|reject]
mf_selector (biggest,all,reject)
--gender Extract gender
--age Extract age
--emotions Extract emotions
--stats-interval INTEGER Output stats after every STATS_INTERVAL
seconds (default: 1)
--help Show this message and exit.
To harness the feature, do the following:
Prepare a job file containing the list of images with metadata (
prepare
). If all images share the same metastring, you can specify it right in the command line when preparing the job file (--meta-const
). If each image has a unique metastring, map metastrings to images in a CSV file (--meta-csv
).Note
The CSV file used as a metadata source should have the following format:
metastring | image
. If some images are not listed in the CSV file, their metastrings will be empty.Tip
To write the list of images to a CSV file, you can use the command below. Each image in the list will be associated with a metastring coinciding with the image full path (in the format
metastring | image
).find /home/user/sample | grep -E 'jpg|png' |awk '{print $0","$0}' > list.csv
If necessary, display the job file content (
print
).Enroll faces to findface-facenapi for further processing (
run
).Note
Should an error occur during the job file processing, correct the mistake and try again with the option –failed (see examples below).
Example¶
Enroll faces from all .jpg
files in a /home/user/images/
directory with a shared metastring Phillip J. Fry
:
To display the list of images in a directory, execute:
ls /home/user/images/
photo1.jpg photo2.jpg photo3.jpg ...
Prepare a job file:
findface-mass-enroll prepare --meta-const='Phillip J. Fry' '/home/user/images/*'
Looking for images matching '*.jpg'
2055 files prepared for upload
2055 files in job file samplejob
Run the job file:
findface-mass-enroll run --token 'RczGgVEMizR1njHHQegNH_g9mwGl6-A1' --api http://127.0.0.1:8000/ --gender --age --emotions --mf-selector=all
[33/2055] faces processed (4 succeeded, 9 failed, 10 skipped). 2.14 rps. [00:00:17/00:16:04]
---------------------------------------- Summary -------------------------------------------
Found 2055 images in job file
Skipped 0 already processed images
Successfully processed 2000 images
Failed to process 55 images
Should an error occur during the job file processing, correct the mistake and try again with the option --failed
:
findface-mass-enroll run --token 'RczGgVEMizR1njHHQegNH_g9mwGl6-A1' --api http://127.0.0.1:8000/ --gender --age --emotions --mf-selector=all --failed
Shard Galleries Statistics¶
You can get a shard galleries statistics and other data right in your browser. This functionality can be harnessed in monitoring systems.
Note
In the case of standalone deployment, you can access Tarantool by default only locally (127.0.0.1). If you want to access Tarantool remotely, change the Tarantool configuration file.
In this section:
List Galleries¶
To list all galleries on a shard, type in the address bar of your browser:
http://<tarantool_host_ip:shard_port>/stat/list/:start/:limit
:start
is the number of a gallery the list starts with.
:limit
is the maximum number of galleries in the list.
Example
Request
http://127.0.0.1:8001/stat/list/1/99
or
curl http://127.0.0.1:8001/stat/list/1/99 \| jq
Response
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 6700 100 6700 0 0 45812 0 --:--:-- --:--:-- --:--:-- 45890
{
"galleries": [
{
"cnt_indexed": 0,
"id": 1,
"cnt_preindex": 0,
"name": "591b0cdfb0d5bd7058ef0968_default",
"cnt_linear": 35268
},
{
"cnt_indexed": 0,
"id": 2,
"cnt_preindex": 0,
"name": "591b0cdfb0d5bd7058ef0968_lublino",
"cnt_linear": 1818
},
{
"cnt_indexed": 0,
"id": 3,
"cnt_preindex": 0,
"name": "591b0cdfb0d5bd7058ef0968_gifs",
"cnt_linear": 297
}
],
"total": 3
}
Get Gallery Information¶
To get a gallery information, type in the address bar of your browser:
http://<tarantool_host_ip:shard_port>/stat/info/:name
:name
is the gallery name.
Example
Request
curl http://127.0.0.1:8001/stat/info/5968bda4a2a4bb6018bee2b2_cam_cam1 | jq
Response
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 210 100 210 0 0 17654 0 --:--:-- --:--:-- --:--:-- 19090
{
"cnt_indexed": 0,
"cnt_preindex_deleted": 0,
"index_file": "none",
"index_loaded": false,
"cnt_preindex": 0,
"cnt_linear": 85011,
"cptr": 29556448,
"id": 34,
"name": "5968bda4a2a4bb6018bee2b2_cam_cam1",
"cnt_indexed_deleted": 0
}
Direct API Requests to Tarantool¶
You can use HTTP API to extract data directly from the Tarantool Database.
In this section:
General Information¶
API requests to Tarantool should be sent to http://<tarantool_host_ip:port>
.
Tip
The port for API requests can be found in the FindFace.start
section of the Tarantool configuration file:
cat /etc/tarantool/instances.enabled/FindFace.lua
##8001:
FindFace.start("127.0.0.1", 8001)
Note
In the case of standalone deployment, you can access Tarantool by default only locally (127.0.0.1). If you want to access Tarantool remotely, change the Tarantool configuration file.
Each API request to Tarantool contains the following parameters:
:ver
: the API version (v1 at the moment).:name
: the gallery name.:id
: the face id.
Add Face¶
Request
POST /:ver/:name/add/:id
Body
: a raw feature vector (facen)
Returns:
- HTTP 200 and empty body if success.
- HTTP 409 if a face with the same id already exists in the gallery.
- HTTP with a status other than 200 and error description in the body if failure.
Example
curl -s -D - 'http://localhost:8001/v1/my_gal/add/1234' --data-binary @3827305024709134.facen
HTTP/1.1 200 Ok
Content-length: 0
Server: Tarantool http (tarantool v1.7.3-673-g23cc4dc)
Connection: keep-alive
Get Facen¶
Request
GET /:ver/:name/get/:id
Returns:
- A JSON representation of the face with its id and base64 encoded facen if success.
- HTTP 404 if a face with the given id is not found in the gallery.
- HTTP with a status other than 200 and error description in the body if failure.
Tip
To convert a facen from base64 to a binary file, execute:
echo 'facen in base64' |base64 -d> facen
Example
curl -s -D - 'http://localhost:8001/v1/my_gal/get/1234' HTTP/1.1 200 Ok Content-length: 1754 Server: Tarantool http (tarantool v1.7.3-673-g23cc4dc) Connection: keep-alive {"facen":"BFa9PWNlS7215fI98ETQvJkxML2hUFY9cF\/Tu9ZjnLx\/uVc9EzWSPQTsR7zoysI8+4PSPIsjnr2GV1M8eFMKvfn9mjsPPjA8ZXoNvTEsSr0rJkM9MR0IPINXSj3Em0s9awm5Oos5SD380a693GroPBz6nzxQMDQ9HdOjPd7QhDxUIzC+g90sPUWUDLwjk7U9cpWkPZ83 rTyEDNm8Ti\/0ve4Trr1rnQA+Yc\/KvJzqnbzOPSG998CKPBFpAr77kFO9BonDvK9B0buvjAq9Q7A\/u6awnTw0lvy80QZcvRFQAz0BdH498hF6vQKRcDy77c08mGRkvQ305DomnBM9XSqwvN54GT0ClFO9a+kWvhp7iT3uqqU9v1+\/vYhzm7uREt091douuyDKRr2PcIG9Uc8xPVJnvzt5T309NicxPD9SAr3f6sO8UmlhvRMI67wlTte880wYvUF8o7xg4\/g8aqNQu\/AAWD2z59C9CQCrPepF7Dy8qUa9iCczPfKv+Dy+bRo9KhyYPZfY0b1xtbY7nKXLuvYFbr0g8rM86o0QPRCKOj1a7rU9bd+3Pbqs7LslJcO9bBh+vVYeUr3S95Y9Wtg5PUZnRr0D0G08lkRkveImPDx4iQ084Qy1vKRBjj3uf4W85qx+vREFX7uccQ++5mMMvetNAL25b409P0GQvDIGLz3mHqg9ca\/Guv2beTy56wg7p\/hTPdxQgr0jxQQ9Ud0CPZcx\/LtRLiU9bECQvUnvszpMVcM8b3OovURPET3JdHs9LyQUPsc9JzvW1ZQ7y2ySPdN4Xb0xi9c8X7UevRqjVL0MLpE9PoQpvFxxjD2NCDO81jH\/PF1KFTzc3pc7qpaFPXxuPb2tjsY9iA5lPR1NoT1+Uuu7G6gpu727wTwo6ii8iaH+PI1WY72D9QG+8lhAPUegx71VsFs8ajQLvOdekrzGqAg+zhPLvbjyNDxaI1E9Wkj\/O1307D1ZMSk9IxqGvYCvFb1bE429hZF4vewikzwDbfG8wwYNPiQn4L2NV6Q9VKrvPTjwTr3dlG05jck+vZ\/KID1+n8Y8qpvnvOJjBj2P4+w8IJGgvROAfz1S4ve8QEouvQ5CkDu0OTI8\/v\/pvFrK5b3bkIO82LVBPcf2Yr0aGaU9RArUvEecJz1r8zk87U4vvC65ljz6kRS956U2PH6JMT5nfAg7KX7qPBz7Ejy60vk9\/iEPPYw8pT3Mfvk8UQYyPUCG+TyD5CO90c6nvSVLvDwRJSW9C3udvDORMz3zqtU8yd+0PXrubj3u9pQ9cGZIPVjlqTz6eIs8Z4wsPIjEIT3gnqI9kjhTPRJ8b73crA492KKIvSvpEz3ROrs9M+ZrO3RDOrwPpgG9+buePbiwi726dSs9k\/iVvZjEhT3W0B69IRojvQGUVj2J6vQ9FiDhPNRUO70bcum9fOOvPKA\/y7yB9wq9ntsBPYL6XL0wgkw7nLu6O\/\/USz1EoUg9JKE9PLDzNL0Pns49fPVyPJfZaj2g6pi8MuZePV0xQLxkR4W9pEe7vYTv7jytv567nakpPcCHZbsfjx89jPENPW0x87vr3Wi84L9mvSGeFL2hsBo9HBI2vXiEJr2uIQW7L0FsPU2w8jz2chi9FB5nvFcj9rknTha9qxCoPb0Qu72sIik9Hn4FvE\/8JL02Vh0879v\/O6weQjxpD7k85Kj2PGb0ej0V6xS8\/4EvPXmv3z0=","id":1234}
Remove Face¶
Warning
Removing a face from Tarantool will not remove it from MongoDB.
Request
DELETE /:ver/:name/del/:id
Returns:
- HTTP 200 and empty body if success.
- HTTP 404 if a face with the given id is not found in the gallery.
- HTTP with a status other than 200 and error description in the body if failure.
Example
curl -s -D - -X DELETE 'http://localhost:8001/v1/my_gal/del/1234'
HTTP/1.1 200 Ok
Content-length: 0
Server: Tarantool http (tarantool v1.7.3-673-g23cc4dc)
Connection: keep-alive
Face Search¶
Request
POST /:ver/:name/search/:limit/:threshold?linear_search
:limit
: the maximum number of faces in the response
:threshold
: the minimum similarity for faces in the response (from 0 to 1).
linear_search
(boolean, optional): set linear_search=1 (true) to use only the linear space to search for faces. This setting has priority over the only_index setting (/etc/tarantool/instances.enabled/FindFace.lua).
body
: a raw facen.
Returns:
- A JSON array with faces with the
conf
andid
fields in the body if success. The value in theX-search-stat
header indicates whether the fast index was used for the search:with_index
orwithout_index
. - HTTP with a status other than 200 and error description in the body if failure.
Example
curl -s -D - 'http://localhost:8001/v1/my_gal/search/1/0.65?linear_search=1' --data-binary @3827305024709134.facen
HTTP/1.1 200 Ok
Content-length: 22
X-search-stat: without_index
Server: Tarantool http (tarantool v1.7.3-673-g23cc4dc)
Connection: keep-alive
[{"conf":1,"id":1234}]
List Faces¶
Request
GET /:ver/:name/list/:start_id/:count
:start_id
: the minimum face_id
in the response
:count
: the maximum number of faces in the response
Returns:
- A JSON array with faces, and the next page URL if success. Each face is provided with its id, base64 encoded facen and the name of a Tarantool space where the face is located (linear, preindex, or indexed). The next page URL should be passed as
:start_id
in another API request to get the next page of results. - HTTP with a status other than 200 and error description in the body if failure.
Example
curl -s -D - 'http://localhost:8001/v1/my_gal/list/0/1' HTTP/1.1 200 Ok Content-length: 1795 Server: Tarantool http (tarantool v1.7.3-673-g23cc4dc) Connection: keep-alive {"faces":[{"id":1234,"space":"linear","facen":"BFa9PWNlS7215fI98ETQvJkxML2hUFY9cF\/Tu9ZjnLx\/uVc9EzWSPQTsR7zoysI8+4PSPIsjnr2GV1M8eFMKvfn9mjsPPjA8ZXoNvTEsSr0rJkM9MR0IPINXSj3Em0s9awm5Oos5SD380a693GroPBz6nzxQMDQ9HdO jPd7QhDxUIzC+g90sPUWUDLwjk7U9cpWkPZ83rTyEDNm8Ti\/0ve4Trr1rnQA+Yc\/KvJzqnbzOPSG998CKPBFpAr77kFO9BonDvK9B0buvjAq9Q7A\/u6awnTw0lvy80QZcvRFQAz0BdH498hF6vQKRcDy77c08mGRkvQ305DomnBM9XSqwvN54GT0ClFO9a+kWvhp7iT3uqqU9v1+\/vYhzm7uREt091douuyDKRr2PcIG9Uc8xPVJnvzt5T309NicxPD9SAr3f6sO8UmlhvRMI67wlTte880wYvUF8o7xg4\/g8aqNQu\/AAWD2z59C9CQCrPepF7Dy8qUa9iCczPfKv+Dy+bRo9KhyYPZfY0b1xtbY7nKXLuvYFbr0g8rM86o0QPRCKOj1a7rU9bd+3Pbqs7LslJcO9bBh+vVYeUr3S95Y9Wtg5PUZnRr0D0G08lkRkveImPDx4iQ084Qy1vKRBjj3uf4W85qx+vREFX7uccQ++5mMMvetNAL25b409P0GQvDIGLz3mHqg9ca\/Guv2beTy56wg7p\/hTPdxQgr0jxQQ9Ud0CPZcx\/LtRLiU9bECQvUnvszpMVcM8b3OovURPET3JdHs9LyQUPsc9JzvW1ZQ7y2ySPdN4Xb0xi9c8X7UevRqjVL0MLpE9PoQpvFxxjD2NCDO81jH\/PF1KFTzc3pc7qpaFPXxuPb2tjsY9iA5lPR1NoT1+Uuu7G6gpu727wTwo6ii8iaH+PI1WY72D9QG+8lhAPUegx71VsFs8ajQLvOdekrzGqAg+zhPLvbjyNDxaI1E9Wkj\/O1307D1ZMSk9IxqGvYCvFb1bE429hZF4vewikzwDbfG8wwYNPiQn4L2NV6Q9VKrvPTjwTr3dlG05jck+vZ\/KID1+n8Y8qpvnvOJjBj2P4+w8IJGgvROAfz1S4ve8QEouvQ5CkDu0OTI8\/v\/pvFrK5b3bkIO82LVBPcf2Yr0aGaU9RArUvEecJz1r8zk87U4vvC65ljz6kRS956U2PH6JMT5nfAg7KX7qPBz7Ejy60vk9\/iEPPYw8pT3Mfvk8UQYyPUCG+TyD5CO90c6nvSVLvDwRJSW9C3udvDORMz3zqtU8yd+0PXrubj3u9pQ9cGZIPVjlqTz6eIs8Z4wsPIjEIT3gnqI9kjhTPRJ8b73crA492KKIvSvpEz3ROrs9M+ZrO3RDOrwPpgG9+buePbiwi726dSs9k\/iVvZjEhT3W0B69IRojvQGUVj2J6vQ9FiDhPNRUO70bcum9fOOvPKA\/y7yB9wq9ntsBPYL6XL0wgkw7nLu6O\/\/USz1EoUg9JKE9PLDzNL0Pns49fPVyPJfZaj2g6pi8MuZePV0xQLxkR4W9pEe7vYTv7jytv567nakpPcCHZbsfjx89jPENPW0x87vr3Wi84L9mvSGeFL2hsBo9HBI2vXiEJr2uIQW7L0FsPU2w8jz2chi9FB5nvFcj9rknTha9qxCoPb0Qu72sIik9Hn4FvE\/8JL02Vh0879v\/O6weQjxpD7k85Kj2PGb0ej0V6xS8\/4EvPXmv3z0="}],"next":5678}
Hacks for tntapi
¶
In this section:
Additional Configuration Parameters¶
To configure interaction between findface-facenapi and Tarantool, specify additional parameters in the 3rd argument of the FindFace.start
section in the tntapi configuration file:
sudo vi /etc/tarantool/instances.enabled/FindFace.lua
FindFace.start("127.0.0.1", 8001, {license_ntls_server="127.0.0.1:3133", additional parameter 1, ..., additional parameter N})
## Example:
FindFace.start("127.0.0.1", 8001, {license_ntls_server="127.0.0.1:3133", facen_size = 320, log_requests = false})
Additional parameters:
Parameter | Default value | Description |
---|---|---|
log_requests | true | Enable request logging (/var/log/tarantool/FindFace.log). |
facen_size | 320 | Facen’s size. Before editing this parameter, be sure to consult NTechLab experts. |
search_threads | 1 | Number of threads for fast index search. |
replication | nil | Only for a replica. Master instance IP address. |
soft_delete_mode | false | Enable the soft deletion mode, when the faces are not removed from the fast index, but hidden in search results. |
Soft Deletion Mode¶
Tarantool supports the soft deletion mode, when the faces are not removed from the fast index, but hidden in search results. We recommend you to enable this mode due to the following benefits:
- Tarantool starting time linearly depends on the number of faces removed from the
Indexed
space (fast index). If the soft deletion mode is on, the faces are not physically removed from the fast index, so face deletion doesn’t affect the starting time. - Fast index search quality also depends on the number of physically removed faces. It doesn’t sink in the soft deletion mode.
To enable the soft deletion mode, edit the FindFace.start section as follows:
FindFace.start("127.0.0.1", 8001, {license_ntls_server="127.0.0.1:3133", soft_delete_mode = true})
Tarantool Replication¶
Replication allows multiple Tarantool instances to work on copies of the same face database. The database copies are kept in sync because each instance can communicate its changes to all the other instances. Tarantool supports master-slave replication. You can add and delete data only by using the master instance, slave instances (aka replicas) are read-only, i.e. can be used only for searching and consulting data.
To learn how to deploy a Tarantool replica set, refer to the Tarantool official documentation.
To start a created replica for the first time, do the following:
Start the master instance.
In the replica configuration file, specify the IP address and listening port of the master instance.
FindFace.start("127.0.0.1", 48001, {replication = "127.0.0.1:33001"})
Copy the latest snapshot (.snap) of the master instance into the
memtx_dir
directory of the replica.--Directory to store data memtx_dir = '/opt/ntech/var/lib/tarantool/default/snapshots'
Copy the master instance logs into the
wal_dir
directory of the replica.--Directory to store data wal_dir = '/opt/ntech/var/lib/tarantool/default/xlogs'
Start the replica. You can start as many replicas affiliated with the same master instance as needed.
Important
Before enabling the fast index for the master instance :use_index("/path/to/<index>.idx")
, copy the index file (<index>.idx
) to the same path on its replica. Then perform use_index
on the master instance.
Tip
Delete obsolete index files on the replica in order to avoid unnecessary index transitions, should the master instance and replica be heavily out of sync.
Tip
To synchronize the master instance and replica, you can also copy the latest master snapshot to the replica.
REST API¶
How to Use REST API¶
In this section:
API Version¶
The API version is increased every time a major change is made and allows us to avoid breaking backwards compatibility. The API version should be specified in the request path (for example, v1 in /v1/detect/
).
The most recent version is v1 which provides such advanced functions as gender, age and emotions recognition.
Note
When starting a new project, you should always use the latest stable version of the API.
Authentication¶
All API methods require a simple token-based HTTP Authentication. In order to authenticate, you should put the word “Token” and your token key into the Authorization HTTP header, separated by a whitespace:
Note
To learn how to create a token, consult Create Authentication Token.
Authorization: Token yfT8ftheVqnDLS3Q0yCiTH3E8YY_cm4p
All requests that fail to provide a valid authentication token will result in a HTTP 401 Unauthorized
response.
Common Object Types¶
Face¶
Represents a human face. Note that it might be several faces on a single photo. Different photos of the same person as also considered to be different faces.
"id" (number)
: unique identifier of the face generated by API."timestamp" (string)
: time of face object creation as ISO8601 string."photo" (string)
: URL of file name of a photo that had been used to create the face object."photo_hash" (string)
: Hash of the original photo. Note that identical photos will always have the same hash, and different photos will most certainly have different hashes. Don’t interpret this value and don’t make assumptions about particular hash function used for hash calculation."thumbnail" (string)
: URL of face thumbnail stored on FindFace servers."x1" (number)
: x coordinate of the top-left corner of face’s bounding box on the original photo."y1" (number)
: y coordinate of the top-left corner of face’s bounding box on the original photo."x2" (number)
: x coordinate of the bottom-right corner of face’s bounding box on the original photo."y2" (number)
: y coordinate of the bottom-right corner of face’s bounding box on the original photo."meta" (string)
: metadata string that you can use to store any information associated with the face."galleries" (string[])
: array of galleries names that have this face.
Bounding Box (bbox)¶
Represents a rectangle on a photo. Usually used as a face’s bounding box. May be specified in two ways:
- Separated coordinates:
"x1" (number)
: x coordinate of the top-left corner of the bounding box."y1" (number)
: y coordinate of the top-left corner of the bounding box."x2" (number)
: x coordinate of the bottom-right corner of the bounding box."y2" (number)
: y coordinate of the bottom-right corner of the bounding box.
- Array of coordinates
[x1, y1, x2, y2]
The API methods accept both formats, but always return bbox as a JSON dictionary.
Note that in some case the coordinates might be outside photo dimensions, including negative values.
Parameters Format¶
There are three ways to pass parameters to the API methods:
application/json
: parameters are represented by a JSON contained in the body.application/x-www-form-urlencoded
: parameters are represented by form field names and values.multipart/form-data
: parameters are encoded into separate parts. This way supports uploading a photo image file in the same request.query string
: parameters are appended to request URI. When passing parameters in a query string, complex structures (such as bboxes) should be encoded in JSON.
There are two ways of specifying a photo image file:
- As a publicly accessible URL.
- Included in a request as part of multipart form.
All responses are in JSON format and UTF-8 encoding.
How to Use Examples¶
Examples in methods descriptions illustrate possible method requests and responses. To check the examples without writing code, use the
embedded API framework. To access the framework, enter in the address bar of your browser: http://<facenapi_ip>:8000/v1/docs/v1/overview.html
for the API version /v1.
Confidence Thresholds¶
For some methods you need to specify a threshold for verification or identification confidence. The higher is the threshold, the less are chances that a wrong person will be positively verified or identified, however, some valid photos may also fail verification.
There are 4 pre-defined threshold levels:
Strict (0.7834)
: used for applications where a chance of misidentification should be minimized. This level corresponds to False Accept Rate (FAR) of 1e-5 on our test dataset.Medium (0.6616)
: balances low probability of misidentification and inability to identify a valid person. Corresponds to 1e-3 FAR on our test dataset.Low (0.5690)
: used when it’s important to maximize the verification or identification rate, and misidentification does not cause severe consequences. Corresponds to 1e-1 FAR on our test dataset.None (0)
: use when you need to calculate similarity of different persons or find similar people rather than verify identity.
You can also specify your own threshold level from 0 to 1, depending on your environment and needs.
Note
If no threshold level is specified, it is set to the default value 0.75
.
Pagination¶
Some methods (such as GET /faces/
and GET /meta/
) may
potentially return thouthands and hundreds of thouthands results. To
avoid problems associated with such large amounts, we have introduced
pagination.
Methods that support pagination return two more parameters in addition to a list of results:
prev_page
: URL to the previous page (path and query only)next_page
: URL to the next page (path and query portion only)
For example, if GET http://<facenapi_ip>:8000/v0/faces/
has returned
the next_page
value ‘/v0/faces/?max_id=12345'
, you should
request GET http://<facenapi_ip:8000/v0/faces/?max_id=12345
to get
the next portion of the results.
Limits¶
FindFace Enterprise Server SDK imposes the following limits.
Limit | Value |
---|---|
Image formats | JPEG, PNG, WEBP |
Maximum photo file size | 10 MB |
Minimal size of a face | 50x50 pixels |
Maximum number of detected faces on a single photo | Unlimited |
Additionally, the URL provided to the API to fetch an image should be public (without authentication) and direct (without any redirects).
Error Reporting¶
If a method fails, it always returns a response with a HTTP code other than 200 and a JSON body containing the error description. The error body always includes at least two fields: code and status:
code
is a short string in CAPS_AND_UNDERSCORES, usable for automatic decoding.reason
is a human-readable description of the error and should not be interpreted automatically.
Common Error Codes
Error code | Description |
---|---|
AUTH_FAILED |
A wrong authentication token or no token has been provided. |
BAD_PARAM |
Some parameters are invalid. This response type has additional attributes ‘param’ and ‘value’ describing which parameter caused the error. |
MALFORMED_JSON |
The request body doesn’t contain a valid JSON. |
SERVICE_UNAVAILABLE |
Your request cannot be processed because some components are experiencing an outage. |
General Methods¶
In this section:
- Method /detect POST
- Method /verify POST
- Method /identify POST
- Method /face POST
- Method /face/id/<id> GET
- Method /face/id/<id> PUT
- Method /face/id/<id> DELETE
- Method /face/meta/<meta> GET
- Method /faces GET
- Method /faces/gallery/<gallery> GET
- Method /meta GET
- Method /galleries GET
- Method /galleries/<gallery> POST
- Method /galleries/<gallery> DELETE
- Method /docs GET
- Method /docs/<version> GET
- Method /person/id/<id> GET
- Method /history/search POST
Method /detect POST¶
This method detects faces on the provided image. You can either upload the image file as multipart/form-data or provide an URL, which the API will use to fetch the image.
Parameters:
photo
: an uploaded image, or a publicly accessible URL, containing the image
Returns:
- A list of rectangles, containing the detected faces
Example
Request
POST /v0/detect/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"photo": "http://static.findface.pro/sample.jpg"
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 06:04:02 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: [length]
{
"faces":
[
{
"x1": 236,
"x2": 311,
"y1": 345,
"y2": 419
}
]
}
Method /verify POST¶
This method is used to verify that two faces belong to the same person, or, alternatively, measures the similarity between the two faces. You
can choose between these two modes by setting the threshold
parameter.
In the case, when a binary decision is required, the user should pass a value for the threshold
parameter. You can use one of the 3 preset values: strict
, medium
and low
with the former aimed at minimizing the false accept rates and the latter being somewhat more permissive. You can also set a user-defined value.
In the case, when you need to calculate similarity of different persons or find similar people rather than verify identity, pass none
to the threshold
parameter.
Note
If no threshold level is specified, it is set to the default value 0.75
.
Tip
Please feel free to contact us if you need to tune the threshold value for your specific use-case and/or dataset.
Parameters:
photo1
: the first uploaded image or an external URLphoto2
: the second uploaded image or an external URLbbox1
[optional]: array of bounding boxes for the faces on the first photobbox2
[optional]: array of bounding boxes for the faces on the second photothreshold
[optional]: one of “strict”, “medium”, “low” or “none”, or a value between 0 and 1. Default is 0.75.mf_selector
[optional]: specifies behavior in a case of multiple faces on a photo; one of:"reject"
: return an error if more than one face was detected on any of image"biggest"
[default]: add the biggest face on the image"all"
: verify all faces, found on both images.
Note
Note that providing
bbox1
orbbox2
argument overrides the value of this parameter.
Returns:
- binary verification result, only returned if threshold was not set to none. Each pair of faces is given it’s own result. The given pair of photos is also provided with the verification result. It will be true if each face on the first photo has a match on the second.
- the coordinates of the bounding boxes with the faces on the images
- the algorithm’s confidence in the decision, measured from 0 to 1
Example
Request
POST /v0/verify/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"photo1": "http://static.findface.pro/sample.jpg",
"photo2": "http://static.findface.pro/sample2.jpg"
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results": [
{
"bbox1": {
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
},
"bbox2": {
"x1": 78,
"x2": 185,
"y1": 114,
"y2": 222
},
"confidence": 0.4206026792526245,
"verified": true
}
],
"verified": true
}
Method /identify POST¶
This method is used to search through the face database. The method returns at most n faces (one by default), which are the most similar to the specified face, and the similarity is above the specified threshold. You can optionally specify a gallery id to check a photo only against photos in this gallery.
Parameters:
photo
: the uploaded image, or an external URLx1, y1, x2, y2
[optional]: coordinates of a bounding box of the face on the photothreshold
[optional]: one of “strict”, “medium”, “low” or “none”, or a value between 0 and 1. Default is 0.75.n
[optional]: maximum number of closest faces to return, 1 by defaultstrict
[optional]: specifies behavior in case if one or several tntapi shards are out of service. This parameter takes priority over thetntapi_ignore_search_errors
parameter from the findface-facenapi configuration file.True
: return an error if some tntapi shards are out of serviceFalse
[default]: use available tntapi shards to obtain face identification results, indicating the number of available servers vs the total number of servers in theX-Live-Servers
header.
mf_selector
[optional]: specifies behavior in case if multiple faces are detected on the photo or inside the provided bounding box:"reject"
: return an error if more than one face was detected on any of image"biggest"
[default]: identify the biggest face on the image"all"
: identify all faces, found on the image.
Returns:
- A map where keys are array representations of bounding boxes of faces on provided photo and values are arrays face objects, along with match confidence, measured from 0 (lowest) to 1 (highest)
Example
Request
POST /v0/identify/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"n": 10,
"photo": "http://static.findface.pro/sample.jpg"
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results": {
"[419, 236, 345, 311]": [
{
"confidence": 1,
"face": {
"galleries": ["default", "ppl"]
"id": 316275,
"meta": "Sam Berry",
"photo": "http://static.findface.pro/sample.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-07-01T12:18:27.477653",
"x1": 236,
"x2": 311,
"y1": 345,
"y2": 419
}
},
{
"confidence": 0.723975,
"face": {
"galleries": ["default", "ppl"]
"id": 316283,
"meta": "Sam Berry",
"photo": "http://test.flexify.io/img/sample2.jpg",
"photo_hash": "9b1dd93259fe87df122cd678ce95b9f9",
"timestamp": "2016-07-01T13:19:36.376548",
"x1": 78,
"x2": 185,
"y1": 114,
"y2": 222
}
}
]
}
}
Method /face POST¶
Processes the uploaded image or provided URL, detects faces and adds the detected faces to the searchable database. If there are multiple faces on the photos, only the biggest face is added by default. You can add a custom string meta, such as name or ID, which uniquely identifies a person. Multiple face objects may have the same meta. We recommend that you don’t assign the same meta to different persons. Thus when using person’s name as a meta, make sure that all names are unique. You can optionally prefix it with a gallery id to upload into non-default gallery.
Parameters:
photo
: an uploaded image, or a publicly accessible URL, containing the imagemeta
[optional]: some user-defined string identifierbbox
[optional]: array of bounding boxes specifying face locations on the imagemf_selector
[optional]: specifies behavior in case if there are multiple faces found on the image or inside the specified rectangle; one of:"reject"
: return an error if more than one face was detected"biggest"
[default]: add the biggest face on the image"all"
: add all faces, found on the image. Please note that the meta will be the same for all faces added
galleries
[optional]: list of gallery names``cam_id`` [optional]: UUID of the camera
Returns:
- A JSON representation of the added faces or a failure reason
- In the case multiple faces are detected and
mf_selector
is set to reject, this method returns400 Bad Request
and a list of bounding box coordinates for each detected face.
Example #1
Request
POST /v0/face/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"meta": "Sam Berry",
"photo": "http://static.findface.pro/sample.jpg",
"galleries": ["gal1", "niceppl"]
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 06:04:02 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: [length]
{
"results": [
{
"galleries": ["default", "gal1", "niceppl"]
"id": 2334,
"meta": "Sam Berry",
"photo": "http://static.findface.pro/sample.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:11:29.425339",
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
}
]
}
Example #2
Request
POST /v0/face/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"mf_selector": "reject",
"photo": "http://static.findface.pro/sample-multiface.jpg"
}
Response
HTTP/1.1 400 Bad Request
Date: Mon, 13 Jun 2016 06:04:02 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: [length]
{
"code": 400,
"faces": [
{
"x1": 1952,
"x2": 2137,
"y1": 838,
"y2": 1023
},
{
"x1": 1766,
"x2": 1952,
"y1": 1312,
"y2": 1498
},
{
"x1": 1385,
"x2": 1540,
"y1": 939,
"y2": 1094
},
{
"x1": 2452,
"x2": 2607,
"y1": 664,
"y2": 818
},
{
"x1": 1609,
"x2": 1764,
"y1": 767,
"y2": 922
}
],
"reason": "Too many faces: 5"
}
Method /face/id/<id> GET¶
Returns detailed information about the face with id = FaceID.
Parameters:
- This method doesn’t accept any additional parameters.
Returns:
- A JSON representation of the face with
id = FaceID
.
Example
Request
GET /v0/face/id/2333/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"galleries": ["default", "ppl"]
"id": 2333,
"meta": "Sam Berry",
"photo": "http://static.findface.pro/sample.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:06:42.075754",
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
}
Method /face/id/<id> PUT¶
This method can be used to modify certain fields of the face object with id = FaceID
. Currently only changes to the meta attribute are supported.
Parameters:
meta
: new meta stringperson_id
: unique identifier of the persongalleries
: JSON dictionary with one key and one value. Either{"add":["list","of","galleries"]}
,{"del":["list","of","galleries"]}
,{"set":["list","of","galleries"]}
. Allows you to add face to galleries, remove from galleries or replace gallery list completely.
Returns:
- A JSON representation of the updated face with id = FaceID
Example
Request
PUT /v0/face/id/5/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"meta": "Sam Berry #2"
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"id": 2333,
"meta": "Sam Berry #2",
"photo": "http://static.findface.pro/sample2.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:06:42.075754",
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
}
Method /face/id/<id> DELETE¶
Deletes a face with the id = FaceId.
Parameters:
- This method does not accept any additional parameters.
Returns:
- HTTP 204 No Content in the case of success, or the reason of failure
Example
Request
DELETE /v0/face/id/2332/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token ca7916cdac260628c411cb5d895dd566
Content-Length: 0
Response
HTTP/1.1 204 No Content
Method /face/meta/<meta> GET¶
Returns the list of faces with a given meta string. Note that the method is case-sensitive, so the given meta has to fully match the one from the database. A meta string has to be URL encoded, and according to the standard, spaces should be encoded as %20 (not +) in this part of the URL.
Parameters:
- This method doesn’t accept any additional parameters.
Returns:
- Returns the list of faces with a <meta>.
Example
Request
GET /v0/face/meta/Sam%20Berry/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results": [
{
"galleries": ["default", "ppl"],
"id": 2333,
"meta": "Sam Berry",
"photo": "http://static.findface.pro/sample.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:06:42.075754",
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
},
{
"galleries": ["default", "ppl"],
"id": 2378,
"meta": "Sam Berry",
"photo": "http://static.findface.pro/sample2.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:06:42.075754",
"x1": 46,
"x2": 502,
"y1": 472,
"y2": 789
}
]
}
Method /faces GET¶
Parameters
- This method doesn’t accept any additional parameters.
Returns:
- Returns the list of all faces stored in database.
Example
Request
GET /v0/faces/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results": [
{
"galleries": ["default", "ppl"]
"id": 2333,
"meta": "Sam Berry",
"photo": "http://static.findface.pro/sample.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:06:42.075754",
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
},
{
"galleries": ["default", "ppl"]
"id": 2335,
"meta": "",
"photo": "http://static.findface.pro/sample2.jpg",
"photo_hash": "9879efb38d2dae550460c9edb6f36982",
"timestamp": "2016-06-13T11:34:57.275394",
"x1": 8,
"x2": 152,
"y1": 406,
"y2": 550
}
]
}
Method /faces/gallery/<gallery> GET¶
Returns the list of all faces stored in a specified gallery.
Method /meta GET¶
This method retrieves all the meta string stored in the database along with one of the associated faces. To get more faces call GET /v0/face/meta/[Meta]
.
Parameters:
- This method doesn’t accept any additional parameters
Returns:
- A list of objects containing meta string, number of faces marked with this meta string, and JSON representation of the first face object marked with this meta string
Example
Request
GET /v0/meta/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results": [
{
"count": 1,
"face": {
"galleries": ["default", "ppl"]
"id": 2333,
"meta": "Sam Berry",
"photo": "http://static.findface.pro/sample.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:06:42.075754",
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
},
"meta": "Sam Berry"
},
{
"galleries": ["default", "ppl"]
"count": 15,
"face": {
"id": 2563,
"meta": "Angelina Jolie",
"photo": "http://static.findface.pro/sample2.jpg",
"photo_hash": "dc7ac54590729669ca869a18d92cd05e",
"timestamp": "2016-06-13T11:06:42.075754",
"x1": 225,
"x2": 307,
"y1": 345,
"y2": 428
},
"meta": "Angelina Jolie"
}
]
}
Method /galleries GET¶
List all your galleries.
Returns:
- A JSON dictionary with list of gallery ids
Example
Request
GET /v0/galleries/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results": [
"default",
"test"
"57bd75f941741d36ab4614a0",
"57bd76a241741d377bf881ac",
]
}
Method /galleries/<gallery> POST¶
Creates a new gallery under a given name. The gallery name can contain
English letters, numbers, underscore and minus sign
([a-zA-Z0-9_-]+
). It shouldn’t be longer than 48 characters.
Parameters:
This method doesn’t accept any additional parameters.
Example
Request
POST /v0/galleries/testgal HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Response
HTTP/1.1 201 Created
Date: Mon, 13 Jun 2016 06:04:02 GMT
Method /galleries/<gallery> DELETE¶
Deletes the gallery and all faces in it.
Returns:
- HTTP 204 No content.
Example
Request
DELETE /v0/galleries/niceppl HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Length: 0
Response
HTTP/1.1 204 No Content
Method /docs GET¶
Lists documented API versions. Available without authorization.
Method /docs/<version> GET¶
Get documentation for specified API version. Available without authorization.
Method /person/id/<id> GET¶
Parameters:
- This method doesn’t accept any additional parameters
Returns:
- A JSON representation of the person with id = FaceID
Example
Request
GET /person/history/id/2001 HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"cam_ids": [1, 25, 26, 27],
"start": "2016-06-13T11:00:00.000000",
"end": "2016-06-14T11:00:00.000000"
}
Response
HTTP/1.1 200 OK
Date: Mon, 13 Jun 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"results":
[
{
"person_id": 2001,
"face_id": 240344,
"cam_id": 25,
"meta": "Sam Berry",
"screenshot":"https://static.findface.pro/57726179d6946f02f3763824/dc7ac54590729669ca869a18d92cd05e_thumb.j
pg",
"timestamp": "2016-06-13T11:06:42.075754",
},
{
"person_id": 2001,
"face_id": 240422,
"cam_id": 25,
"meta": "Sam Berry",
"screenshot": "https://static.findface.pro/57726179
d6946f02f3763824/dc7ac54590729669ca869a18d92cd05e_thumb.j
pg",
"timestamp": "2016-06-13T11:08:44.073452",
}
]
}
Method /history/search POST¶
This method retrieves all events from camera history of the given parameters.
Parameters:
"person_id"
[optional]: unique person id- ``“cam_ids”`` [optional]: array of camera ids.
"start"
[optional]: search history interval, start time as ISO8601 string"end"
[option]: search history interval, end time as ISO8601 string- ``“friend”`` [optional]: friend or foe identification
- ``“limit”`` [optional]: records per page, if 0 (default) - unlimited
Returns:
- A list of history events.
next_page
: URL to the next page (path and query portion only). If no such field in response - no more pages exist.
Example
Request
POST /v0/history/search HTTP/1.1
Host: 127.0.0.1
Authorization: Token e93437ccdae66d57a45a5c6d9aa7602e
Content-Type: application/json
Content-Length: [length]
{
"limit": 2,
}
Response
HTTP/1.1 200 OK
Date: Mon, 12 Oct 2016 12:23:56 GMT
Content-Type: application/json
Content-Length: [length]
{
"next_page": "/v0/history/search?max_id=4",
"results":[
{
"friend":false,
"meta":"",
"photo_hash":"9fda49f2444f93c33ad8aa914e20e53b",
"cam_id":"12345678123456781234567812345678",
"person_id":8,
"timestamp":"2016-10-11T14:36:27.450000",
"photo":"",
"id":20146,
"y1":77,
"x1":285,
"x2":552,
"y2":345
},
{
"friend":false,
"meta":"",
"photo_hash":"dc7ac54590729669ca869a18d92cd05e",
"cam_id":"12345678123456781234567812345678",
"person_id":8,
"timesamp":"2016-10-12T12:57:07.509000",
"photo":"",
"id":20147,
"x1":236,
"y1":345,
"x2":311,
"y2":419
}
]
}
Galleries¶
There is always a gallery titled default. Faces are always added to the default gallery and cannot be removed from it. The default gallery cannot be stopped.
In addition to the default gallery, you can create custom galleries and add faces into them. Custom galleries allows you to have several datasets in one environment. This might be useful if you need to search through different face lists, for example if you have several products or several customers with different face datasets.
To create a custom gallery, use the method POST /galleries/gallery_name.
By default, all API methods apply to the default gallery. However, you can narrow down usage of most methods to a specific gallery (see the
table below). To do so, provide the gallery name in your API request URI. For example, to search a person in a gallery ‘ppl’, use POST /faces/gallery/ppl/identify/`` instead of ``POST /identify/
.
Default gallery method | Custom gallery method |
---|---|
POST /identify/ |
POST /faces/gallery/<Gallery>/identify/ |
GET /faces/ |
GET /faces/gallery/<Gallery>/ |
GET /face/meta/<Meta> |
GET /face/gallery/<Gallery>/meta/<Meta> |
GET /meta/ |
GET /meta/gallery/<Gallery>/ |
Methods for Video Face Detection¶
These methods extend general API methods of FindFace Enterprise Server SDK.
In this section:
Method /camera POST¶
Description
Creates a new camera.
Parameters:
meta
[optional]: some user-defined string identifierurl
[optional]: url address of the camera’s streamdetector
[optional]: some user-defined string identifierrot
[W,H,X,Y] [optional]: enable detecting and tracking faces only inside a clipping rectangle (ROT, region of tracking).roi
[W,H,X,Y] [optional]: enable posting faces detected only inside a region of interest (ROI).
Returns:
A JSON representation of the added camera or a failure reason.
Example
Request
POST /v0/camera/ HTTP/1.1
Host: 127.0.0.1
Authorization: Token 1234567890qwertyuiop
Content-Type: application/json
Content-Length: [length]
{
"meta": "test",
"url": "http://test.com:1234/stream.flv",
"detector": "detec1"
}
Response
HTTP/1.1 201 Created
Content-Length: [length]
Content-Type: application/json; charset=UTF-8
{
"meta": "meta",
"url": "http://test.com:1234/stream.flv",
"detector": "detec1",
"id": "7bb35e9d-9f4f-4e5b-8811-e1dded6de811"
}
Method /camera GET¶
Description
Lists all cameras.
Parameters:
This method doesn’t accept any additional parameters.
Returns:
The list of all cameras.
Example
Request
GET /v0/camera HTTP/1.1
Host: 127.0.0.1
Authorization: Token 1234567890qwertyuiop
Response
HTTP/1.1 200 OK
Content-Length: [length]
Date: Thu, 13 Oct 2016 12:14:22 GMT
Content-Type: application/json; charset=UTF-8
[
{
"meta": "firstcam",
"url": "http://192.168.133.37:1234/stream.flv"
"id": "34ba07c4-0677-4d5c-9946-62c625cd7127"
},
{
"meta": "newinfo",
"url": "http://5.6.7.8:1234/stream.flv",
"id": "b28a898b-6334-4d37-8888-c9dd858ddc47"
},
...
]
Method /camera/<camera_id> GET¶
Description
Gets information about the camera with id = camera_id
.
Parameters:
This method doesn’t accept any additional parameters.
Returns:
Info about the camera or a failure reason.
Example
Request
GET /v0/camera/b28a898b-6334-4d37-8888-c9dd858ddc47 HTTP/1.1
Host: 127.0.0.1
Authorization: Token 1234567890qwertyuiop
Response
HTTP/1.1 200 OK
Content-Length: [length]
Content-Type: application/json; charset=UTF-8
{
"meta": "test info",
"url": "http://5.6.7.8:1234/stream.flv",
"id": "b28a898b-6334-4d37-8888-c9dd858ddc47"
}
Method /camera/<camera_id> PUT¶
Description
This method can be used to modify certain fields of the camera object with id = camera_id
.
Parameters:
meta
[optional]: new meta stringurl
[optional]: url address of the camera’s streamrot
[W,H,X,Y] [optional]: enable detecting and tracking faces only inside a clipping rectangle (ROT, region of tracking). If you use ROT, be sure to pass this parameter to the camera each time you send a PUT request because if this parameter is missing or empty in the request, ROT on the camera will be deleted.roi
[W,H,X,Y] [optional]: enable posting faces detected only inside a region of interest (ROI). If you use ROI, be sure to pass this parameter to the camera each time you send a PUT request because if this parameter is missing or empty in the request, ROI on the camera will be deleted.
Returns:
A JSON representation of the updated camera with id = <camera_id>.
Example #1
Request
PUT /v0/camera/b28a898b-6334-4d37-8888-c9dd858ddc47 HTTP/1.1
Host: 127.0.0.1
Authorization: Token 1234567890qwertyuiop
Content-Type: application/json
Content-Length: [length]
{
"meta": "newinfo",
"url": "http://zzzz.com:1234/stream.flv"
}
Response
HTTP/1.1 200 OK
Content-Length: [length]
Content-Type: application/json; charset=UTF-8
{
"url": "http://zzzz.com:1234/stream.flv",
"id": "b28a898b-6334-4d37-8888-c9dd858ddc47",
"meta": "newinfo"
}
Example #2
Request
PUT /v0/camera/b28a898b-6334-4d37-8888-c9dd858ddc47 HTTP/1.1
Host: 127.0.0.1
Authorization: Token 1234567890qwertyuiop
Content-Type: application/json
Content-Length: [length]
{
"rot": [
120,
120,
35,
50
],
"roi": [
100,
100,
40,
50
]
}
Response
HTTP/1.1 200 OK
Content-Length: [length]
Content-Type: application/json; charset=UTF-8
{
"id": "b28a898b-6334-4d37-8888-c9dd858ddc47",
"rot": [
120,
120,
35,
50
],
"roi": [
100,
100,
40,
50
]
}
Method /camera/<camera_id> DELETE¶
Description
Deletes the camera with id = camera_id
.
Parameters:
This method doesn’t accept any additional parameters.
Returns:
HTTP 204 No Content in the case of success, or the reason of failure.
Example
Request
DELETE /v0/camera/b28a898b-6334-4d37-8888-c9dd858ddc47 HTTP/1.1
Host: 127.0.0.1
Authorization: Token 1234567890qwertyuiop
Content-Length: 0
Response
HTTP 204 No Content
Tip
You can also find the REST API documentation on our website and at http://<facenapi_ip>:8000/v1/docs
.
Maintenance and Troubleshooting¶
Analyze Log Files¶
Log files provide a complete record of each FindFace Enterprise Server SDK component activity.
findface-facenapi
sudo tail -f /var/log/syslog | grep facenapi
Jun 28 17:20:08 ubuntu findface-facenapi[17104]: [I 170628 17:20:08 base:234] 200 POST /v0/face (127.0.0.1) 1114 487 241 12
1114
— total response time (FindFace Enterprise Server SDK components + MongoDB + Python),487
— face detection time,241
— findface-nnapi response time,12
— tntapi response time.findface-nnapi
sudo tail -f /var/log/syslog | grep nnapi
Jul 7 03:53:05 ubuntu findface-nnapi[49606]: (2017-07-07 10:53:05) [INFO ] Request: 127.0.0.1:34494 0x7fb100000960 HTTP/1.0 POST /facen
Jul 7 03:53:06 ubuntu findface-nnapi[49606]: (2017-07-07 10:53:06) [INFO ] Response: 0x7fb100000960 /facen?x2=0&y1=0&x1=0&y2=0 200 0
fkvideo_detector
sudo tail -f /var/log/syslog | grep fkvideo_detector
extraction-api
sudo tail -f /var/log/syslog | grep extraction-api
Load-balanced service
sudo tail -f /var/log/nginx/service_name.access_log
sudo tail -f /var/log/nginx/nnapi.access_log
Tarantool
sudo cat /var/log/tarantool/FindFace.log
Migrate to Different Detector or Model¶
Tip
Do not hesitate to contact our experts on migration by info@ntechlab.com.
Sometimes you have to migrate your FindFace Enterprise Server SDK instance to another face detector or neural network model. This usually happens when you decide to update to the latest version of the product.
Tip
You can find the models summary here.
If you need to re-detect faces, you should regenerate both normalized face images, thumbnails and facens. If you just want to apply a different model, it usually suffices to regenerate only facens. FindFace Enterprise Server SDK provides tools that can handle most migration use cases.
Warning
Different detectors have diverse sensitivity to certain facial features. Be aware that, after re-detecting your database, you may miss out on some previously found faces.
In this section:
Tools¶
To migrate your instance, you will need the following tools:
Tool | Description |
---|---|
findface-regenerate |
Script that regenerates and overrides face data in MongoDB by applying different detector settings or another model to the images in the Uploads folder. |
mongo2searchapi |
Script that transfers newly generated facens from MongoDB to Tarantool. |
Both tools are automatically installed with findface-facenapi.
Requirements¶
The /var/lib/ffupload/uploads/
folder (Uploads
) has to be populated with at least the original images. Its content can be viewed at http://<findface_upload_IP:3333/uploads/
in your browser.
Overall, the findface-regenerate
tool works with the Uploads
folder in the following way:
Use case | How it works |
---|---|
Different detector settings | The findface-regenerate tool runs original images through the facenapi -nnapi pipeline with different detector [and model] settings, and returns regenerated normalized images, thumbnails and facens. |
Different model | The findface-regenerate tool runs normalized face images through nnapi with different model settings, and returns regenerated facens. |
Regenerate Face Data¶
Important
Before conducting any operations on your MongoDB database, be sure to create its backup.
Apply findface-regenerate
as follows:
Navigate into
/usr/bin/
. Display and thoroughly examine thefindface-regenerate
help message:cd /usr/bin/ findface-regenerate --help
## findface-regenerate --help Usage: /usr/bin/findface-regenerate [OPTIONS] Options: --help show this help information /usr/lib/python3/dist-packages/facenapi/core/decoders/decoder_threaded.py options: --max-size Maximum allowed photo width/height (default 4000) /usr/lib/python3/dist-packages/facenapi/core/detectors/detector_dlib.py options: --dlib-adjust-threshold Adjust face detector threshold (default 0.0) --dlib-max-size images with width or height larger than dlib_max_size will be scaled down before being fed into detector (default 1200) --dlib-normalizer path to normalizer data (default /usr/share/findface-data/normalizer.dat) /usr/lib/python3/dist-packages/facenapi/core/detectors/detector_nnd.py options: --nnd-max-face-size Maximum face size in pixels (no limit if 0) (default 0) --nnd-min-face-size Minimum face size in pixels (default 30.0) --nnd-o-net-thresh (default 0.9) --nnd-p-net-thresh (default 0.5) --nnd-r-net-thresh (default 0.5) --nnd-scale-factor (default 0.79) --nnd-workers Number of detector workers threads. (0 - as much as there are cpus) (default 0) /usr/lib/python3/dist-packages/facenapi/core/main_utils.py options: --decoder Image decoder (threaded) (default threaded) --detector Face detector (dlib,nnd) (default nnd) --extractor Feature extractor (nnapi,extraction-api) (default nnapi) --facen-storage Feature vector storage (searchapi_replicated,tntapi,searchapi) (default tntapi) --id-generator Face id generator (tntime,mongo) (default tntime) /usr/lib/python3/dist-packages/facenapi/server/context.py options: --fetch-proxy Fetch images from urls via proxy, ex: http://1.2.3.4:3128 --ffupload-url url (without path) to PUT images uploaded to /face, ex: http://127.0.0.1:1234 --friend-count (default 5) --friend-interval (default 604800) --gae enable Gender, Age and Emotions support (default False) --mongo-host mongo database host (default localhost) --mongo-port mongo database port (default 27017) --person-identify identify persons (default False) --person-identify-global identify persons across all cameras (default False) --person-identify-threshold threshold for persons identify (default 0.75) --upload-path path of $ffupload_url (default uploads) /usr/lib/python3/dist-packages/facenapi/server/regenerate_facens.py options: --config path to config file --coroutines Number of parallel coroutines (default 30) --every-other (default 1) --every-other-offset (default 0) --facen-size Facen size in number of floats. (facens of this sizes are not regenerated when smart regeneration is enabled) (default -1) --max-id Maximum id (inclusive) --min-id Minimum id (inclusive) --regenerate What to regenerate: facens, thumbs, normalized (comma-separated). (default facens) /usr/lib/python3/dist-packages/tornado/log.py options: --log-file-max-size max size of log files before rollover (default 100000000) --log-file-num-backups number of log files to keep (default 10) --log-file-prefix=PATH Path prefix for log files. Note that if you are running multiple tornado processes, log_file_prefix must be different for each of them (e.g. include the port number) --log-rotate-interval The interval value of timed rotating (default 1) --log-rotate-mode The mode of rotating files(time or size) (default size) --log-rotate-when specify the type of TimedRotatingFileHandler interval other options:('S', 'M', 'H', 'D', 'W0'-'W6') (default midnight) --log-to-stderr Send log output to stderr (colorized if possible). By default use stderr if --log_file_prefix is not set and no other logging is configured. --logging=debug|info|warning|error|none Set the Python log level. If 'none', tornado won't touch the logging configuration. (default info)
To change detector settings, uncomment and edit the detector-related parameters in the
findface-facenapi
configuration file.sudo vi /etc/findface-facenapi.ini detector = 'nnd' ...
To switch the face biometric model, edit the
model_facen
parameter in thefindface-nnapi
configuration file:sudo vi /etc/findface-nnapi.ini model_facen = apricot_320
Configure
findface-regenerate
by using command line arguments as described in the help message. For example, to switch the face detector, execute from/usr/bin
:sudo findface-regenerate --regenerate=normalized,thumbs,facens --config=/etc/findface-facenapi.ini
To switch the model, execute:
sudo findface-regenerate --regenerate=facens --config=/etc/findface-facenapi.ini
Transfer Facens from MongoDB to Tarantool¶
Apply mongo2searchapi
as follows:
Create a backup for Tarantool.
Stop Tarantool.
sudo systemctl stop tarantool@FindFace*
Delete snapshot
.snap
, xlog.xlog
and fast index.idx
files for all tntapi shards.Tip
By default, these files are stored in the following folders:
- Standalone instance:
/opt/ntech/var/lib/tarantool/default/snapshots
/opt/ntech/var/lib/tarantool/default/xlogs
/opt/ntech/var/lib/tarantool/default/index
- Cluster instance:
/opt/ntech/var/lib/tarantool/shard_N/snapshots
/opt/ntech/var/lib/tarantool/shard_N/xlogs
/opt/ntech/var/lib/tarantool/shard_N/index
- Standalone instance:
If facens differ in size for the old and new models, update the facen size in the
FindFace.start
section of the Tarantool configuration file/etc/tarantool/instances.enabled/FindFace_shard_N.lua
. Do so for each shard.sudo vi /etc/tarantool/instances.enabled/FindFace_shard_N.lua FindFace.start("127.0.0.1", 8001, {license_ntls_server="127.0.0.1:3133", facen_size = 320})
Run
mongo2searchapi
on thefindface-facenapi
host:sudo python3 -m facenapi.server.tools.mongo2searchapi --config=/etc/findface-facenapi.ini
Start Tarantool
sudo systemctl start tarantool@FindFace*
Update to The Latest Version¶
In this section:
Update with Data Preservation¶
To update FindFace Enterprise Server SDK to the latest version while maintaining face data, do the following:
Stop all the FindFace Enterprise Server SDK services:
sudo service 'findface*' stop sudo service 'fkvideo*' stop sudo service 'ntls' stop sudo service 'nginx*' stop sudo service 'tarantool*' stop sudo service 'mongod*' stop
Prepare the new package on each designated host.
Upgrade the services by executing:
sudo apt-get update sudo apt-get upgrade
Start the FindFace Enterprise Server SDK services.
sudo service 'findface*' start sudo service 'fkvideo*' start sudo service 'ntls' start sudo service 'nginx*' start sudo service 'tarantool*' start sudo service 'mongod*' start
Migrate FindFace Enterprise Server SDK to a different detector or neural network model if necessary.
Reinstall in Full¶
To fully reinstall FindFace Enterprise Server SDK, do the following:
- Remove the old instance with all the enrolled faces.
- Deploy the latest version, following the standard deployment procedure.
Remove Instance¶
You can automatically remove FindFace Enterprise Server SDK, and, optionally, MongoDB and Tarantool by using the ffserver_uninstall.sh script. Do the following:
Download the
ffserver_uninstall.sh
script to some directory on a designated host (for example, to/home/username/
).From this directory, make the ffserver_uninstall.sh script executable.
chmod +x ffserver_uninstall.sh
Launch the ffserver_uninstall.sh script.
sudo ./ffserver_uninstall.sh
Answer the questions provided by the script interactive wizard to choose whether to remove FindFace Enterprise Server SDK completely (along with all the enrolled faces), or while maintaining face data.
Retrieve Licensing Information¶
You can use API to retrieve licensing information in JSON.
Request
curl http://localhost:3185/license.json -s | jq
Exemplary response
Note
The last_updated
parameter in the response indicates how long ago the local license has been checked for the last time.
Interpret its value (in seconds) as follows:
- [0, 5] — everything is alright.
- (5, 30] — there may be some problems with connection, or with a local drive where the license file is stored.
- (30; 120] — almost certainly something bad happened.
- (120; ∞) — the licensing source response has been timed out. Take action.
"valid": false
: connection with the licensing source has never been established.
{
"name": "NTLS",
"time": 1504794255,
"type": "online",
"license_id": "2e46fed81cc843539f0cf8bd4c1df254",
"generated": 1503571034,
"last_updated": 3,
"valid": {
"value": true,
"description": ""
},
"source": "/ntech/license/import_803e10f14948d5e8a7583de99b0411635743a01cd7afd8589c475f5b60e202cb.lic",
"limits": [
{
"type": "time",
"name": "end",
"value": 4753938994
},
{
"type": "number",
"name": "faces",
"value": 1000000000000,
"current": 80037
},
{
"type": "number",
"name": "cameras",
"value": 4294967295,
"current": 2
},
{
"type": "boolean",
"name": "gender",
"value": true
},
{
"type": "boolean",
"name": "age",
"value": true
},
{
"type": "boolean",
"name": "emotions",
"value": true
},
{
"type": "boolean",
"name": "fast-index",
"value": true
}
],
"services": [
{
"name": "FindFace-tarantool",
"ip": "127.0.0.1:37058"
},
{
"name": "findface-nnapi",
"ip": "127.0.0.1:37057"
},
{
"name": "findface-extraction-api",
"ip": "127.0.0.1:37056"
},
{
"name": "fkvideo-detector",
"ip": "127.0.0.1:37059"
}
]
}
Appendix¶
Neural Network Models¶
Here you can see a summary for neural network models created by our Lab and used in FindFace Enterprise Server SDK:
Type | Name | In use | Facen size |
---|---|---|---|
Face biometrics | model_36 |
2016 | 160 |
model_39c |
2016 | 160 | |
fr_1 |
2016-04/05/2017 | 160 | |
en_1 |
2016-03/03/2017 | 320 | |
en2_face0 |
since 03/14/2017 | 320 | |
apricot_160f |
since 07/31/2017 | 160 | |
apricot_320 |
since 07/31/2017 | 320 | |
banana_800f |
since 09/15/2017 | 800 | |
Gender recognition | fr_1_gender0 |
since 04/05/2017 | N/A |
Age recognition | fr_1_age0 |
since 04/05/2017 | N/A |
Emotions recognition | model_39c_em |
04/05/2017- 08/11/2017 | N/A |
emotion_1 |
since 08/11/2017 | N/A |