Only this pageAll pages
Powered by GitBook
1 of 27

1.8.0, English, 1v1

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Introduction

Thank you for using the JCV Face Recognition Service "Sense ID."

SenseID provides an easy-to-use AI Face Recognition service. Designed for all types of online authentication scenarios to ensure the security and compliance of your online business, SenseID offers features such as photo quality checks, face comparisons, and liveness detection based on a server and edge combination.

SenseID server (private cloud) offers two models, 1v1 (Face Comparison) and 1vN (Face Search). Here, different manuals are provided for each model. This manual is for "Sense ID 1v1 V1.8.0". To switch between other models and versions, click on the upper left of the screen and select the target model and version.

You can access the manual for the SenseID liveness detection SDK here.

  • https://docs.japancv.co.jp/senseid-silent-liveness-detection-sdk/

Manuals are subject to revision. For details, refer to the revision history page in each manual.

Revision History

Date

Revised content

2021/08/20

  • Applied the contents of V1.8.0

  • Fixed some typographical errors

2021/03/08

  • The first edition released

Installation Manual

This manual provides instructions for installing SenseID.

This manual describes how to install the JCV face recognition service "Sense ID." To successfully deploy the service, please read this manual carefully before starting.

This manual is intended for customers who belong to the IT department and have experience using and operating Linux, Kubernetes, Docker, and cloud.

The installation process described in this manual is described in detail in the following figure.

Release Notes

This page provides the release notes of SenseID 1v1

2 UDID

This page describes the UDID required to issue a Sense ID license.

2.1 What is UDID

The UDID is a server identification code calculated from the server hardware information. SenseID activation is associating with the UDID. Download the UDID acquisition tool and follow the instructions to acquire the UDID before applying for a SenseID license.

2.2 UDID acquisition tool

Only the server for Go-Workers needs licenses. The server for Ruby-Cloud-API does not require licenses. Execute the following procedure only on the server for Go-Workers.

The UDID acquisition tool is used to get the UDID of the deployment target server.

The file name of the UDID acquisition tool isSenseIDPrivateCloud-UDIDGetter-V4.1.0.zip.

2.3 Get UDID

Place and unzip the UDID acquisition tool on the server.

Be sure to unzip the ZIP file on a Linux-based system. If you unzip it on a non-Linux system, a soft link failure may occur, and the program execution may fail.

Change the directory to the unzipped folder and execute theUDIDGetter.sh.

Please sent the outputUDID.txtfile, together with your contract number to the JCV product window .

Revision History

Date

Version

Revised content

2021/08/20

V1.8.0

  • Updated the face recognition algorithm

  • Added error code and API parameter descriptions

  • Added function to customize encryption key and vector

2021/03/08

V1.7.0

  • The first edition released

Date

Revised content

2021/08/20

  • The first edition released

Operation Manual

This manual provides instructions during the operation of SenseID.

This manual describes each operation procedure required for SenseID.

This manual is intended for customers who belong to the IT department and have experience using and operating Linux, Kubernetes, Docker, and cloud.

$ unzip SenseIDPrivateCloud-UDIDGetter-V4.1.0.zip
$ cd /SenseIDPrivateCloud-UDIDGetter-V4.1.0
$ sudo ./UDIDGetter.sh

Revision History

Date

Revised content

2021/08/20

  • Deleted the unused error code 2006 from and .

  • Added descriptions to the error code 2003 and 2004 in and .

  • Deleted the unused liveness status from and .

2021/03/08

  • The first edition released

Chapter 1 Face Compare
Chapter 2 Quality Check
Chapter 1 Face Compare
Chapter 2 Quality Check
Section 1.4 /identity/silent_image_verification/stateless
Chapter 3 Liveness Detection

1 System Requirements

This page describes the system operating environment requirements of SenseID.

1.1 System

Ubuntu Server 18.04 LTS is recommended for the Sense ID usage environment. We recommend a quad-core or higher CPU, 8GM or higher RAM, and 100GB or higher disk capacity on the hardware side. Note that AVX is required for the CPU instruction set.

Configuration items

Configuration requirements

Minimum operating system kernel version number

V3.2.0 or more

CPU model

x86_64

Requirements for the number of CPU cores

Quad-core (4) or more

CPU instruction set

SSE, AVX, FMA;

compatibility: SSE > AVX > FMA;

operating speed: FMA > AVX > SSE

RAM requirements

16GB or more

Supported OS & minimum version

Ubuntu Server (16.04 LTS) or higher

Disk space requirements

100GB or more

1.2 Services

The services described in this section are running inside the server. It is strongly recommended to implement a secure API mechanism, authentication mechanism, secure communication, and DNS outside of SenseID for safe use.

It is recommended to use separate servers for Ruby-Cloud-API and Go-Workers if possible.

  • Ruby-Cloud-API

    • The HTTP services, including the main interface for client API calls.

    • Service port: 3000

  • Go-Workers

    • The back-end computing vision services, primarily the encapsulation of algorithms provided to Ruby-Cloud-API in HTTP.

    • Service port: 50050

4 Update

This page describes how to update to a higher version of SenseID.

In this manual, we will guide you through the update procedure updating SenseID from V1.7.0 to V1.8.0.

As a preparation, unzip and place the V1.8.0 package 1v1-private-cloud-v1.8.tgz in the same directory where V1.7.0 is installed.

4.1 Stop Ruby-Cloud-API service (old version)

Change the directory to the old version folder, and stop the Ruby-Cloud-API service.

4.2 Updated configuration file (new version)

Refer to , , in the , set the number of CPUs and the address of Go-Workers in the new version's configuration file as in the old version.

4.3 Load service images (new version)

Change the directory to the new version folder, and load the Ruby-Cloud-API image file.

4.4 Start Ruby-Cloud-API service (new version)

Start the Ruby-Cloud-API service of the new version.

4.5 Stop Go-Workers service (old version)

Change the directory to the old version folder, and stop the Go-Workers service.

4.6 Copy the license files

Copy the license files from the old version to specified folders of the new version.

senseid_kestrel.lic is required since V1.8.0. If you have not received it yet, please contact the JCV product window () with the UDID.txt file and your contract number. For details, refer to in the .

After receiving senseid_kestrel.lic, copy it to the specified folder of the new version with the following command.

