Only this pageAll pages
Powered by GitBook
1 of 27

1.8.0, 日本語, 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...

改訂履歴

日付

改訂内容

2021/08/20

  • 初版

改訂履歴

日付

改訂内容

2021/08/20

  • V1.8.0の内容を反映

  • 一部誤字脱字を修正

2021/03/08

  • 初版

リリースノート

SenseID 1v1のリリースノートをご確認いただけます。

日付

バージョン

改訂内容

2021/08/20

V1.8.0

  • 顔認証アルゴリズムを更新

  • エラーコードとAPIパラメータの説明を追加

  • 暗号化キーのカスタマイズ化機能を追加

2021/03/08

V1.7.0

  • 初版

APIマニュアル

SenseIDのAPI利用方法について記載されています。

本章では、必要に応じて参考にできるように、JCV顔認証サービスで提供されるすべてのAPIに関する手順について詳細に説明します。APIの説明には、機能の紹介、パラメーター、出力結果、エラーメッセージなどが含まれます。

1 システム環境設定の要件

SenseIDのシステム動作環境について記載しています。

1.1 システムについて

SenseIDの利用環境には、Ubuntu Server 18.04 LTSを推奨します。ハードウェア側では、クアッドコアまたはそれ以上のCPU、8GM以上のRAM、100GB以上のディスク容量を推奨します。なお、CPU命令セットにAVXが必要です。

構成項目

構成要件

最小のOSカーネルバージョン

バージョン3.2.0以上

1.2 サービスについて

この節に記載しているサービスはサーバー内部で動作するものです。安全に使用するためには安全なAPIメカニズム、認証メカニズム、通信、DNSをSenseID外部に実装することを強く推奨します。

Ruby-Cloud-APIとGo-Workersを別々の専用サーバーを利用することを推奨します。

  • Ruby-Cloud-API

    • クライアントから呼び出される主要なインターフェースを含む、HTTP サービス。

    • サービスポート:3000

  • Go-Workers

5 SenseIDの展開に関する FAQ

SenseIDのインストール中によく発生する問題について記載しています。

Q1.展開先マシンのバージョンが古く、命令セットが低レベル(または対応する命令セットに AVX 命令セットが含まれていない)な状態です。ログを取得し確認するために、”tail -f tmp/worker.log.0” コマンドを実行したところ、ログ内に "SIGILL: illegal instruction” と出てきてしまいました。この問題の解決方法を教えてください。

A1. まず、マシンで対応している命令セットを確認します。

  1. cat /proc/cpuinfo

改訂履歴

  • バックエンドのコンピューティングサービス。主にアルゴリズムをカプセル化してあり、Ruby-Cloud-APIに対してHTTP形式で提供されます。

  • サービスポート:50050

CPUモデル

x86_64

CPUコア数の要件

クアッドコア(4)以上

CPU命令セット

SSE、AVX、FMAのいずれか 互換性:SSE > AVX > FMA 動作速度:FMA > AVX > SSE

RAM要件

16GB以上

サポートされるOSと最小バージョン

Ubuntu Server (16.04 LTS)

ディスクスペース要件

100GB以上

日付

改訂内容

2021/08/20

  • 1章 顔の比較と 2章 写真品質チェックシステムレスポンスコード2006を削除

  • 1章 顔の比較と 2章 写真品質チェックシステムレスポンスコード2003と2004に説明文書を追加

  • 1.4節と 3章 なりすまし防止発生しないliveness_statusをいくつ削除

2021/03/08

  • 初版

1 顔の比較 (ステートレス)

イントロダクション

JCV顔認証サービス「SenseID」をご利用いただき、ありがとうございます。

SenseIDは、使いやすいAI顔認証サービスを提供します。オンラインビジネスのセキュリティとコンプライアンスを確保するためのあらゆる種類のオンライン認証シナリオに対応できるよう作られており、写真品質チェックをはじめ、顔比較や生体検知などの機能を提供し、サーバーとエッジの組み合わせに基づくサービスとなっております。

SenseIDサーバー(プライベートクラウド)では、1v1(顔比較)と1vN(顔検索)の2つのモデルを提供しています。ここでは、各モデルでご利用いただくマニュアルを提供しています。なお、本マニュアルは「SenseID 1v1 V1.8.0」向けの内容です。他のモデルやバージョンの切り替えについては、画面左上をクリックして対象のモデルとバージョンを選択してください。

SenseID専用生体検知SDKのマニュアルはこちらからアクセスできます。

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

マニュアルは改訂される場合があります。詳細は各マニュアルの改訂履歴ページを参照してください。 

2 写真品質チェック

3 なりすまし防止

運用マニュアル

SenseIDの運用中に必要な手順について記載しています。

本マニュアルでは、JCV顔認証サービスSenseIDの運用中に必要な各運用手順について記載しています。

