Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
まず、マシンで対応している命令セットを確認します。
cat /proc/cpuinfo コマンドを実行します。
フラグを確認します。
AVX と AVX2 の組み合わせが含まれていない場合は、CPU 命令セットが AVX 命令セットをサポートしていないことを示します。
解決方法は 2 通りあります。
1) AVX 命令セットが含まれるマシンに変更します。
2) 現在のマシンで、強制的にSSE 命令セットが使用されるようにします。ただし、サービスの性能は低下し、処理スピードは半減します。
強制的に SSE 命令セットが使用されるようにするには、go-workers の env ファイルを開き、FORCE_SET_SSE=false を FORCE_SET_SSE=true に変更します。
注意事項: 変更後、保存してから、go-workers サービスを再起動します。サービスを再起動する方法は以下のとおりです。
まず ./stop/sh を実行してから、./start.sh を実行します。
./start.sh を複数回実行するなど、展開中に開始コマンド (./start.sh) が繰り返し呼び出される場合、またはポートが使用されている場合、ログを確認すると次のエラーが発生していました。注意事項: go-workers または go-cloud-api を開始する際は、対応する ./start.sh を一度だけ開始してください。
1) 下記のコマンドを実行します。
2) ./tool/supervisord -c config/supervisor.conf -dに対応するプロセス番号を強制終了します。
弊社が提供する「プライベートクラウドパッケージ」には、デフォルトでライセンスが含まれていませんので、ライセンスの詳細な利用方法については、を参照してください。
1)panic: bad license: -1
ライセンスが壊れている(空のライセンスなど)ので、再度ライセンスファイルを差し替えてください。
2) panic: open fixture/license/senseid_ocr/senseid_ocr.lic: no such file or directory
ライセンスがインポートされていないということですので、指定したフォルダにライセンスファイルをインポートしてください。
3)panic: bad license: -16
udid mismatchと表示され、ライセンスにバインドされているハードウェアの指紋と現在のデバイスのハードウェアの指紋が一致していません。デバイスのハードウェア情報が変更されていないことを確認してください。
デバイスのUUIDが変更されていることを確認したら、新しいライセンスを申請できる事業者に新しいUUIDを提供して、新しいライセンスを忘れずに交換してください。
主にモデルファイルに関連したファイル形式が間違っていることを意味します。
例えば、WINDOWS システムの解凍ソフトを使用して、「プライベートクラウドパッケージ」を解凍してサーバーにアップロードすると、モデルファイルの一部が破損する可能性があります。お客様は、インストールパッケージをサーバに再アップロードし、コマンドラインで解凍することをお勧めします。
listen: listen tcp :50050: bind: address already in useps aux | grep supervisordkill -9 PIDJCV の SenseID 認証プライベートクラウドサービスをご利用いただき、ありがとうございます。
当マニュアルでは、プライベートクラウドサービスの使用方法の詳細について説明いたします。プライベートクラウドサービスの導入を成功させるために、導入作業を開始する前に、当マニュアルをよくお読みください。
当マニュアルで記載されているプライベートクラウドの展開サービスの使用プロセスについて、次の図で詳細に説明します。
当マニュアルでは、プライベートクラウドを認証するための展開方法について、主にインストール、設定、重要なサービスの起動、また発生する可能性のある問題とその解決策について詳しく説明しています。
プライベートクラウドを展開する前に、運用および保守担当者はこのマニュアルを注意深くお読みください。
推奨されるマシン構成は、ubuntu 18.04のOSです。ハードウェアに関しては、クアッドコアまたはそれ以上の CPU、8GM 以上の RAM、そして 100GB 以上のディスク容量があることを推奨します。
注意事項: 命令セットには、AVX が必要です。
ruby-cloud-api: クライアントから呼び出される主要なインタフェースを含むHTTP サービス。
go-workers: バックエンドのコンピューティングサービス。主にアルゴリズムをカプセル化してあり、ruby-cloud-api に対して HTTP 形式で提供されます。
プライベートクラウドのライセンスファイルはメールに添付されて提供されます。プライベートクラウドを展開する前に、ライセンスファイルの名前を変更して、対応するディレクトリに配置する必要があります。
ライセンス数とタイプは、開くように設定されているさまざまなインターフェースによって異なる場合があります。詳細については「」をご参照ください。
展開パッケージ名: 1v1-private-cloud.tgz
o 注意事項: 必ず Linux 上で解凍するようにしてください。Windows 上でパッケージを解凍した場合、動的リンクライブラリのソフトリンク障害が発生します。
ストラクチャは次のとおりです。
(ライセンスにより) デバイスを紐づけるする必要があるため、go-workers の Dockerイメージは展開に使用できません。
ruby-cloud-api.tar は、対応するサービスの Docker イメージです。展開には、docker-compose を使用できます。
このサービスは主要なコンピューティングサービスであるため、できれば専用のサーバーリソースを割り当てます。
注意事項: まずは、マシンの物理 CPU コア数を確認する必要があります。物理 CPU コア情報を取得するコマンドは以下のとおりです。
env ファイルを開き、CONCURRENT の値を物理 CPU コア数に設定し、保存します。
注意事項:
CONCURRENTには、マシンの物理 CPU コア数を超える値を設定することはできません。CONCURRENT値が大きいほど、サービスの同時実行数が高くなり、メモリと CPU の消費量が多くなります。
開始前に、ライセンスが置き換えられていることを確認します。
なお、展開ディレクトリ内に停止スクリプトも用意されています。
注意事項: tail コマンドの実行結果にポート番号 50050 の Server Listen が含まれている場合、サービスが正常に開始されたことを示します。
正常に展開された場合の実行結果の例は以下のとおりです (サービスが正常に開始したことを示しています)。
以下のサービスのデプロイはDockerに依存しますので、ご自身でDockerをインストールしてください。
実行結果は以下のとおりです。
.env ファイルを開きます。
最終行の WORKER_IP 値を修正し、go-workers サービスが展開されているマシンの IP アドレスを設定します。保存後、ファイルを閉じます。
IP アドレスの取得コマンド:
結果は以下のとおりです。
結果は以下のとおりです。
ここまでにサービスが展開されています。
返されるサンプルは次のとおりです。展開が正常である場合(サービスが正常に開始されたことを証明します):
こちらの節に記載しているサービスはサーバー内部で動作するものの為、認証情報を変更することはできません。安全に使用して頂けれる為に、安全なAPIメカニズム、認証メカニズム、通信、DNSをSenseID外部に実装することを強く推奨します。
サービスポート: 50050
サービスポート: 3000
インターフェース定義: 詳細については、インターフェースファイルをご参照ください。
Ubuntu (16.04)、debian (9)、centos (7)、redhat (7.0)
ディスクスペース要件
100GB 以上
構成項目
構成要件
最小の OS カーネルバージョン
バージョン 3.2.0 以上
CPU モデル
x86_64
CPU コア数の要件
クアッドコア以上
CPU 命令セット
SSE、AVX、FMA のいずれか。互換性: SSE > AVX > FMA。動作速度: FMA > AVX > SSE。
RAM 要件
8GB 以上
サポートされる OS の種類および最小バージョン
$ tar -xvzf 1v1-private-cloud.tgz$ cd 1v1-private-cloud$ ls -a.
├── .env
├── docker-compose
├── load_image.sh
├── docker-compose.yml
├── docs
├── go-workers
└── ruby-cloud-api.tar$ cd go-workers$ echo Cores=$(($(lscpu | awk '/^Socket/{print $2}') * $(lscpu | awk '/^Core/{print $4}')))$ vim .env$ ./start.sh$ ./stop.sh$ tail -f tmp/worker.log.0$ curl 127.0.0.1:50050/healthcheck{"request_id":"07a41c21822e4223a373e77bfc186ed2","status":"ok"}$ ./load_image.shLoaded image: registry.sensetime.com/senseid-cloudv2/ruby-cloud-api:v1.0.0$ vi .env$ hostname -I | cut -d' ' -f1$ docker-compose up -dCreating network "senseid-private-cloud-yyyymmdd_default" with the default driver
Creating senseid-private-cloud-yyyymmdd_ruby-cloud-api_1 ... done$ docker-compose ps Name Command State Ports
-----------------------------------------------------------------------------------------------------------------------------
senseid-private-cloud-20191225_ruby-cloud-api_1 ./entrypoint.sh start Up (healthy) 0.0.0.0:3000->3000/tcp$ curl 127.0.0.1:3000/healthcheck{"code":1000,"status":"ok"}ユーザーがアップロードした個人データは暗号化する必要があります。暗号化アルゴリズムは AES-256-CBC を使用します。暗号化に必要なキーおよび IV は、デフォルトの設定では以下のとおりです。
key = dcbbad6765e14139a07d34b92292a672
iv = df25d188a061変更する場合は、環境変数 PARAM_DECRYPT_KEY および PARAM_DECRYPT_IV を更新します。キーは 32 文字で、IV は 12 文字です。
人物の画像ファイルまたはその他の個人データを読み取ります。
AES-256-CBC でデータを暗号化します。
Base64 で上記の結果を暗号化します。
デプロイターゲットのデバイスの UDIDを取得します。
UDID取得ツールのファイル名称は、SenseIDPrivateCloud-UDIDGetter-V4.1.0.zipです。
お使いのデバイスに対応するプロセッサープラットフォームのディレクトリへ移動します。
例: cd SenseIDPrivateCloud-UDIDGetter-V4.1.0/
標準的な使い方:
コマンドラインで ./UDIDGetter.sh o を実行します。
出力された UDID.txt ファイルをメールで担当者に送付します。
Linux で使用する場合は、必ず Linux 上で ZIP ファイルを解凍するようにしてください。Linux 以外で解凍したd場合、ソフトリンクの障害が原因で、プログラムの実行が失敗する可能性があります。
エラー: save udid to file error, code -1の場合, sudo ./UDIDGetter.shを実行してください。
本章では、必要に応じて参考にできるように、JCV 認証クラウドサービスで提供されるすべての API に関する手順について詳細に説明します。 API の説明には、関数の紹介、パラメーター、出力結果、エラーメッセージなどが含まれます。
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);
}
}ライセンスファイルのアクティベーションは、UUID に紐づける形で実行されます。異なるインターフェースを開くように設定している場合、対応するライセンスファイルも異なります。1 つのインターフェースは、1-2 つのライセンスファイルに対応します。プライベートクラウドを展開する前に、ライセンスファイルの名前を変更して、指定ディレクトリに配置する必要があります。
プライベートクラウドのライセンスファイルは、メールに添付されて提供されます。すべてのインターフェースを開くためには、対応する2つのライセンスファイルをそれぞれアクティベーションする必要があります。詳細については、次の手順を参照してください。
SENSEID\_FACE\_xxx.lic ファイルの名前をsenseid\_face.licに変更
SENSEID\_LIVENESS\_xxx.lic ファイルの名前を senseid\_liveness.licに変更
ライセンスディレクトリへ移動します。
ls licenseを実行します。次の 3つのフォルダーが表示されます。
※本製品ではsenseid_ocrはサポートされておりません。
注意事項: 実際には、このディレクトリのフォルダーに応じて、該当する名前が変更されたライセンスファイルを渡す必要があります。