4.7 Start Go-Workers service (new version)

Change the directory to the new version folder, and start the Go-Workers service.

4.8 Check services (new version)

Check if services started normally.

  • Ruby-Cloud-API

  • Go-Workers

4 Service Deployment

This page describes detailed steps to install SenseID.

This chapter describes how to deploy and activate the SenseID service, primarily installing, configuring, launching critical services and potential issues and solutions.

4.1 Confirm the installation package

The installation package should have been unzipped to place the license files. See Section 3.3.1 for more details.

Change the directory to the root folder where you unzipped the SenseID installation package.

$ cd 1v1-private-cloud-v1.8
$ ls -1

The structure is as follows:

api.tar
docker-compose
docker-compose.yml
go-workers
load_image.sh
package.toml
product.toml

4.2 Deploy Go-Workers

This service is a major computing service, so it is recommended to allocate dedicated server resources if possible.

4.2.1 Adjust CPU cores

Before deploying Go-Workers, you need to get the number of physical CPU cores on your server. The command to get the physical CPU core information is as follows.

$ echo Cores=$(($(lscpu | awk '/^Socket/{print $2}') * $(lscpu | awk '/^Core/{print $4}')))

Change the directory to the Go-Workers folder, open the.envfile, and set theHANDLERSvalue to the number of physical CPU cores obtained above if you are using a dedicated server. Otherwise, specify a number. Save and close the.envfile.

$ cd go-workers
$ vi .env

HANDLERS cannot be set to a value that exceeds the number of physical CPU cores on the server. The higher theHANDLERSvalue is, the higher the number of concurrent services and the higher the memory and CPU consumption.

4.2.2 Start Go-Workers service

Before you start, make sure your license has been replaced.

Start the Go-Workers service.

$ sudo ./start.sh

You only need to execute this instruction once.

A script to stop the service is also provided in the same folder. Execute it only when you want to stop the service.

$ sudo ./stop.sh

4.2.3 Check Go-Workers service

To confirm whether the Go-Workers service started normally, try the following command to see the logs.

$ tail -f tmp/worker.log.0

If the tail command contains Server Listen on port 50050, the service has started successfully.

Also, perform the health check with the following command.

$ curl 127.0.0.1:50050/healthcheck

An example is as follows (This indicates that the service started successfully).

{"request_id":"07a41c21822e4223a373e77bfc186ed2","status":"ok"}

4.3 Deploy Ruby-Cloud-API

The deployment of the following services depends on Docker. Make sure you have Docker installed on your server.

4.3.1 Load service images

Load the Ruby-Cloud-API image file.

$ cd 1v1-private-cloud-v1.8
$ sudo ./load_image.sh

The execution result is as follows.

Loaded image: registry.sensetime.com/senseid-cloudv2/api-1v1:xxx

4.3.2 Set Go-Workers address

Get the IP address of the Go-Workers server.

$ hostname -I | cut -d' ' -f1

Open the .env file in the root folder of the SenseID installation package.

$ vi .env

Set the WORKER_IP value in the last line to the IP address of the server where the Go-Workers service is deployed.

4.3.3 Adjust CPU cores

Sets the number of physical CPU cores on the server, the same way as Go-Workers.

$ vi .env

Open the.envfile, and set theHANDLESvalue to the number of physical CPU cores obtained if you are using a dedicated server. Otherwise, specify a number. Save and close the.envfile.

HANDLES cannot be set to a value that exceeds the number of physical CPU cores on the server. The higher theHANDLESvalue is, the higher the number of concurrent services and the higher the memory and CPU consumption.

4.3.4 Start Ruby-Cloud-API service

Start the Ruby-Cloud-API service.

$ sudo ./docker-compose up -d

The results are as follows.

Creating network "1v1-private-cloud-yyyymmdd_default" with the default driver
Creating 1v1-private-cloud_api_1 ... done

Confirm that the Docker is running.

$ sudo ./docker-compose ps

The results are as follows.

         Name                    Command             State               Ports
---------------------------------------------------------------------------------------
1v1-private-cloud_api_1   ./entrypoint.sh start   Up (healthy)   0.0.0.0:3000->3000/tcp

The service is now successfully deployed.

4.3.5 Check Ruby-Cloud-API service

Perform the health check with the following command.

$ curl 127.0.0.1:3000/healthcheck

An example is as follows (This indicates that the service started successfully).

{"code":1000,"status":"ok"}
$ tar -xvzf 1v1-private-cloud-v1.8.tgz
1v1-private-cloud-v1.7/
1v1-private-cloud-v1.8/
$ cd 1v1-private-cloud-v1.7
$ sudo ./docker-compose stop
$ cd 1v1-private-cloud-v1.8
$ sudo ./load_image.sh
$ sudo ./docker-compose up -d
$ cd 1v1-private-cloud-v1.7/go-workers
$ sudo ./stop.sh
$ cp 1v1-private-cloud-v1.7/go-workers/fixture/lisense/senseid_face/senseid_face.lic 1v1-private-cloud-v1.8/go-workers/fixture/lisense/senseid_face
$ cp 1v1-private-cloud-v1.7/go-workers/fixture/lisense/senseid_liveness/senseid_liveness.lic 1v1-private-cloud-v1.8/go-workers/fixture/lisense/senseid_liveness
$ cp {file_path}/senseid_kestrel.lic {installation_path}/1v1-private-cloud-v1.8/go-worker/fixture/license/senseid_kestrel
$ cd 1v1-private-cloud-v1.8/go-workers
$ sudo ./start.sh
$ sudo ./docker-compose ps
$ tail -f tmp/worker.log.0
Section 4.2.1 Adjust CPU cores
Section 4.3.2 Set Go-Workers address
Section 4.3.3 Adjust CPU cores
Installation Manual
Chapter 2 UDID
Installation Manual

5 Error Codes

This page describes the error code that occurs during the operation of SenseID.

error_code

Value

Description

STID_OK

0

Success

STID_E_INVALID_ARG

-1

Invalid parameter, please check whether the value of each input parameter is correct

STID_E_HANDLE

-2

Handle error, please check whether the input handle is correct

STID_E_OUTOFMEMORY

-3

Insufficient memory, system error

STID_E_FAIL

-4

Operation failure, internal error