当マニュアルはIT部門に所属するお客様、Linux、Kubernetes、Docker、クラウドなどの利用・運用経験があるお客様を対象にしています。

コマンドを実行します。
  • フラグを確認します。

  • 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 を実行します。

    Q2. go-workersで./start.shを複数回実行するなど、展開中に開始コマンド (./start.sh) が繰り返し呼び出される場合、またはポートが使用されている場合、ログを確認すると次のエラーが発生していました。

    go-workers または go-cloud-api を開始する際は、対応する ./start.sh を一度だけ開始してください。

    A2. 1) 下記のコマンドを実行します。

    2) ./tool/supervisord -c config/supervisor.conf -dに対応するプロセス番号を強制終了します。

    Q3. ライセンスの使用に関するエラータイプのまとめ

    A3. 弊社が提供する「プライベートクラウドパッケージ」には、デフォルトでライセンスが含まれていません。ライセンスの詳細な利用方法については、プライベートクラウドファイルのライセンスの使い方を参照してください。

    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を提供して、新しいライセンスを忘れずに交換してください。

    Q4 error:-8 ?

    4. 主にモデルファイルに関連したファイル形式が間違っていることを意味します。

    例えばWindows用の解凍ソフトを使用して、「プライベートクラウドパッケージ」を解凍してサーバーにアップロードすると、モデルファイルの一部が破損する可能性があります。そのため、インストールパッケージをサーバに再アップロードし、コマンドラインで解凍することをお勧めします。

    listen: listen tcp :50050: bind: address already in use
    $ ps aux | grep supervisord
    $ kill -9 PID

    3 ライセンスアクティベーション

    SenseIDの製品アクティベーションについて記載しています。

    3.1 ライセンスとは

    SenseIDのGo-Workersサービスを使用するには、ライセンスファイルが必要です。ライセンスファイルのアクティベーションは、UDIDに紐づける形で実行されます。異なるサービスを使用する場合、対応するライセンスファイルも異なります。1つのSenseIDサーバーには、1〜3つのライセンスファイルに対応します。SenseIDを展開する前に、ライセンスファイルの名前を変更して、指定のディレクトリに配置する必要があります。

    Go-Workers用のサーバーのみがライセンスを必要とします。 Ruby-Cloud-API用のサーバーにはライセンスは必要ありません。 以下の手順は、Go-Workers用のサーバーのみで実施してください。

    SenseIDのライセンスファイルは、JCV製品窓口より提供されます。アクティベーションの詳細については、次の手順を参照してください。

    3.2 ライセンスの名前変更

    • SENSEID_FACE_xxx.licファイルの名前を、senseid_face.licに変更

    • SENSEID_KESTREL_xxx.licファイルの名前を、senseid_kestrel.licに変更

    • SENSEID_LIVENESS_xxx.lic

    3.3 ライセンスの置き換え手順

    3.3.1 インストールパッケージ展開

    パッケージ名:1v1-private-cloud-v1.8.tgz

    必ずLinux上でtgzファイルを解凍するようにしてください。Linux以外で解凍した場合、ソフトリンクの障害が発生し、プログラムの実行が失敗する可能性があります。

    3.3.2 ライセンスファイル配置

    SenseIDのインストールパッケージの解凍先にある、ライセンスディレクトリへ移動します。

    以下の命令を実施し、次の3つのフォルダーが表示されることを確認できます。

    指定したディレクトリにライセンスファイルをコピーし、元のファイルを上書きします。

    3 写真と動画の規格

    SenseIDのAPI機能を使用する為の入力写真と動画基準について記載しています。

    3.1 入力写真の基準

    1. 写真のフォーマットは以下のいずれかであること。推奨フォーマットはJPG(JPEG)はです。 フォーマット:JPG(JPEG)、BMP、PNG、GIF、TIFF

    写真の幅と高さは32ピクセル以上、かつ5,000px以下であること。推奨サイズは640✕480ピクセルです。
  • 写真ファイルのサイズは5MB以下であること。サイズが大きいほど、処理性能に影響があります。100KBまで圧縮することを推奨します。

  • 3.2 入力動画の基準

    1. 一般的な動画フォーマットをサポートしています。推奨フォーマットはmp4です。 対応フォーマット:mp4、avi、flv、wmv、mov、rm

    2. 動画の幅と高さは8ピクセル以上、かつ5,000px以下であること。推奨サイズは640✕480ピクセルです。

    3. 動画ファイルのサイズは16MB以下であること。サイズが大きいほど、処理性能に影響があります。約500KB〜1MB程度に圧縮することを推奨します。

    ファイルの名前を、
    senseid_liveness.lic
    に変更

    1 ライセンスファイルの更新と変更

    SenseIDの製品ライセンス更新について記載しています。

    ライセンスファイルを更新するためには、指定のディレクトリに旧ライセンスファイルから新しいライセンスファイルを上書きして配置する必要があります。詳細はインストールマニュアルの3章 ライセンスファイルを配置をご参照ください。

    上記の手順を実行後、サービスを再起動してくだい。

    $ cd 1v1-private-cloud-v1.8/go-worker
    $ sudo ./stop.sh
    $ sudo ./start.sh
    $ tar -xvzf 1v1-private-cloud-v1.8.tgz
    $ cd 1v1-private-cloud-v1.8/go-workers/fixture/license
    $ ls -1
    
    senseid_face
    senseid_kestrel
    senseid_liveness
    #1) senseid_face.licをsenseid_faceフォルダーに移動し、以前のライセンスを上書き
    $ cp {ファイル先}/senseid_face.lic {インストール先}/1v1-private-cloud-v1.8/go-workers/fixture/license/senseid_face
    
    #2) senseid_kestrel.licをsenseid_kestrelフォルダーに移動し、以前のライセンスを上書き
    $ cp {ファイル先}/senseid_kestrel.lic {インストール先}/1v1-private-cloud-v1.8/go-workers/fixture/license/senseid_kestrel
    
    #3) senseid_liveness.licをsenseid_livenessフォルダーに移動し、以前のライセンスを上書き
    $ cp {ファイル先}/senseid_liveness.lic {インストール先}/1v1-private-cloud-v1.8/go-workers/fixture/license/senseid_liveness

    4 アップデート

    SenseIDの製品バージョンアップデートについて記載しています。

    本マニュアルでは、SenseIDのV1.7.0からV1.8.0へのアップデートを例にして、アップデート手順を案内します。

    事前準備として、V1.8.0のパッケージ1v1-private-cloud-v1.8.tgzをV1.7.0がインストールした同じディレクトリに解凍・配置してください。

    4.1 旧バージョンのRuby-Cloud-APIサービスを停止

    旧バージョンのフォルダーに移動し、Ruby-Cloud-APIサービスを停止します。

    2 UDID

    SenseIDのライセンス発行に必要なUDIDについて記載しています。

    2.1 UDIDとは

    UDIDは、サーバーのハードウエア情報から算出したサーバーの識別コードです。SenseIDのアクティベーションは、UDIDに紐づける形で実行されます。SenseIDの認証を申請する前にUDID取得ツールをダウンロードし、指示に従ってUDIDを取得してください。

    Go-Workers用のサーバーのみがライセンスを必要とします。 Ruby-Cloud-API用のサーバーにはライセンスは必要ありません。 以下の手順は、Go-Workers用のサーバーのみで実施してください。

    4.2 新バージョンの設定ファイルを更新

    インストールマニュアルの4.2.1節 並行CPU数を調整、4.3.2節 Go-Workersサービスアドレスを設定、4.3.3節 並行CPU数を調整を参照し、CPU数とGo-Workersのアドレスを、旧バージョンと同様に新バージョンの設定ファイルで設定します。

    4.3 新バージョンのサービスイメージを読み込む

    新バージョンのディレクトリに移動し、イメージファイルを読み込みます。

    4.4 新バージョンのRuby-Cloud-APIサービスを開始

    新バージョンでのRuby-Cloud-APIサービスを開始します。

    4.5 旧バージョンのGo-Workersサービスを停止

    旧バージョンのフォルダーに移動し、Go-Workersサービスを停止します。

    4.6 ライセンスファイルをコピー

    旧バージョンから、ライセンスファイルを新バージョンのGo-Workersの指定フォルダにコピーします。

    V1.8.0からsenseid_kestrel.licが必要となります。予めUDID.txtファイル、およびお客様の契約番号を、JCV製品提供窓口()までご連絡ください。詳細はインストールマニュアルの2章 UDID取得をご参照ください。

    senseid_kestrel.licを取得後、以下の命令で新バージョンの指定フォルダにコピーしてください。

    4.7 新バージョンのGo-Workersサービスを開始

    新バージョンのフォルダーに移動し、Go-Workersサービスを開始します。

    4.8 新サービス開始の確認

    サービスが正常に開始したか確認します。

    • Ruby-Cloud-API

    • Go-Workers

    2.2 UDID取得ツール

    デプロイターゲットのサーバーの UDIDを取得します。

    UDID取得ツールのファイル名称は、SenseIDPrivateCloud-UDIDGetter-V4.1.0.zipです。

    2.3 UDIDを取得

    UDID取得ツールをサーバーに配置・解凍してください。

    必ずLinux上でZIPファイルを解凍するようにしてください。Linux以外で解凍した場合、ソフトリンクの障害が発生し、プログラムの実行が失敗する可能性があります。

    解凍したディレクトリへ移動し、UDIDGetter.shを実行してください。

    出力されたUDID.txtファイル、およびお客様の契約番号を、JCV製品提供窓口である、宛にご連絡ください。

    $ unzip SenseIDPrivateCloud-UDIDGetter-V4.1.0.zip

    2 写真と動画の暗号化

    SenseIDのAPI機能を使用する為の写真と動画暗号化方法について記載しています。

    2.1 暗号化キーの設定

    ユーザーがアップロードした個人データ(写真と動画)は、暗号化する必要があります。暗号化アルゴリズムはAES-256-GCMが使用されています。 暗号化に必要なキーおよびIVは、デフォルトの設定では以下のとおりです。

    PARAM_DECRYPT_KEY = dcbbad6765e14139a07d34b92292a672
    PARAM_DECRYPT_IV = df25d188a061

    変更する場合、環境変数PARAM_DECRYPT_KEYおよびPARAM_DECRYPT_IVを更新してください。キーは32文字で、IVは12文字です。

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

    2.2 暗号化方法

    1. 人物の写真ファイルまたは動画ファイルを読み取ります。

    2. AES-256-GCMでデータを暗号化します。

    3. Base64で上記の結果を暗号化します。

    $ 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 {ファイル先}/senseid_liveness.lic {インストール先}/1v1-private-cloud-v1.8/go-worker/fixture/license/senseid_liveness
    $ cd 1v1-private-cloud-v1.8/go-workers
    $ sudo ./start.sh
    $ sudo ./docker-compose ps
    $ tail -f tmp/worker.log.0
    $ cd /SenseIDPrivateCloud-UDIDGetter-V4.1.0
    $ sudo ./UDIDGetter.sh
    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);
        }
    }

    5 エラーコード一覧

    SenseIDの運用中に発生するエラーコードについて記載しています。

     

    error_code

    値

    説明

    STID_OK

    0

    成功

    STID_E_INVALID_ARG

    -1

    無効なパラメータです。 各入力パラメータの値が正しく指定されているかを確認してください。

    STID_E_HANDLE

    4 サービスの展開方法

    SenseIDのインストール方法について記載しています。

    SenseIDを認証するための展開方法について、主にインストール、設定、重要なサービスの起動、また発生する可能性のある問題とその解決策について詳しく説明しています。

    4.1 インストールパッケージの展開確認

    ライセンスファイルファイルを配置する為に、パッケージを解凍します。手順は3.3.1節をご参照ください。

    解凍されたファイルのディレクトリへ移動し、現在のディレクトリにあるファイルを表示します。

    構造は次のとおりです。

    4.2 Go-Workersの展開

    このサービスは主要なコンピューティングサービスであるため、できれば専用のサーバーリソースを割り当てるようにしてください。

    4.2.1 並行CPU数を調整

    Go-Workersを配置する前に、サーバーの物理CPUコア数を確認する必要があります。物理CPUコア情報を取得するコマンドは以下のとおりです。

    Go-Workersディレクトリへ移動して.envファイルを開き、専用サーバーを利用する場合、HANDLERSの値を先程確認した物理CPUコア数に設定してください。それ以外の場合は、コア数を指定してください。編集後、.envファイルを保存してください。

    HANDLERSには、サーバーの物理CPUコア数を超える値を設定することはできません。HANDLERS値が大きいほど、サービスの同時実行数が高くなり、メモリとCPUの消費量が多くなります。

    4.2.2 Go-Workersサービスを開始

    開始する前に、ライセンスが置き換え済であることを確認してください。

    Go-Workersサービスを開始します。

    この命令を実行する必要があるのは一度のみです。

    なお、展開ディレクトリ内に停止スクリプトも用意されています。停止したい場合、以下の命令を実行してください。

    4.2.3 Go-Workersサービス開始の確認

    サービスが正常に開始したかを確認するために、以下の命令でログを参照します。

    tailコマンドの実行結果にポート番号50050のServer Listenが含まれていれば、サービスが正常に開始されたことを示します。

    また、以下の命令でヘルスチェックを実施してください。

    正常に展開された場合の実行結果の例は、以下のとおりです(これはサービスが正常に開始したことを示しています)。

    4.3 Ruby-Cloud-APIを展開

    以下のサービスのデプロイはDockerに依存しますので、ご自身でDockerをインストールしてください。

    4.3.1 サービスイメージを読み込む

    Ruby-Cloud-APIのイメージファイルを読み込みます。

    実行結果は以下のとおりです。

    4.3.2 Go-Workersサービスアドレスを設定

    Go-WorkersサーバーのIPアドレスを取得してください。

    SenseIDインストールパッケージのルートフォルダにある.envファイルを開きます。

    最終行の WORKER_IP 値を、Go-Workersサービスが展開されているサーバーの IP アドレスで設定します。

    4.3.3 並行CPU数を調整

    Go-Workersと同様に、サーバーの物理CPUコア数を設定します。

    .envファイルを開き、専用サーバーを利用する場合、API_HANDLESの値を先程確認した物理CPUコア数に設定してください。それ以外の場合は、コア数を指定してください。編集後、.envファイルを保存してください。

    API_HANDLESには、サーバーの物理CPUコア数を超える値を設定することはできません。API_HANDLES値が大きいほど、サービスの同時実行数が高くなり、メモリとCPUの消費量が多くなります。

    4.3.4 Ruby-Cloud-APIサービス開始

    Ruby-Cloud-APIサービスを開始します。

    結果は、以下のとおりです。

    Dockerが起動していることを確認します。

    結果は以下のとおりです。

    ここまででサービスは展開されています。

    4.3.5 Ruby-Cloud-APIサービス開始を確認

    以下の命令で、ヘルスチェックを実施してください。

    正常に展開された場合、実行結果の例は以下のとおりです(サービスが正常に開始したことを示しています)。

    $ cd 1v1-private-cloud-v1.8
    $ ls -1
    api.tar
    docker-compose
    docker-compose.yml
    go-workers
    load_image.sh
    package.toml
    product.toml

    -2

    Handleの作成に失敗しました。入力Handleが正しく提供されているかを確認してください。

    STID_E_OUTOFMEMORY

    -3

    メモリ不足です。

    STID_E_FAIL

    -4

    操作に失敗しました。 一般的な内部エラーです。

    STID_E_INVALID_PIXEL_FORMAT

    -6

    その画像のピクセルはサポートされていません。 3章 写真と動画の規格を参照してください。

    STID_E_FILE_NOT_FOUND

    -7

    リソースファイルが見つかりません(ライセンス、モデルなど)。 入力パスが正しいか確認してください。

    STID_E_INVALID_FILE_FORMAT

    -8

    ファイル形式が正しくありません(主にモデルファイルに関連しています)。

    STID_E_MODEL_FILE_EXPIRE

    -9

    モデルファイルの有効期限が切れています。

    STID_E_INVALID_AUTH

    -13

    不正なライセンスファイルが見つかりました(提供された製品名がライセンスと一致していない場合など)、もしくはライセンスファイルがロードされていません。

    STID_E_AUTH_EXPIRE

    -15

    SDKのライセンスファイルの有効期限が切れています。

    STID_E_UDID_MISMATCH

    -16

    UDIDが一致しません。 ライセンスに発行されたハードウェアの指紋が、検出されたハードウェアの指紋と一致していません。

    STID_E_VERSION_MISMATCH

    -23

    検出されたSDKのバージョンは、ライセンスファイルの発行された範囲内にありません。

    STID_E_PLATFORM_NOTSUPPORTED

    -24

    サポートされていないプラットフォームが検出されました。 検出されたプラットフォームが、発行されたライセンスファイルの範囲を超えています。

    STID_E_MODEL_UNZIP_FAILED

    -25

    モデルの解凍に失敗しました。 モデルファイルが破損していないか確認してください。

    STID_E_SUBMODULE_NOT_FOUND

    -26

    サブモデルが存在しません。 正しいモデルファイルが使用されているか確認してください。

    STID_E_CAPABILITY_NOTSUPPORTED

    -2067857410

    ライセンスの機能をサポートしていないインターフェースを使用しています。

    STID_E_GET_UDID_FAIL

    -2146304001

    UDIDの取得に失敗しました。

    STID_E_READ_MODEL_FILE_FAIL

    -10

    モデルファイルの読み取りに失敗しました。

    STID_E_LOAD_LIBRARY_FAILED

    -2065563655

    ダイナミックライブラリのロードに失敗しました。

    STID_E_ONLINE_ACTIVATE_PARENT_LICENSE_NOT_FOUND

    -2145517553

    親ライセンスが見つかりません。

    STID_E_ONLINE_ACTIVATE_PARENT_LICENSE_TOO_MANY

    -2145517552

    認証ファイルの親証明書が多すぎます。 最大数は10です。

    $ echo Cores=$(($(lscpu | awk '/^Socket/{print $2}') * $(lscpu | awk '/^Core/{print $4}')))
    $ cd go-workers
    $ vi .env
    $ sudo ./start.sh
    $ sudo ./stop.sh
    $ tail -f tmp/worker.log.0
    $ curl 127.0.0.1:50050/healthcheck
    {"request_id":"07a41c21822e4223a373e77bfc186ed2","status":"ok"}
    $ cd 1v1-private-cloud-v1.8
    $ sudo ./load_image.sh
    Loaded image: registry.sensetime.com/senseid-cloudv2/api-1v1:xxx
    $ hostname -I | cut -d' ' -f1
    $ vi .env
    $ vi .env
    $ sudo ./docker-compose up -d
    Creating network "1v1-private-cloud-yyyymmdd_default" with the default driver
    Creating 1v1-private-cloud-yyyymmdd_api_1 ... done
    $ sudo ./docker-compose ps
             Name                    Command             State               Ports
    ---------------------------------------------------------------------------------------
    1v1-private-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"}
    [email protected]
    [email protected]

    2.1 /quality/face/stateless

    顔写真品質チェックのインターフェースです。

    写真ファイルに、複数の顔が含まれることは可能です

    顔写真の規格は、運用マニュアルの3章 写真と動画の規格をご参照ください。

    リクエストモード

    POST

    リクエスト URL

    リクエストパラメーター

    通常のレスポンス

    異常なレスポンス

    システムレスポンスコードの説明

    可能なHTTPステータスコード

    サンプル

    写真タイプが要件を満たしていません

    4000

    detection failed

    特徴の抽出に失敗しました。写真に顔が検出されませんでした

    フィールド

    型

    必須

    説明

    encrypted_image

    string

    Yes

    暗号化された写真。暗号化方法の参照: 個人データの暗号化

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード:1000

    faces

    array

    写真に写っている各顔のクオリティについての情報

    request_id

    string

    リクエストのID

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード

    message

    string

    エラーメッセージ

    request_id

    string

    リクエストのID

    コード

    フィールドの値

    説明

    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/quality/face/stateless
    {
        "code": 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
    }
    {
        "code": int,
        "message": string,
        "request_id": string
    }
    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();
        }
    }

    1.1 /identity/image_verification/stateless

    インターフェースを介してアップロードされた2つの顔写真を比較して、2つの顔が同一人物のものかどうかを判断します。

    写真の規格は、運用マニュアルの3章 写真と動画の規格をご参照ください。

    リクエストモード

    POST

    リクエスト URL

    リクエストパラメーター

    通常のレスポンス

    顔比較スコアのしきい値とエラー率との対応関係

    推奨しきい値:0.7以上

    異常なレスポンス

    システムレスポンスコードの説明

    可能なHTTPステータスコード

    使用サンプル

    Curl

    Java

    3.1 /liveness/silent_detection/stateless

    サイレント生体検知のインターフェースです。

    動画の規格は、運用マニュアルの3章 写真と動画の規格をご参照ください。

    リクエストモード

    POST

    リクエスト URL

    リクエストパラメーター

    通常のレスポンス

    ここでliveness_statusの結果は以下のようになります:

    異常なレスポンス

    システムレスポンスコードの説明

    可能なHTTPステータスコード

    サンプル

    1.3 /identity/liveness_image_verification/stateless

    インターフェースを介してアップロードされた顔画像と生体認証データを比較して、画像内の顔が同一人物のものであるかどうかを判断します。

    写真の規格は、運用マニュアルの3章 写真と動画の規格をご参照ください。

    リクエストモード

    POST

    リクエスト URL

    リクエストパラメーター

    通常のレスポンス

    顔比較スコアのしきい値とエラー率との対応関係

    推奨しきい値:0.7 以上

    異常なレスポンス

    システムレスポンスコードの説明

    可能なHTTPステータスコード

    使用サンプル

    Curl

    Java

    1.2 /identity/multiface_image_omni_verification/stateless

    比較対象の顔写真に複数の顔が含まれる場合、2つの写真に含まれる顔の各グループの類似度スコアを返します。

    写真の規格は、のをご参照ください。

    リクエストモード

    POST

    No

    デフォルト値はfalseで、写真が回転していないことを示します。値がtrueの場合、写真は自動的に回転されます

    check_quality

    boolean

    No

    デフォルト値はfalseで、画質テストは行われません。値がtrueの場合、画質のテストが行われます

    写真タイプが要件を満たしていません

    4000

    detection failed

    特徴の抽出に失敗しました。写真に顔が検出されませんでした

    4004

    face occlusion

    顔は検出されていますが、目、鼻、口で部分的に見えなくなっています

    フィールド

    型

    必須

    説明

    first_encrypted_image

    string

    Yes

    暗号化された写真1。暗号化方法の参照: 個人データの暗号化

    second_encrypted_image

    string

    Yes

    暗号化された写真2。暗号化方法の参照: 個人データの暗号化

    auto_rotate

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード:1000

    verification_score

    float

    顔比較スコア、範囲:0〜1 。値が大きいほど、2つの顔が同じ人物のものである確率が高くなります

    request_id

    string

    リクエストのID

    閾値

    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

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード

    message

    string

    エラーメッセージ

    request_id

    string

    リクエストのID

    コード

    フィールドの値

    説明

    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 or corrupted

    No

    選出されたフレーム写真の顔のクロップを返すかどうかを指定します。。 デフォルト値はfalseで、値がtrueかつ生体認証が通過した場合にbase64_face_imageフィールドは返されます

    return_status

    boolean

    No

    エラーステータスの説明を返すかどうかを指定します。デフォルトはfalseで、値がtrueの場合にのみliveness_statusフィールドは返されます

    サイレントライブネス検出のエラー状態を記述します。このフィールドは、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の場合に返されます

    request_id

    string

    リクエストのID

    フィールド

    型

    必須

    説明

    encrypted_video

    string

    Yes

    暗号化された動画。暗号化方法の参照: 個人データの暗号化

    return_image

    boolean

    No

    選出されたフレーム写真と選出されたフレーム写真のタイムスタンプを返すかどうかを指定します。デフォルト値はfalseで、値がtrueかつ生体認証が通過した場合にimage_timestamp,base64_imageフィールドが返されます

    return_face_image

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード:1000

    passed

    boolean

    生体認証に通過したかどうか

    liveness_score

    float

    サイレント生体認証のスコア(参考までに、結果はpassedフィールドを使用してください)

    liveness_status

    ステータス

    説明

    ok

    サイレント生体認証は合格:動画の中の人は実在する

    hack

    サイレント生体認証は不合格。理由:捏造した顔 (例えば, ビデオで撮影された顔)

    short_time

    サイレント生体認証は不合格。理由:顔を含めるビデオの持続時間は2s未満

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード

    message

    string

    エラーメッセージ

    request_id

    string

    リクエストのID

    コード

    フィールドの値

    説明

    1200

    invalid argument

    無効な入力パラメーター

    2008

    invalid video error

    無効な動画(ビデオの持続時間は2s未満)

    4007

    liveness silent check failed

    サイレント生体認証に失敗

    ステータスコード

    ステータスフィールド

    400

    BAD_REQUEST

    404

    NOT_FOUND

    411

    LENGTH_REQUIRED

    413

    PAYLOAD_TOO_LARGE

    500

    INTERNAL_ERROR

    boolean

    string

    No

    デフォルト値はfalseで、画像が回転していないことを示します。値がtrueの場合、画像は自動的に回転されます

    check_quality

    boolean

    No

    デフォルト値がfalseの場合は品質チェックを行わず、trueの場合は画像の品質チェックを行います

    画像タイプが要件を満たしていません

    2007

    corrupted liveness data error

    生体検知ファイルが破損しています

    4000

    detection failed

    特徴の抽出に失敗しました。画像に顔が検出されませんでした

    4004

    face occlusion

    顔は検出されていますが、目、鼻、口が部分的に見えません

    フィールド

    型

    必須

    説明

    liveness_file

    file

    Yes

    生体検知SDKによる検出に成功した後に返された暗号化されたバイナリ・ストリーム・ファイル(例:protobufData)です。既に暗号化されているので、別途暗号化を必要としません

    encrypted_image

    string

    Yes

    暗号化された画像 。暗号化方法の参照: 個人データの暗号化

    auto_rotate

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード:1000

    verification_score

    float

    顔照合スコア、値0〜1、値が高いほど同一人物である可能性が高いことを示します

    request_id

    string

    リクエストのID

    閾値

    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

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード

    message

    string

    エラーメッセージ

    request_id

    string

    リクエストのID

    コード

    フィールドの値

    説明

    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 or corrupted

    http://ip:port/identity/image_verification/stateless
    {
        "code": 1000,
        "verification_score": float,
        "request_id": string
    }
    {
        "code": int,
        "message": string,
        "request_id": string
    }
    curl -X POST "http://ip:port/identity/image_verification/stateless" \
      -d first_encrypted_image=xxx \
      -d second_encrypted_image=xxx \
      -d auto_rotate=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/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();
        }
    }
    http://ip:port/liveness/silent_detection/stateless
    {
        "code": int,
        "passed": boolean,
        "liveness_score": float,
        "liveness_status": string,
        "image_timestamp": float,
        "base64_image": string,
        "base64_face_image": string,
        "request_id": string
    }
    {
        "code": int,
        "message": string,
        "request_id": string
    }
    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();
        }
    }
    http://ip:port/identity/liveness_image_verification/stateless
    {
        "code": 1000,
        "verification_score": float,
        "request_id": string
    }
    {
        "code": int,
        "message": string,
        "request_id": string
    }
    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
    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();
        }
    }
    リクエスト URL

    リクエストパラメーター

    フィールド

    型

    必須

    説明

    first_encrypted_image

    string

    Yes

    暗号化された写真1。暗号化方法の参照:

    second_encrypted_image

    string

    Yes

    暗号化された写真2。暗号化方法の参照:

    auto_rotate

    通常のレスポンス

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード:1000

    scores

    array

    写真の各グループの顔のスコアの比較。推奨しきい値:0.7〜0.8

    face_rects

    hash

    各写真の顔の顔枠

    request_id

    例:

    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以上

    異常なレスポンス

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード

    message

    string

    エラーメッセージ

    request_id

    string

    リクエストのID

    システムレスポンスコードの説明

    コード

    フィールドの値

    説明

    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

    使用サンプル

    Curl

    Java

    運用マニュアル
    3章 写真と動画の規格
    http://ip:port/identity/multiface_image_omni_verification/stateless
    {
        "code": 1000,
        "scores": [ # [[a1b1 顔比較スコア, a1b2 顔比較スコア], [a2b1 顔比較スコア, a2b2 顔比較スコア]]
      "face_rects":{ hash,# 各写真の顔枠
            [
                float,
                float,
                float,
                float
            ]
        ],
        "face_rects": { # face frame in each image
            "first_image_face_rects": [ # [[a1 顔枠の座標], [a2 顔枠の座標]]
                [
                    int,
                    int,
                    int,
                    int
                ],
                [
                    int,
                    int,
                    int,
                    int
                ]
            ],
            "second_image_face_rects": [ # [[b1 顔枠の座標],[b2 顔枠の座標]]
                [
                    int,
                    int,
                    int,
                    int
                ],
                [
                    int,
                    int,
                    int,
                    int
                ]
            ]
        },
        "request_id": "2c4156bb47794f66a2ed50d5a87e5ca2"
    }
    {
        "code": int,
        "message": string,
        "request_id": 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=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/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の場合、写真は自動的に回転されます

    string

    このリクエストのID

    invalid image type or corrupted

    写真タイプが要件を満たしていません

    4000

    detection failed

    特徴の抽出に失敗しました。写真に顔が検出されませんでした

    個人データの暗号化
    個人データの暗号化

    インストールマニュアル

    SenseIDをインストールする手順について記載しています。

    本マニュアルでは、JCV顔認証サービス「SenseID」のインストール方法について説明します。導入を成功させるために、導入作業を開始する前には、当マニュアルをよくお読みください。

    当マニュアルは、主にIT部門に所属するお客様、Linux、Kubernetes、Docker、クラウドなどの利用・運用経験があるお客様を対象にしています。

    本マニュアルで記載されているインストールのプロセスについては、次の図で詳細に説明します。

    1.4 /identity/silent_image_verification/stateless

    このAPIは、サイレント生体認証結果と自撮りの顔写真を比較に利用します。

    写真と動画の規格は、運用マニュアルの3章 写真と動画の規格をご参照ください。

    リクエストモード

    POST

    リクエスト URL

    リクエストパラメーター

    check_qualityは現在、顔が遮られているかどうかのみを評価できます。 今後は他の評価項目を導入する可能性があります。

    通常のレスポンス

    ここで、liveness_statusの結果は以下のようになります。

    顔比較スコアのしきい値とエラー率との対応関係

    推奨しきい値:0.7 以上

    異常なレスポンス

    システムレスポンスコードの説明

    可能なHTTPステータスコード

    使用サンプル

    Curl

    Java

    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の場合のみ返されます

    サイレントライブネス検出のエラー状態を記述します。このフィールドは、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の場合に返されます

    request_id

    string

    リクエストのID

    画像タイプが要件を満たしていません

    4000

    detection failed

    特徴の抽出に失敗しました。画像に顔が検出されませんでした

    4004

    face occlusion

    顔は検出されるが、目、鼻、口が部分的に見えません

    4007

    liveness silent check failed

    サイレント生体認証に失敗しました

    フィールド

    型

    必須

    説明

    encrypted_video

    string

    Yes

    暗号化された動画。暗号化方法の参照: 個人データの暗号化

    encrypted_image

    string

    Yes

    暗号化された画像 。暗号化方法の参照: 個人データの暗号化

    auto_rotate

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード:1000

    passed

    boolean

    生体認証に通過したかどうか

    liveness_score

    float

    サイレント生体認証のスコア(参考までに、結果はpassedフィールドを使用してください)

    liveness_status

    ステータス

    説明

    ok

    サイレント生体認証は合格:動画の中の人は実在する

    hack

    サイレント生体認証は不合格。理由:捏造した顔(例えば, ビデオで撮影された顔など)

    short_time

    サイレント生体認証は不合格。理由:ビデオの持続時間は2s未満など

    閾値

    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

    フィールド

    型

    説明

    code

    int

    システムレスポンスコード

    message

    string

    エラーメッセージ

    request_id

    string

    リクエストのID

    コード

    フィールドの値

    説明

    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

    string

    invalid image type or corrupted

    http://ip:port/identity/silent_image_verification/stateless
    {
        "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
    }
    {
        "code": int,
        "message": string,
        "request_id": string
    }
    curl -X POST "http://ip:port/identity/silent_image_verification/stateless" \
      -d encrypted_video=xxx \
      -d encrypted_image=xxx \
      -d auto_rotate=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/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();
        }
    }