上記の手順を実行後、サービスを再起動します (注意事項: サービスの開始後にライセンスを置き換えた場合は、サービスを再起動する必要があります)。
最初に実行: ./stop.sh
次に実行: ./start.shcd go-worker/fixture/license ├── senseid_face
└── senseid_liveness1) senseid_face.lic を senseid_face フォルダーに移動して、以前のライセンスを上書き
2) senseid_liveness.lic を senseid_liveness フォルダーに移動して、以前のライセンスを上書きインターフェースを介してアップロードされた顔画像と生体認証データを比較して、画像内の顔が同一人物のものであるかどうかを判断します。
画像は、以下の要件を満たすものとします。
JPG (JPEG)、BMP、PNG、GIF、TIFF のいずれかの形式
幅と高さは 8 px 以上 5,000 px 以下
ファイルサイズは 5 MB 以下
POST
顔比較スコアの閾値とエラー率との対応関係:
推奨閾値: 0.7 以上
システムレスポンスコードの説明
可能性のある http ステータスコード:
比較対象の顔画像に複数の顔が含まれる場合に、 2 つの画像に含まれる顔の各グループの類似度スコアを返します。
顔画像は、以下の要件を満たすものとします。
JPG (JPEG)、BMP、PNG、GIF、TIFF のいずれかの形式
幅と高さは 8 px 以上 5,000 px 以下
ファイルサイズは 5 MB 以下
No
デフォルト値は false で、画像が回転していないことを示します。値が true の場合、画像は自動的に回転されます。
check_quality
boolean
No
デフォルト値が false の場合は品質チェックを行わず、true の場合は画像の品質チェックを行います。
画像タイプが要件を満たしていません
2006
corrupted image error
画像が破損しています
4000
detection failed
特徴の抽出に失敗しました。画像に顔が検出されませんでした
4004
face occlusion
顔は検出されたが、目、鼻、口が部分的に見えないです
フィールド
型
必須
説明
liveness_file
File
Yes
インタラクティブ・ライブネスまたはサイレント・ライブネスSDKによる検出に成功した後に返された暗号化されたバイナリ・ストリーム・ファイル(i.e. protobufData)です。別途の暗号化を必要とせずに既に暗号化されています。
encrypted_image
String
Yes
暗号化された画像 。暗号化方法の参照: 個人データの暗号化
auto_rotate
フィールド
型
説明
request_id
string
このリクエストのID
code
int
システムレスポンスコード: 1000
verification_score
float
顔照合スコア、値0~1、値が高いほど同一人物である可能性が高いことです。
閾値
0.4
0.5
0.6
0.7
0.8
0.9
エラー率
1/10
1/100
1/1000
1/10,000
1/100,000
1/1,000,000
フィールド
型
説明
request_id
string
このリクエストのID
code
int
システムレスポンスコード
message
string
エラーメッセージ
コード
フィールドの値
説明
1200
invalid argument
無効な入力パラメーター
2003
invalid image size
画像サイズが要件を満たしていません
2004
invalid content length
画像コンテンツの長さが要件を満たしていません
2005
ステータスコード
ステータスフィールド
400
BAD_REQUEST
404
NOT_FOUND
411
LENGTH_REQUIRED
413
PAYLOAD_TOO_LARGE
500
INTERNAL_ERROR
boolean
invalid image type
http://ip:port/identity/liveness_image_verification/stateless{
'request_id': 'xxx',
'code': xxx,
'verification_score': xxx
}{
'request_id': 'xxx',
'code': xxx,
'message': xxx
}curl -X POST "http://ip:port/identity/liveness_image_verification/stateless" \
-F liveness_file=@/PATH/TO/FILE \
-d encrypted_image=xxx \
-d auto_rotate=trueimport 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();
}
}POST
フィールド
型
必須
説明
first_encrypted_image
String
Yes
暗号化された画像 1。暗号化方法の参照:
second_encrypted_image
String
Yes
暗号化された画像 2。暗号化方法の参照:
auto_rotate
フィールド
型
説明
request_id
string
このリクエストのID
code
int
システムレスポンスコード: 1000
scores
array
画像の各グループの顔のスコアの比較。推奨閾値: 0.7〜0.8
face_rects
例:
first_image_file に相当する図 A に 2 つの顔 (a1、a2) が含まれていて、second_image_file に相当する 図 B にも 2 つの顔 (b1、b2) が含まれているとします。a1b1 などの値は、図 A に含まれる顔 a1 と図 B に含まれる顔 b1 の比較スコアを表します。
顔比較スコアの閾値とエラー率との対応関係:
閾値
0.4
0.5
0.6
0.7
0.8
0.9
エラー率
1/10
1/100
1/1000
1/10,000
1/100,000
1/1,000,000
推奨閾値: 0.7 以上
フィールド
型
説明
request_id
string
このリクエストのID
code
int
システムレスポンスコード
message
string
エラーメッセージ
システムレスポンスコードの説明
コード
フィールドの値
説明
1200
invalid argument
無効な入力パラメーター
2003
invalid image size
画像サイズが要件を満たしていません
2004
invalid content length
画像コンテンツの長さが要件を満たしていません
2005
可能性のある http ステータスコード:
ステータスコード
ステータスフィールド
400
BAD_REQUEST
404
NOT_FOUND
411
LENGTH_REQUIRED
413
PAYLOAD_TOO_LARGE
500
INTERNAL_ERROR
インターフェースを介してアップロードされた 2 つの顔画像を比較して、2 つの顔が同一人物のものかどうかを判断します。
画像は、以下の要件を満たすものとします。
JPG (JPEG)、BMP、PNG、GIF、TIFF のいずれかの形式
幅と高さは 8 px 以上 5,000 px 以下
ファイルサイズは 5 MB 以下
http://ip:port/identity/multiface_image_omni_verification/stateless{
'code: Int, # システムレスポンスコード
'scores': array, # [[a1b1 顔比較スコア, a1b2 顔比較スコア], [a2b1 顔比較スコア, a2b2 顔比較スコア]]
"face_rects":{ hash,# 各画像の顔枠
'first_image_face_rects':[a1 顔枠の座標], [a2 顔枠の座標]],
'second_image_face_rects,:[[b1 顔枠の座標],[b2 顔枠の座標]]
},
'request_id': string # このリクエストのID
}{
'request_id': string,
'code': int,
'message': string
}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=trueimport 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();
}
}boolean
No
デフォルト値は false で、画像が回転していないことを示します。値が true の場合、画像は自動的に回転されます。
hash
各画像の顔の顔枠
request_id
string
リクエスト番号
invalid image type
画像タイプが要件を満たしていません
2006
corrupted image error
画像が破損しています
4000
detection failed
特徴の抽出に失敗しました。画像に顔が検出されませんでした
No
選出されたフレーム画像の顔のクロップを返すかどうか。 デフォルト値は false で、値が true かつ生体認証が通過した場合に base64_face_imageフィールドは返されます
return_status
boolean
No
エラーステータスの説明を返すかどうかを指定します。デフォルトはfalseで、値がtrueの場合にのみliveness_status フィールドは返されます
サイレント生体認証のスコア(参考までに、結果はpassedフィールドを使用してください)
liveness_status
string
サイレントライブネス検出のエラー状態を記述します。このフィールドは、return_status=true の時に返されます
image_timestamp
float
選出されたフレームのタイムスタンプを秒単位で表し、passed=true、return_image=trueの場合に返されます
base64_image
string
選出されたフレーム画像、passed=true、return_image=trueの場合は該当フィールドを返します
base64_face_image
string
選出された顔写真の切り抜き、passed=true、return_face_image=trueの場合に返されます
サイレント生体認証は合格してない、理由: 動画の途中で顔が入れ替わっていました
face_occlusion
サイレント生体認証は合格してない、理由: 一定期間顔が見えなくなる
フィールド
型
必須
説明
encrypted_video
String
Yes
暗号化された動画。暗号化方法の参照: 個人データの暗号化
return_image
boolean
No
選出されたフレーム画像と選出されたフレーム画像のタイムスタンプを返すかどうか。 デフォルト値は false で、値が true かつ生体認証が通過した場合に image_timestamp, base64_image フィールドが返されます
return_face_image
フィールド
型
説明
request_id
string
リクエストのID
code
int
システムレスポンスコード: 1000
passed
boolean
生体認証に通過したかどうか
liveness_score
ステータス
説明
ok
サイレント生体認証は合格した: 動画の中の人は実在する
hack
サイレント生体認証は合格してない、理由: 捏造した顔 (例えば, ビデオで撮影された顔)
short_time
サイレント生体認証は合格してない、理由: ビデオの持続時間は2s未満
no_face_detected
サイレント生体認証は合格してない、理由: 映像から顔は検出されません
loss_tracking
サイレント生体認証は合格してない、理由: 途中で顔がフレームアウト
フィールド
型
説明
request_id
string
リクエストのID
code
int
システムレスポンスコード
message
string
エラーメッセージ
コード
フィールドの値
説明
1200
invalid argument
無効な入力パラメーター
2008
invalid video error
無効な動画
4007
liveness silent check failed
サイレント生体認証失敗
ステータスコード
ステータスフィールド
400
BAD_REQUEST
404
NOT_FOUND
411
LENGTH_REQUIRED
413
PAYLOAD_TOO_LARGE
500
INTERNAL_ERROR
boolean
float
face_changed
画像タイプが要件を満たしていません
2006
corrupted image error
画像が破損しています
4000
detection failed
特徴の抽出に失敗しました。画像に顔が検出されませんでした。
フィールド
型
必須
説明
encrypted_image
String
Yes
暗号化された画像 。暗号化方法の参照: 個人データの暗号化
フィールド
型
説明
request_id
string
このリクエストのID
code
int
システムレスポンスコード: 1000
faces
Array
写真に写っている各顔のクオリティーについての情報
フィールド
型
説明
request_id
string
リクエストのID
code
int
システムレスポンスコード
message
string
エラーメッセージ
コード
フィールドの値
説明
1200
invalid argument
無効な入力パラメーター
2003
invalid image size
画像サイズが要件を満たしていません
2004
invalid content length
画像ボリュームが要件を満たしていません
2005
ステータスコード
ステータスフィールド
400
BAD_REQUEST
404
NOT_FOUND
411
LENGTH_REQUIRED
413
PAYLOAD_TOO_LARGE
500
INTERNAL_ERROR
invalid image type
http://ip:port/liveness/silent_detection/stateless{
"request_id": string,
"code": int,
"passed": boolean,
"liveness_score": float,
"liveness_status": string,
"image_timestamp": float,
"base64_image": string,
"base64_face_image": string,
}{
'request_id': 'xxx',
'code': xxx,
'message': xxx
}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=trueimport 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();
}
}http://ip:port/quality/face/stateless{
"code": integer, # システム応答コード. 1000
"faces":[
{
"rect": { # 顔枠の位置
"left": integer, # 顔枠の左端の水平座標、画像の左上を原点とする
"top": integer, # 顔枠の上枠の垂直座標、画像の左上隅を原点とする
"right": integer, # 顔枠の右端の水平座標、画像の左上隅を原点とする
"bottom": integer # 顔枠の下枠の垂直座標、画像の左上を原点とする
},
"pose": { # ポーズ角度情報
"yaw": float, # Y 軸角度を示します
"pitch": float, # X 軸角度を示します
"roll": float # Z 軸角度を示します
},
"occlusion":{ # 遮られる情報
"left_eye": float, # 左目が遮られていない割合, 値 [0,1], 値が大きいほど遮られていない
"right_eye": float, # 右目が遮られていない割合, 値 [0,1], 値が大きいほど遮られていない
"nose": float, # 鼻の遮られていない割合、値 [0,1]、値が大きいほど遮られていない
"mouth": float, # 口の遮られていない割合、値 [0,1]、値が大きいほど遮られていない
"total": float # 顔の遮られていない総合割合、値 [0,1]、値が大きいほど遮られていない
},
"distance2center": float, # 顔から画像の中心までの距離、範囲 [0,1] で、スコアが高いほど、顔が画像の中心に近いことを表します。計算方法:max(1 - 五官中心から画像中心への距離 / 画像の短辺の距離, 0)
"size": float, # 顔が画像に面積の割合、範囲 [0,1] で、スコアが高いほど、顔の面積割合が大きいことを表します。計算方法:五官が画像に占める面積 / 画像の面積
"brightness": float, # 顔の明るさのスコア, 範囲は [-1,1] で, スコアが高いほど明るさが高いことを表します
"sharpness": float, # 鮮明度スコア, 値の範囲 [0,1], スコアが高いほど鮮明になります
"mouth_open": float, # 口の開き具合, [0,1]の範囲内の値, スコアが高いほど口の開き具合が低くなります
"integrity": float # 画像中の顔の完全性, 値の範囲 [0,1], スコアが高いほど画像中の顔が完全である、計算式: 画像中の顔の面積 / 顔の面積
},
...
],
"request_id": string # リクエストのID
}{
'request_id': 'xxx',
'code': xxx,
'message': xxx
}curl -X POST "http://ip:port/quality/face/stateless" \
-d encrypted_image=xxximport 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();
}
}POST
フィールド
型
必須
説明
first_encrypted_image
String
Yes
暗号化された画像 1。暗号化方法の参照:
second_encrypted_image
String
Yes
暗号化された画像 2。暗号化方法の参照:
auto_rotate
フィールド
型
説明
request_id
string
このリクエストのID
code
int
システムレスポンスコード: 1000
verification_score
float
顔比較スコア、範囲: 0~1 。値が大きいほど、2 つの顔が同じ人物のものである確率が高くなります。
顔比較スコアの閾値とエラー率との対応関係:
閾値
0.4
0.5
0.6
0.7
0.8
0.9
エラー率
1/10
1/100
1/1000
1/10,000
1/100,000
1/1,000,000
推奨閾値: 0.7 以上
フィールド
型
説明
request_id
string
このリクエストのID
code
int
システムレスポンスコード
message
string
エラーメッセージ
システムレスポンスコードの説明
コード
フィールドの値
説明
1200
invalid argument
無効な入力パラメーター
2003
invalid image size
画像サイズが要件を満たしていません
2004
invalid content length
画像ボリュームが要件を満たしていません
2005
可能性のある http ステータスコード:
ステータスコード
ステータスフィールド
400
BAD_REQUEST
404
NOT_FOUND
411
LENGTH_REQUIRED
413
PAYLOAD_TOO_LARGE
500
INTERNAL_ERROR
http://ip:port/identity/image_verification/stateless{
'request_id': 'xxx',
'code': xxx,
'verification_score': xxx
}{
'request_id': 'xxx',
'code': xxx,
'message': xxx
}curl -X POST "http://ip:port/identity/image_verification/stateless" \
-d first_encrypted_image=xxx \
-d second_encrypted_image=xxx \
-d auto_rotate=trueimport 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();
}
}boolean
No
デフォルト値は false で、画像が回転していないことを示します。値が true の場合、画像は自動的に回転されます。
check_quality
boolean
No
デフォルト値は false で、画質テストは行われません。値がtrueの場合、画質のテストが行われます。
invalid image type
画像タイプが要件を満たしていません
2006
corrupted image error
画像が破損しています
4000
detection failed
特徴の抽出に失敗しました。画像に顔が検出されませんでした。
4004
face occlusion
顔は検出されたが、目、鼻、口で部分的に見えなくなっています。
このAPIは、サイレント生体認証結果と自撮りの顔写真を比較に利用されています。
POST
一般的なビデオフォーマットはサポートされています。例えば: .mp4, .avi, .flv, .wmv, .mov, .rm
顔画像は、以下の要件を満たすものとします。
JPG (JPEG)、BMP、PNG、GIF、TIFF のいずれかの形式
幅と高さは 8 px 以上 5,000 px 以下
ファイルサイズは 5 MB 以下
ここで、liveness_statusの結果は以下のようになる:
顔比較スコアの閾値とエラー率との対応関係:
推奨閾値: 0.7 以上
システムレスポンスコードの説明
可能性のある http ステータスコード:
No
デフォルト値は false で、画像が回転していないことを示します。値が true の場合、画像は自動的に回転されます
check_quality
boolean
No
デフォルト値が false の場合は品質チェックを行わず、true の場合は画像の品質チェックを行います
return_image
boolean
No
選出されたフレーム画像と選出されたフレーム画像のタイムスタンプを返すかどうか。 デフォルト値は false で、値が true かつ生体認証が通過した場合に image_timestamp, base64_image フィールドが返されます
return_face_image
boolean
No
選出されたフレーム画像の顔のクロップを返すかどうか。 デフォルト値は false で、値が true かつ生体認証が通過した場合に base64_face_imageフィールドは返されます
return_status
boolean
No
エラーステータスの説明を返すかどうかを指定します。デフォルトはfalseです; liveness_status フィールドは値がtrueの場合にのみ返されます
サイレント生体認証のスコア(参考までに、結果はpassedフィールドを使用してください)
liveness_status
string
サイレントライブネス検出のエラー状態を記述します。このフィールドは、return_status=true の時に返されます
verification_score
float
顔照合スコア、おすすめの閾値: > 0.7。このフィールドはpassed=trueの場合に返されます
image_timestamp
float
選出されたフレームのタイムスタンプを秒単位で表し、passed=true、return_image=trueの場合に返されます
base64_image
string
選出されたフレーム画像、passed=true、return_image=trueの場合は該当フィールドを返します
base64_face_image
string
選出された顔写真の切り抜き、passed=true、return_face_image=trueの場合に返されます
サイレント生体認証は合格してない、理由: 動画の途中で顔が入れ替わっていました
face_occlusion
サイレント生体認証は合格してない、理由: 一定期間顔が見えなくなる
画像タイプが要件を満たしていません
2006
corrupted image error
画像が破損しています
4000
detection failed
特徴の抽出に失敗しました。画像に顔が検出されませんでした
4004
face occlusion
顔は検出されるが、目、鼻、口が部分的に見えないです
4007
liveness silent check failed
サイレント生体認証失敗
フィールド
型
必須
説明
encrypted_video
String
Yes
暗号化された動画。暗号化方法の参照: 個人データの暗号化
encrypted_image
String
Yes
暗号化された画像 。暗号化方法の参照: 個人データの暗号化
auto_rotate
フィールド
型
説明
request_id
string
このリクエストのID
code
int
システムレスポンスコード: 1000
passed
boolean
生体認証に通過したかどうか
liveness_score
ステータス
説明
ok
サイレント生体認証は合格した: 動画の中の人は実在する
hack
サイレント生体認証は合格してない、理由: 捏造した顔 (例えば, ビデオで撮影された顔)
short_time
サイレント生体認証は合格してない、理由: ビデオの持続時間は2s未満
no_face_detected
サイレント生体認証は合格してない、理由: 映像から顔は検出されません
loss_tracking
サイレント生体認証は合格してない、理由: 途中で顔がフレームアウト
閾値
0.4
0.5
0.6
0.7
0.8
0.9
エラー率
1/10
1/100
1/1000
1/10,000
1/100,000
1/1,000,000
フィールド
型
説明
request_id
string
このリクエストのID
code
int
システムレスポンスコード
message
string
エラーメッセージ
コード
フィールドの値
説明
1200
invalid argument
無効な入力パラメーター
2003
invalid image size
画像サイズが要件を満たしていません
2004
invalid content length
画像コンテンツの長さが要件を満たしていません
2005
ステータスコード
ステータスフィールド
400
BAD_REQUEST
404
NOT_FOUND
411
LENGTH_REQUIRED
413
PAYLOAD_TOO_LARGE
500
INTERNAL_ERROR
boolean
float
face_changed
invalid image type
http://ip:port/identity/silent_image_verification/stateless{
"request_id": string,
"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': 'xxx',
'code': xxx,
'message': xxx
}curl -X POST "http://ip:port/identity/silent_image_verification/stateless" \
-d encrypted_video=xxx \
-d encrypted_image=xxx \
-d auto_rotate=trueimport 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();
}
}