STID_E_INVALID_PIXEL_FORMAT

-6

The image format is not supported, please refer to the interface description

STID_E_FILE_NOT_FOUND

-7

Resource file not found (such as license, model, etc.). Check whether the input path is correct

STID_E_INVALID_FILE_FORMAT

-8

Incorrect file format, mainly related to the model file

STID_E_MODEL_FILE_EXPIRE

-9

Model file expired

STID_E_INVALID_AUTH

-13

Illegal license file (for example, the product name is not consistent), or license file does not load.

STID_E_AUTH_EXPIRE

-15

license file or SDK expires

STID_E_UDID_MISMATCH

-16

UDID mismatch, and the hardware fingerprint bound to the license is inconsistent with the current device’s hardware fingerprint

STID_E_VERSION_MISMATCH

-23

Product SDK version mismatch. The current SDK version is beyond the version range specified in the license

STID_E_PLATFORM_NOTSUPPORTED

-24

The platform is not supported. The current running SDK platform is inconsistent with the platform scope specified in the license

STID_E_MODEL_UNZIP_FAILED

-25

Model decompression failed, please check whether the model file is damaged

STID_E_SUBMODULE_NOT_FOUND

-26

Submodel does not exist, please check whether the use of the model file is correct

STID_E_CAPABILITY_NOTSUPPORTED

-2067857410

Use an interface that does not support capabilities in the license

STID_E_GET_UDID_FAIL

-2146304001

Failed to get the UDID

STID_E_READ_MODEL_FILE_FAIL

-10

Failed to read the model file

STID_E_LOAD_LIBRARY_FAILED

-2065563655

Failed to load dynamic library

STID_E_ONLINE_ACTIVATE_PARENT_LICENSE_NOT_FOUND

-2145517553

The parent license can't

STID_E_ONLINE_ACTIVATE_PARENT_LICENSE_TOO_MANY

-2145517552

Too many parent certificates of the authorization file, up to 10 levels

2.1 /quality/face/stateless

Perform a quality check of the photo.

The photo file can contain multiple faces.

For photo standards, refer to Chapter 3 Photo and Video Standards in the Operation Manual.

Request mode

POST

Request URL

http://ip:port/quality/face/stateless

Request parameters

Name

Type

Required

Description

encrypted_image

string

Yes

Encrypted photo Encryption method reference:

Normal response

Name

Type

Description

code

int

System response code: 1000

faces

Array

Information about the quality of each face in the photo

request_id

string

The ID of this request

{
    "code": 1000,
    "faces": [
        {
            "rect": { # face frame position
                "left": integer, # The left border of the face frame is the X-coordinate, and the upper left corner of the image is the origin of coordinates
                "top": integer, # The top border of the face frame is the Y-coordinate, and the upper left corner of the image is the origin of coordinates
                "right": integer, # The right border of the face frame is the X-coordinate, and the upper left corner of the image is the origin of coordinates
                "bottom": integer # The bottom border of the face frame is the Y-coordinate, and the upper left corner of the image is the origin of coordinates
            },
            "pose": { # pose angle information
                "yaw": float, # rotation angle around the Y-axis
                "pitch": float, # rotation angle around the X-axis
                "roll": float # rotation angle around the Z-axis
            },
            "occlusion":{ # occlusion information
                "left_eye": float, # The proportion of left eye not occluded with value range between [0,1]. The larger the value, the less occlusion
                "right_eye": float, # The proportion of right eye not occluded with value range between [0,1]. The larger the value, the less occlusion
                "nose": float, # The proportion of nose not occluded with value range between [0,1]. The larger the value, the less occlusion
                "mouth": float, # The proportion of mouth not occluded with value range between [0,1]. The larger the value, the less occlusion
                "total": float # The proportion of five features not occluded with value range between [0,1]. The larger the value, the less occlusion
            },
            "distance2center": float, # The proportion of the distance of the face to the center of the image with value range between [0,1]. The higher the score, the closer the face to the center of the image. The calculation formula is as follows: max (1-distance from the center of five features to the center of the image/distance of the short side of the image, 0)
            "size": float, # The proportion of five features in the image with value range between [0,1]. The higher the score, the greater the proportion of five features: Area of the five features in the image/image area
            "brightness": float, # Face brightness score with value range between [-1,1]. The higher the score, the higher the brightness
            "sharpness": float, # Face sharpness score with value range between [0,1]. The higher the score, the higher the sharpness
            "mouth_open": float, # Degree of mouth opening with value range between [0,1]. The higher the score, the lower the degree of mouth opening
            "integrity": float # Integrity of the five features in the image, with value range between [0,1]. The higher the score, the more integral the face is in the image. The calculation formula is as follows: Area of the five features in the image/five features area
        }
    ],
    "request_id": string
}

Abnormal response

Name

Type

Instructions

code

int

System response code

message

string

Error Messages

request_id

string

The ID of this request

{
    "code": int,
    "message": string,
    "request_id": string
}

System response code

code

Field value

Description

1200

invalid argument

Invalid input parameter

2003

invalid image size

The image size (height and width in pixel) does not meet the requirements

2004

invalid content length

The image file size does not meet the requirements

2005

invalid image type or corrupted

The image type does not meet the requirements

4000

detection failed

Feature extraction failed, no face detected in the image

Possible HTTP status codes

status

Description

400

BAD_REQUEST

404

NOT_FOUND

411

LENGTH_REQUIRED

413

PAYLOAD_TOO_LARGE

500

INTERNAL_ERROR

Sample

curl -X POST "http://ip:port/quality/face/stateless" \
  -d encrypted_image=xxx
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClient {
    public static final String POST_URL = "http://127.0.0.1:3000/quality/face/stateless";
    private static AESCipher cipher = new AESCipher("dcbbad6765e14139a07d34b92292a672", "df25d188a061");

    public static void Post() throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost(POST_URL);

        List<NameValuePair> params = new ArrayList<>();

        String encryptedImage = cipher.encrypt(
                Files.readAllBytes(Paths.get("src/main/resources/face_01.jpg")));

        params.add(new BasicNameValuePair("encrypted_image", encryptedImage));

        post.setEntity(new UrlEncodedFormEntity(params));
        HttpResponse response = httpclient.execute(post);

        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity respEntity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(respEntity.getContent()));
            String line = reader.readLine();
            System.out.println(line);
        } else {
            HttpEntity respEntity = response.getEntity();
            String responseString = EntityUtils.toString(respEntity);
            System.out.println("error:" + response.getStatusLine().getStatusCode()
                    + "  " + response.getStatusLine().getReasonPhrase());
            System.out.println("cause of error:" +responseString);
        }
    }

    public static void main(String[] args) throws Exception {
        Post();
    }
}
[Photo and Video Encryption]

3.1 /liveness/silent_detection/stateless

Perform silent liveness detection on the server to decide whether the person in the uploaded video is a living human or not.

For video standards, refer to Chapter 3 Photo and Video Standards in the Operation Manual.

Request mode

POST

Request URL

http://ip:port/liveness/silent_detection/stateless

Request parameters

Name

Type

Required

Description

encrypted_video

string

Yes

Encrypted video Encryption method reference:

return_image

boolean

No

Whether to return the selected frame of face and timestamp of the selected frame of the photo. The default is false. image_timestamp and base64_image are returned only when this value is true and the live detection is passed.

return_face_image

boolean

No

Whether to return the face clipping of the selected frame of the photo. The default is false. base64_face_imageis returned only when this value is true and the live detection is passed.

return_status

boolean

No

Whether to return the error status description. The default is false. liveness_status is returned only when this value is true.

Normal response

Name

Type

Description

code

int

System response code: 1000

passed

boolean

Liveness detection passed or not

liveness_score

float

The score of silent liveness detection (for reference only, please refer to the passed field)

liveness_status

string

Description of the error status of silent liveness detection. This field is returned when return_status=true

image_timestamp

float

Timestamp of the selected frame of image in seconds. This field is returned only when passed=true and return_image=true

base64_image

string

The selected frame of the photo. This field is returned only when passed=true and return_image=true

base64_face_image

string

Face clipping of the selected frame of the photo. This field is returned only when passed=true and return_face_image=true

request_id

string

The ID of this request

The possible results ofliveness_statusare as follows:

Status

Description

ok

Silent liveness detection passed: the person in the video is real

hack

Silent liveness detection failed, reason: face spoofing (for example, photos taken by the mobile phone)

short_time

Silent liveness detection failed, reason: video time with the face is less than 2s

{
    "code": int,
    "passed": boolean,
    "liveness_score": float,
    "liveness_status": string,
    "image_timestamp": float,
    "base64_image": string,
    "base64_face_image": string,
    "request_id": string
}

Abnormal response

Name

Type

Instructions

code

int

System response code

message

string

Error Messages

request_id

string

The ID of this request

{
    "code": int,
    "message": string,
    "request_id": string
}

System response code

code

Field value

Description

1200

invalid argument

Invalid input parameter

2008

invalid video error

Invalid videos (video time is less than 2s)

4007

liveness silent check failed

Silent liveness detection failed

Possible HTTP status codes

status

Description

400

BAD_REQUEST

404

NOT_FOUND

411

LENGTH_REQUIRED

413

PAYLOAD_TOO_LARGE

500

INTERNAL_ERROR

Sample

curl -X POST "http://ip:port/liveness/silent_detection/stateless" \
  -d encrypted_video=xxx \
  -d return_status=true \
  -d return_image=true \
  -d return_face_image=true
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClient {
    public static final String POST_URL = "http://127.0.0.1:3000/liveness/silent_detection/stateless";
    private static AESCipher cipher = new AESCipher("dcbbad6765e14139a07d34b92292a672", "df25d188a061");

    public static void Post() throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost(POST_URL);

        List<NameValuePair> params = new ArrayList<>();

        String encryptedVideo = cipher.encrypt(
                Files.readAllBytes(Paths.get("src/main/resources/video_01.mp4")));

        params.add(new BasicNameValuePair("encrypted_video", encryptedVideo));
        params.add(new BasicNameValuePair("return_image", "true"));
        params.add(new BasicNameValuePair("return_face_image", "true"));
        params.add(new BasicNameValuePair("return_status", "true"));

        post.setEntity(new UrlEncodedFormEntity(params));
        HttpResponse response = httpclient.execute(post);

        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity respEntity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(respEntity.getContent()));
            String line = reader.readLine();
            System.out.println(line);
        } else {
            HttpEntity respEntity = response.getEntity();
            String responseString = EntityUtils.toString(respEntity);
            System.out.println("error:" + response.getStatusLine().getStatusCode()
                    + "  " + response.getStatusLine().getReasonPhrase());
            System.out.println("cause of error:"+responseString);
        }
    }

    public static void main(String[] args) throws Exception {
        Post();
    }
}
[Photo and Video Encryption]
[email protected]
[email protected]

1.4 /identity/silent_image_verification/stateless

Compare the photo and the video uploaded through the interface to determine whether the faces belong to the same person.

For photo and video standards, refer to Chapter 3 Photo and Video Standards in the Operation Manual.

Request mode

POST

Request URL

http://ip:port/identity/silent_image_verification/stateless

Request parameters

Name

Type

Required

Description

encrypted_video

string

Yes

Encrypted video Encryption method reference:

encrypted_image

string

Yes

Encrypted photo Encryption method reference:

auto_rotate

boolean

No

The default value is false, indicating that the photo is not rotated. When the value is true, the photo is automatically rotated.

check_quality

boolean

No

The default value is false, and no quality test is performed. When the value is true, the photo quality is checked.

return_image

boolean

No

Whether to return the selected frame of face and timestamp of the selected frame of the photo. The default is false. image_timestamp and base64_image are returned only when this value is true and the live detection is passed.

return_face_image

boolean

No

Whether to return the face clipping of the selected frame of the photo. The default is false. base64_face_imageis returned only when this value is true and the live detection is passed.

return_status

boolean

No

Whether to return the error status description. The default is false. liveness_status is returned only when this value is true.

check_qualitycan currently only evaluate face occlusion. Other evaluation items may be added in the future.

Normal response

Name

Type

Description

code

int

System response code: 1000

passed

boolean

Liveness detection passed or not

liveness_score

float

The score of silent liveness detection (for reference only, please refer to the passed field)

liveness_status

string

Description of the error status of silent liveness detection. This field is returned when return_status=true

verification_score

float

Face comparison score, recommended threshold: > 0.7. This field is returned when passed=true

image_timestamp

float

Timestamp of the selected frame of image in seconds. This field is returned only when passed=true and return_image=true

base64_image

string

The selected frame of the photo. This field is returned only when passed=true and return_image=true

base64_face_image

string

Face clipping of the selected frame of the photo. This field is returned only when passed=true and return_face_image=true

request_id

string

The ID of this request

The possible results ofliveness_statusare as follows:

Status

Description

ok

Silent liveness detection passed: the person in the video is real

hack

Silent liveness detection failed, reason: face spoofing (for example, photos taken by the mobile phone)

short_time

Silent liveness detection failed, reason: video time less than 2s

{
    "code": int,
    "passed": boolean,
    "liveness_score": float,
    "liveness_status": string,
    "verification_score": float.
    "image_timestamp": float,
    "base64_image": string,
    "base64_face_image": string,
    "request_id": string
}

Correlations between the verification score threshold and the error rate:

Threshold

0.4

0.5

0.6

0.7

0.8

0.9

error rate

1/10

1/100

1/1000

1/10,000

1/100,000

1/1,000,000

Recommended threshold: greater than 0.7.

Abnormal response

Name

Type

Instructions

code

int

System response code

message

string

Error Messages

request_id

string

The ID of this request

{
    "code": int,
    "message": string,
    "request_id": string
}

System response code

code

Field value

Description

1200

invalid argument

Invalid input parameter

2003

invalid image size

The image size (height and width in pixel) does not meet the requirements

2004

invalid content length

The image file size does not meet the requirements

2005

invalid image type or corrupted

The image type does not meet the requirements

4000

detection failed

Feature extraction failed, no face detected in the image

4004

face occlusion

The face is detected, but the eyes, nose, or mouth are partially occluded

4007

liveness silent check failed

Silent liveness detection failed

Possible HTTP status codes

status

Description

400

BAD_REQUEST

404

NOT_FOUND

411

LENGTH_REQUIRED

413

PAYLOAD_TOO_LARGE

500

INTERNAL_ERROR

Sample

Curl

curl -X POST "http://ip:port/identity/silent_image_verification/stateless" \
  -d encrypted_video=xxx \
  -d encrypted_image=xxx \
  -d auto_rotate=true

Java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClient {
    public static final String POST_URL = "http://127.0.0.1:3000/identity/silent_image_verification/stateless";
    private static AESCipher cipher = new AESCipher("dcbbad6765e14139a07d34b92292a672", "df25d188a061");

    public static void Post() throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost(POST_URL);

        List<NameValuePair> params = new ArrayList<>();

        String encryptedVideo = cipher.encrypt(
                Files.readAllBytes(Paths.get("src/main/resources/video_01.mp4")));
        String encryptedImage = cipher.encrypt(
                Files.readAllBytes(Paths.get("src/main/resources/face_01.jpg")));

        params.add(new BasicNameValuePair("encrypted_video", encryptedVideo));
        params.add(new BasicNameValuePair("encrypted_image", encryptedImage));
        params.add(new BasicNameValuePair("auto_rotate", "true"));
        params.add(new BasicNameValuePair("return_image", "true"));
        params.add(new BasicNameValuePair("return_face_image", "true"));
        params.add(new BasicNameValuePair("return_status", "true"));

        post.setEntity(new UrlEncodedFormEntity(params));
        HttpResponse response = httpclient.execute(post);

        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity respEntity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(respEntity.getContent()));
            String line = reader.readLine();
            System.out.println(line);
        } else {
            HttpEntity respEntity = response.getEntity();
            String responseString = EntityUtils.toString(respEntity);
            System.out.println("error:" + response.getStatusLine().getStatusCode()
                    + "  " + response.getStatusLine().getReasonPhrase());
            System.out.println("cause of error:" +responseString);
        }
    }

    public static void main(String[] args) throws Exception {
        Post();
    }
}
[Photo and Video Encryption]
[Photo and Video Encryption]

3 Liveness Detection

1 Face Compare (Stateless)

2 Quality Check

5 Deployment FAQ

This page describes common issues during SenseID installation.

Q1. The instruction set of the machine for deployment is too low in this version, or the instruction set does not contain the AVX instruction set. It is found that the log contains "SIGILL: illegal instruction” after executing tail -f tmp/worker.log.0 to check the returned log. What’s the solution to this problem?

First, check the instruction set contained in the current machine:

  1. Execute this command: cat /proc/cpuinfo

  2. Check flag

If it does not contain a mix of AVX & AVX2, indicating that the CPU instruction set does not support the Avx instruction set.

There are two solutions:

1) Replace it with a machine containing an AVX instruction set;

2) Force the machine to use an SSE instruction set. However, the service performance will degrade and processing speed will be halved;

Method to force the machine to use an SSE instruction set: open go-workers/. env,

Modify FORCE_SET_SSE=false to FORCE_SET_SSE=true.

Note: Save the exit after modifying, and restart the go-workers. The method to restart the service is as follows:

First execute ./stop/sh then execute ./start.sh

Q2. If the start command (./start.sh) is called repeatedly during deployment, or the port is used, for example, if you execute ./start.sh multiple times in go-workers, it is found that the following errors are reported after checking the log:

listen: listen tcp :50050: bind: address already in use

Note: Start "./start.sh "once respectively corresponding when starting Go-Workers or Ruby-Cloud-API.

1) Execute

ps aux | grep supervisord

2) Kill the corresponding process No. of ./tool/supervisord -c config/supervisor.conf -d:

kill -9 PID

Q3. A summary error type about the use of license:

The "private cloud package" which we provide does not contain licenses by default. For details of licenses, please refer to Chapter 3 License Activation.

1)error panic: bad license: -1

It means the license has broken(such as an empty licenes),please replace the license file again.

2) error panic: open fixture/license/senseid_ocr/senseid_ocr.lic: no such file or directory

It means the license is not imported,please import the license file into the specified folder.

3)error panic: bad license: -16

It meas "udid mismatch", and the hardware fingerprint bound to the license is inconsistent with the current device’s hardware fingerprint.Please make sure the device's hardware information has not changed.

Maybe you use the wrong license or the device's udid is changed.

If you make sure that device's uuid has changed,please provide the new udid to the business person who can apply for the new license to you,and then remember to replace the new license.

Q4 error:-8 ?

It means the file format is incorrect, mainly related to the model file.

For example, using the decompression software under the windows system to decompress and upload the "private cloud package" to server may cause partial damage of the model file. It is recommended that customers re-upload the installation package(xxx.tar) to the server and use the command line(tax xf xxx.tar) to decompress it on the server

3 License Activation

This page describes the activation of SenseID.

3.1 What is license

A license file is required to use the Go-Workers service of SenseID. The activation of the license is associating with the UDID. License files may differ depending on the services you are using. One SenseID server can correspond to one to three license files. You must rename the license file and place it in the specified directory before you can deploy the service.

Only the server for Go-Workers needs licenses. The server for Ruby-Open-API does not require licenses. Execute the following procedure only on the server for Go-Workers.

The JCV product window provides the SenseID license file. Refer to the following parts for activation details.

3.2 Change license file names

  • Change the SENSEID_FACE_xxx.lic file to senseid_face.lic.

  • Change the SENSEID_KESTREL_xxx.lic file to senseid_kestrel.lic.

  • Change the SENSEID_LIVENESS_xxx.lic file to senseid_liveness.lic.

3.3 Replace license files

3.3.1 Unzip the installation package

Package name: 1v1-private-cloud-v1.8.tgz

Be sure to unzip the ZIP file on a Linux-based system. If you unzip it on a non-Linux system, a soft link failure may occur, and the program execution may fail.

$ tar -xvzf 1v1-private-cloud-v1.8.tgz

3.3.2 Place the license files

Change the directory to the license folder where you unzipped the SenseID installation package.

$ cd 1v1-private-cloud-v1.8/go-workers/fixture/license

You can confirm that the following three folders are displayed by executing the following command.

$ ls -1

senseid_face
senseid_kestrel
senseid_liveness

Copy the license files to the specified directories and overwrite the original files.

#1) Copy the senseid_face.lic to the senseid_face folder, and overwrite the previous license file
$ cp {file_path}/senseid_face.lic {installation_path}/1v1-private-cloud-v1.8/go-workers/fixture/license/senseid_face

#2) Copy the senseid_kestrel.lic to the senseid_kestrel folder, and overwrite the previous license file
$ cp {file_path}/senseid_kestrel.lic {installation_path}/1v1-private-cloud-v1.8/go-workers/fixture/license/senseid_kestrel

#3) Copy the senseid_liveness.lic to the senseid_liveness folder, and overwrite the previous license file
$ cp {file_path}/senseid_liveness.lic {installation_path}/1v1-private-cloud-v1.8/go-workers/fixture/license/senseid_liveness

3 Photo and Video Standards

This page describes the standards of input photos and videos for using the SenseID API.

3.1 Input photo standards

  1. The photo format should be one of the following. JPG (JPEG) ,BMP, PNG, GIF, TIFF The recommended format is JPG (JPEG).

  2. The width and height of the photo should be at least 32 pixels and no more than 5,000 pixels. The recommended size is 640*480 pixels.

  3. The size of the photo file must be 5MB or less. The larger the size, the more the processing performance will be affected. We recommend compressing the photo file to 100KB.

3.2 Input video standards

  1. Most common video formats are supported. Include but not restrict to MP4, AVI, FLV, WMV, MOV, RM

    The recommended format is MP4.

  2. The width and height of the video should be at least 8 pixels and no more than 5,000px. The recommended size is 640*480 pixels.

  3. The size of the video file must be 16MB or less. The larger the size, the more the processing performance will be affected. We recommend compressing the video file to about 500KB to 1MB.

1.3 /identity/liveness_image_verification/stateless

Compare the photo and the liveness data uploaded through the interface to determine whether the faces belong to the same person.

For photo standards, refer to Chapter 3 Photo and Video Standards in the Operation Manual.

Request mode

POST

Request URL

http://ip:port/identity/liveness_image_verification/stateless

Request parameters

Name

Type

Required

Description

liveness_file

file

Yes

The encrypted binary stream file (i.e., protobufData) returned after the successful detection by interactive liveness or silent liveness SDK is already encrypted without additional encryption required

encrypted_image

string

Yes

Encrypted photo Encryption method reference:

auto_rotate

boolean

No

The default value is false, indicating that the photo is not rotated. When the value is true, the photo is automatically rotated.

check_quality

boolean

No

The default value is false, and no quality test is performed. When the value is true, the photo quality is checked.

Normal response

Name

Type

Instructions

code

int

System response code: 1000

verification_score

float

The face comparison score is from 0-1. The greater the value, the greater the probability that the two faces belong to the same person.

request_id

string

The ID of this request

{
    "code": 1000,
    "verification_score": float,
    "request_id": string
}

Correlations between the verification score threshold and the error rate:

Threshold

0.4

0.5

0.6

0.7

0.8

0.9

error rate

1/10

1/100

1/1000

1/10,000

1/100,000

1/1,000,000

Recommended threshold: greater than 0.7.

Abnormal response

Name

Type

Instructions

code

int

System response code

message

string

Error Messages

request_id

string

The ID of this request

{
    "code": int,
    "message": string,
    "request_id": string
}

System response code

code

Field value

Description

1200

invalid argument

Invalid input parameter

2003

invalid image size

The image size (height and width in pixel) does not meet the requirements

2004

invalid content length

The image file size does not meet the requirements

2005

invalid image type or corrupted

The image type does not meet the requirements

2007

corrupted liveness data error

Liveness data corruption

4000

detection failed

Feature extraction failed, no face detected in the image

4004

face occlusion

Face detected but partially obscured by eyes, nose, or mouth

Possible HTTP status codes

status

Description

400

BAD_REQUEST

404

NOT_FOUND

411

LENGTH_REQUIRED

413

PAYLOAD_TOO_LARGE

500

INTERNAL_ERROR

Sample

Curl

curl -X POST "http://ip:port/identity/liveness_image_verification/stateless" \
  -F liveness_file=@/PATH/TO/FILE \
  -d encrypted_image=xxx \
  -d auto_rotate=true

Java

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class HttpClient {
    public static final String POST_URL = "http://127.0.0.1:3000/identity/liveness_image_verification/stateless";
    private static AESCipher cipher = new AESCipher("dcbbad6765e14139a07d34b92292a672", "df25d188a061");

    public static void Post() throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost(POST_URL);

        MultipartEntityBuilder entity = MultipartEntityBuilder.create();
        String encryptedImage = cipher.encrypt(
                Files.readAllBytes(Paths.get("src/main/resources/face_01.jpg")));

        entity.addPart("liveness_file", new FileBody(new File("src/main/resources/mobile.protobuf")));
        entity.addPart("encrypted_image", new StringBody(encryptedImage));
        entity.addPart("auto_rotate", new StringBody("true"));

        post.setEntity(entity.build());
        HttpResponse response = httpclient.execute(post);

        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity respEntity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(respEntity.getContent()));
            String line = reader.readLine();
            System.out.println(line);
        } else {
            HttpEntity respEntity = response.getEntity();
            String responseString = EntityUtils.toString(respEntity);
            System.out.println("error:" + response.getStatusLine().getStatusCode()
                    + "  " + response.getStatusLine().getReasonPhrase());
            System.out.println("cause of error:"+responseString);
        }
    }

    public static void main(String[] args) throws Exception {
        Post();
    }
}
[Photo and Video Encryption]

API Manual

This manual provides instructions on how to use the SenseID APIs.

In this manual, we will provide detailed procedures for all APIs provided by SenseID on a case-by-case basis for readers to consult when necessary. The instructions on API include function introduction, parameters, responses, error messages, etc.

1.1 /identity/image_verification/stateless

Compare the two photos including only one face each uploaded through the interface to determine whether the two faces belong to the same person.

For photo standards, refer to Chapter 3 Photo and Video Standards in the Operation Manual.

Request mode

POST

Request URL

http://ip:port/identity/image_verification/stateless

Request parameters

Name

Type

Required

Description

first_encrypted_image

string

Yes

Encrypted photo 1. Encryption method reference:

second_encrypted_image

string

Yes

Encrypted photo 2. Encryption method reference:

auto_rotate

boolean

No

The default value is false, indicating that the photo is not rotated. When the value is true, the photo is automatically rotated.

check_quality

boolean

No

The default value is false, and no quality test is performed. When the value is true, the photo quality is checked.

Normal response

Name

Type

Instructions

code

int

System response code: 1000

verification_score

float

The face comparison score is from 0-1. The greater the value, the greater the probability that the two faces belong to the same person.

request_id

string

The ID of this request

{
    "code": 1000,
    "verification_score": float,
    "request_id": string
}

Correlations between the verification score threshold and the error rate:

Threshold

0.4

0.5

0.6

0.7

0.8

0.9

error rate

1/10

1/100

1/1000

1/10,000

1/100,000

1/1,000,000

Recommended threshold: greater than 0.7.

Abnormal response

Name

Type

Instructions

code

int

System response code

message

string

Error Messages

request_id

string

The ID of this request

{
    "code": int,
    "message": string,
    "request_id": string
}

System response code

code

Field value

Description

1200

invalid argument

Invalid input parameter

2003

invalid image size

The image size (height and width in pixel) does not meet the requirements

2004

invalid content length

The image file size does not meet the requirements

2005

invalid image type or corrupted

The image type does not meet the requirements

4000

detection failed

Feature extraction failed, no face detected in the image

4004

face occlusion

Face detected but partially obscured by eyes, nose, or mouth

Possible HTTP status codes

status

Description

400

BAD_REQUEST

404

NOT_FOUND

411

LENGTH_REQUIRED

413

PAYLOAD_TOO_LARGE

500

INTERNAL_ERROR

Sample

Curl

curl -X POST "http://ip:port/identity/image_verification/stateless" \
  -d first_encrypted_image=xxx \
  -d second_encrypted_image=xxx \
  -d auto_rotate=true

Java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClient {
    public static final String POST_URL = "http://127.0.0.1:3000/identity/image_verification/stateless";
    private static AESCipher cipher = new AESCipher("dcbbad6765e14139a07d34b92292a672", "df25d188a061");

    public static void Post() throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost(POST_URL);

        List<NameValuePair> params = new ArrayList<>();

        String firstEncryptedImage = cipher.encrypt(
                Files.readAllBytes(Paths.get("src/main/resources/face_01.jpg")));
        String secondEncryptedImage = cipher.encrypt(
                Files.readAllBytes(Paths.get("src/main/resources/face_02.jpg")));

        params.add(new BasicNameValuePair("first_encrypted_image", firstEncryptedImage));
        params.add(new BasicNameValuePair("second_encrypted_image", secondEncryptedImage));

        post.setEntity(new UrlEncodedFormEntity(params));
        HttpResponse response = httpclient.execute(post);

        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity respEntity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(respEntity.getContent()));
            String line = reader.readLine();
            System.out.println(line);
        } else {
            HttpEntity respEntity = response.getEntity();
            String responseString = EntityUtils.toString(respEntity);
            System.out.println("error:" + response.getStatusLine().getStatusCode()
                    + "  " + response.getStatusLine().getReasonPhrase());
            System.out.println("cause of error:"+responseString);
        }
    }

    public static void main(String[] args) throws Exception {
        Post();
    }
}
[Photo and Video Encryption]
[Photo and Video Encryption]

2 Photo and Video Encryption

This page describes the photo and video encryption method for using the SenseID API.

2.1 Customize the encryption key and IV

SenseID requires that personal data (photos and videos) must be encrypted before being uploaded via APIs. AES-256-GCM is adopted as the encryption algorithm. The key and IV required for encryption are set as follows by default.

PARAM_DECRYPT_KEY = dcbbad6765e14139a07d34b92292a672
PARAM_DECRYPT_IV = df25d188a061

To customize the key and the IV, update the environment variables PARAM_DECRYPT_KEY and PARAM_DECRYPT_IV. The key is 32 characters and the IV is 12 characters.

$ cd 1v1-private-cloud-v1.8/
$ vi .env

2.2 Encryption method

  1. Load the photo or video file.

  2. Encrypt the data with AES-256-GCM.

  3. Encode the above result with Base64.

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.util.Base64;


public class AESCipher {
    private String key;
    private String iv;

    public AESCipher(String key, String iv) {
        this.key = key;
        this.iv = iv;
    }

    String encrypt(byte[] data) throws Exception{
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(Charset.forName("UTF-8")), "AES");
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, new GCMParameterSpec(128, iv.getBytes(Charset.forName("UTF-8"))));
        byte[] result = cipher.doFinal(data);
        return Base64.getEncoder().encodeToString(result);
    }

    byte[] decrypt(String data) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(Charset.forName("UTF-8")), "AES");
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, new GCMParameterSpec(128, iv.getBytes(Charset.forName("UTF-8"))));
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(data));
        return result;
    }

    public static void main(String[] args) throws Exception{
        String key = "dcbbad6765e14139a07d34b92292a672"; //key 32 bits
        String iv = "df25d188a061"; // iv 12 bits
        String data = "hello world";

        AESCipher cipher = new AESCipher(key, iv);
        String encryptedData = cipher.encrypt(data.getBytes());
        System.out.println("encrypted data: " + encryptedData);

        String decryptedData = new String(cipher.decrypt(encryptedData));
        System.out.println("decrypted data: " + decryptedData);
    }
}

1 License Change and Renew

This page describes how to change or renew the license of Sense ID.

To change or renew the license files, overwrite the new license files from the old licenses file and place them in the specified directories. Refer to Chapter 3 License Activation in the Installation Manual for details.

After replacing the license files, restart the service.

$ cd 1v1-private-cloud-v1.8/go-worker
$ sudo ./stop.sh
$ sudo ./start.sh

1.2 /identity/multiface_image_omni_verification/stateless

Compare the two photos with multiple faces included and uploaded through the interface to get the similarity score of each pair of faces in the two photos.

For photo standards, refer to Chapter 3 Photo and Video Standards in the Operation Manual.

Request mode

POST

Request URL

http://ip:port/identity/multiface_image_omni_verification/stateless

Request parameters

Name

Type

Required

Description

first_encrypted_image

string

Yes

Encrypted photo 1. Encryption method reference:

second_encrypted_image

string

Yes

Encrypted photo 2. Encryption method reference:

auto_rotate

boolean

No

The default value is false, indicating that the photo is not rotated. When the value is true, the photo is automatically rotated.

Normal response

Name

Type

Description

code

int

System response code: 1000

scores

array

The face comparison score of each group of photos

is from 0-1. The greater the value, the greater the probability that the two faces belong to the same person.

face_rects

hash

Face frame in each photo

request_id

string

The ID of this request

For example:

Suppose that Photo A corresponding to first_image_file contains two faces (a1, a2); Photo B corresponding to second_image_file contains two faces (b1, b2); a1b1 represents the comparison score of face a1 in Photo A and face b1 in Photo B. The response is like:

{
    "code": 1000,
    "scores": [ # [[a1b1 face comparison score, a1b2 face comparison score] [a2b1 face comparison score, a2b2 face comparison score]]
        [
            float,
            float,
            float,
            float
        ]
    ],
    "face_rects": { # face frame in each image
        "first_image_face_rects": [ # [[a1 face frame coordinates],[a2 face frame coordinates]]
            [
                int,
                int,
                int,
                int
            ],
            [
                int,
                int,
                int,
                int
            ]
        ],
        "second_image_face_rects": [ # [[b1 face frame coordinates],[b2 face frame coordinates]]
            [
                int,
                int,
                int,
                int
            ],
            [
                int,
                int,
                int,
                int
            ]
        ]
    },
    "request_id": "2c4156bb47794f66a2ed50d5a87e5ca2"
}

Correlations between the verification score threshold and the error rate:

Threshold

0.4

0.5

0.6

0.7

0.8

0.9

error rate

1/10

1/100

1/1000

1/10,000

1/100,000

1/1,000,000

Recommended threshold: greater than 0.7.

Abnormal response

Name

Type

Description

code

int

System response code

message

string

Error Messages

request_id

string

The ID of this request

{
    "code": int,
    "message": string,
    "request_id": string
}

System response code

code

Field value

Description

1200

invalid argument

Invalid input parameter

2003

invalid image size

The image size (height and width in pixel) does not meet the requirements

2004

invalid content length

The image file size does not meet the requirements

2005

invalid image type or corrupted

The image type does not meet the requirements

2006

corrupted image error

Image corrupted

4000

detection failed

Feature extraction failed, no face detected in the image

Possible HTTP status codes

status

Description

400

BAD_REQUEST

404

NOT_FOUND

411

LENGTH_REQUIRED

413

PAYLOAD_TOO_LARGE

500

INTERNAL_ERROR

Sample

Curl

curl -X POST "http://ip:port/identity/multiface_image_omni_verification/stateless" \
  -d first_encrypted_image=xxx \
  -d second_encrypted_image=xxx \
  -d auto_rotate=true

Java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClient {
    public static final String POST_URL = "http://127.0.0.1:3000/identity/multiface_image_omni_verification/stateless";
    private static AESCipher cipher = new AESCipher("dcbbad6765e14139a07d34b92292a672", "df25d188a061");

    public static void Post() throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost post = new HttpPost(POST_URL);

        List<NameValuePair> params = new ArrayList<>();

        String firstEncryptedImage = cipher.encrypt(
                Files.readAllBytes(Paths.get("src/main/resources/face_01.jpg")));
        String secondEncryptedImage = cipher.encrypt(
                Files.readAllBytes(Paths.get("src/main/resources/face_02.jpg")));

        params.add(new BasicNameValuePair("first_encrypted_image", firstEncryptedImage));
        params.add(new BasicNameValuePair("second_encrypted_image", secondEncryptedImage));

        post.setEntity(new UrlEncodedFormEntity(params));
        HttpResponse response = httpclient.execute(post);

        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity respEntity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(respEntity.getContent()));
            String line = reader.readLine();
            System.out.println(line);
        } else {
            HttpEntity respEntity = response.getEntity();
            String responseString = EntityUtils.toString(respEntity);
            System.out.println("error:" + response.getStatusLine().getStatusCode()
                    + "  " + response.getStatusLine().getReasonPhrase());
            System.out.println("cause of error:" +responseString);
        }
    }

    public static void main(String[] args) throws Exception {
        Post();
    }
}
[Photo and Video Encryption]
[Photo and Video Encryption]