PicoGWには、音声認識や顔認識を行うためのプラグインがあります。
このプラグインでは内部的にGoogle Cloud Platform (GCP)を使っています。今回はこれを使ってcurlで顔認識を行うところまで行ってみたいと思います。
GCPからサービスアカウントキー(クレデンシャル)の取得
まず、GCPで顔認識(Cloud Vision API)と音声認識(Cloud Speech-to-Text API)が有効化されたAPIのサービスアカウントキーを作成します。作成方法はいろいろなところに出ているので、ここで繰り返すことはしません。ちょっと検索した限りでは、以下のサイトがわかりやすいように思えました。
- magellan blocks 「Google Cloud Platform のプロジェクトを作成する」
- magellan blocks 「Google Cloud Platform のサービスアカウントキーを作成する」
Google公式の解説ページはこちらです。
取得するサービスアカウントキー(本稿では「クレデンシャル」と呼んでいます)は、おおよそ以下のような内容を持っています。(一部*****で伏せているところがあります)
{ "type": "service_account", "project_id": "*****", "private_key_id": "*****", "private_key": "-----BEGIN PRIVATE KEY-----\n**********\n-----END PRIVATE KEY-----\n", "client_email": "*****@appspot.gserviceaccount.com", "client_id": "", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/*****%40appspot.gserviceaccount.com" }
PicoGW GCPプラグインのインストールと設定
PicoGWはインストール済みとします。 GCPのプラグインをインストールしてPicoGWを起動します。
npm i -g picogw-plugin-gcp picogw
ブラウザでWebフロントエンドを開き、GCPプラグインが含まれていることを確認します。
GCPプラグインの設定画面を開きます(gcpの文字の上で右クリック⇒Settingsを左クリック)。
表示されているテキスト領域を全部削除して、自分で取得したクレデンシャルを貼り付け、右下のApplyボタンを押してください。
これで準備完了です。
API Reference
本APIの呼び出しには、HTTP RESTのPOSTメソッドで画像または音声のファイルを送る必要があります。
POST /v1/gcp/image-label-detection
画像に何が写っているかのラベルを返します。
POST /v1/gcp/image-face-detection
画像から顔領域を探します。
POST /v1/gcp/transcript?lang=[Language code (default is ja)]
音声ファイルから文字起こしをします。周波数変換のために、パスが通った場所にffmpegがインストールされている必要がありますので用意をお願いします。参考:centosの場合
langオプションをつけると、認識言語を変更できます。ここに指定できるコード一覧はこちらにあります。
curlによる動作テスト
画像ラベル判定
コマンドライン:
curl -X POST -F file=@./child1.jpg http://localhost:8080/v1/gcp/image-label-detection結果:
{ "success": true, "result": [ { "faceAnnotations": [], "landmarkAnnotations": [], "logoAnnotations": [], "labelAnnotations": [ { "locations": [], "properties": [], "mid": "/m/0ytgt", "locale": "", "description": "Child", "score": 0.9935216903686523, "confidence": 0, "topicality": 0.9935216903686523, "boundingPoly": null }, { "locations": [], "properties": [], "mid": "/m/0dzct", "locale": "", "description": "Face", "score": 0.9538267254829407, "confidence": 0, "topicality": 0.9538267254829407, "boundingPoly": null }, { "locations": [], "properties": [], "mid": "/m/01k74n", "locale": "", "description": "Facial expression", "score": 0.944551408290863, "confidence": 0, "topicality": 0.944551408290863, "boundingPoly": null }, { "locations": [], "properties": [], "mid": "/m/06z04", "locale": "", "description": "Skin", "score": 0.9381709694862366, "confidence": 0, "topicality": 0.9381709694862366, "boundingPoly": null }, { "locations": [], "properties": [], "mid": "/m/0jnvp", "locale": "", "description": "Baby", "score": 0.9308986067771912, "confidence": 0, "topicality": 0.9308986067771912, "boundingPoly": null }, { "locations": [], "properties": [], "mid": "/m/01bgsw", "locale": "", "description": "Toddler", "score": 0.9096627235412598, "confidence": 0, "topicality": 0.9096627235412598, "boundingPoly": null }, { "locations": [], "properties": [], "mid": "/m/037p5b", "locale": "", "description": "Cheek", "score": 0.8978834748268127, "confidence": 0, "topicality": 0.8978834748268127, "boundingPoly": null }, { "locations": [], "properties": [], "mid": "/m/01f43", "locale": "", "description": "Beauty", "score": 0.8783525824546814, "confidence": 0, "topicality": 0.8783525824546814, "boundingPoly": null }, { "locations": [], "properties": [], "mid": "/m/0f9swq", "locale": "", "description": "Chin", "score": 0.8504008650779724, "confidence": 0, "topicality": 0.8504008650779724, "boundingPoly": null }, { "locations": [], "properties": [], "mid": "/m/0k0pj", "locale": "", "description": "Nose", "score": 0.8419631719589233, "confidence": 0, "topicality": 0.8419631719589233, "boundingPoly": null } ], "textAnnotations": [], "localizedObjectAnnotations": [], "safeSearchAnnotation": null, "imagePropertiesAnnotation": null, "error": null, "cropHintsAnnotation": null, "fullTextAnnotation": null, "webDetection": null, "productSearchResults": null, "context": null } ] }
顔認識
コマンドライン:
curl -X POST -F file=@./child1.jpg http://localhost:8080/v1/gcp/image-face-detection結果:
{ "success": true, "result": [ { "faceAnnotations": [ { "landmarks": [ { "type": "LEFT_EYE", "position": { "x": 183.83306884765625, "y": 158.3272705078125, "z": -0.0009126272052526474 } }, { "type": "RIGHT_EYE", "position": { "x": 237.47848510742188, "y": 152.12179565429688, "z": -19.267776489257812 } }, { "type": "LEFT_OF_LEFT_EYEBROW", "position": { "x": 168.75555419921875, "y": 149.98782348632812, "z": 14.353793144226074 } }, { "type": "RIGHT_OF_LEFT_EYEBROW", "position": { "x": 195.18470764160156, "y": 142.16566467285156, "z": -12.412994384765625 } }, { "type": "LEFT_OF_RIGHT_EYEBROW", "position": { "x": 221.54637145996094, "y": 138.88931274414062, "z": -21.856792449951172 } }, { "type": "RIGHT_OF_RIGHT_EYEBROW", "position": { "x": 263.2908020019531, "y": 141.64749145507812, "z": -17.94286346435547 } }, { "type": "MIDPOINT_BETWEEN_EYES", "position": { "x": 208.23385620117188, "y": 152.1124725341797, "z": -21.061262130737305 } }, { "type": "NOSE_TIP", "position": { "x": 203.107421875, "y": 180.77548217773438, "z": -45.14686965942383 } }, { "type": "UPPER_LIP", "position": { "x": 208.4833221435547, "y": 203.589599609375, "z": -38.105159759521484 } }, { "type": "LOWER_LIP", "position": { "x": 210.4447784423828, "y": 224.2166748046875, "z": -39.48147201538086 } }, { "type": "MOUTH_LEFT", "position": { "x": 193.34466552734375, "y": 215.6253662109375, "z": -18.22780418395996 } }, { "type": "MOUTH_RIGHT", "position": { "x": 239.2014923095703, "y": 211.96807861328125, "z": -32.95136642456055 } }, { "type": "MOUTH_CENTER", "position": { "x": 210.82553100585938, "y": 214.27163696289062, "z": -36.6275634765625 } }, { "type": "NOSE_BOTTOM_RIGHT", "position": { "x": 224.8909912109375, "y": 187.87037658691406, "z": -31.15186309814453 } }, { "type": "NOSE_BOTTOM_LEFT", "position": { "x": 194.1004638671875, "y": 191.8350830078125, "z": -19.869840621948242 } }, { "type": "NOSE_BOTTOM_CENTER", "position": { "x": 207.41456604003906, "y": 192.60531616210938, "z": -35.35366439819336 } }, { "type": "LEFT_EYE_TOP_BOUNDARY", "position": { "x": 183.9964141845703, "y": 154.99205017089844, "z": -3.289634943008423 } }, { "type": "LEFT_EYE_RIGHT_CORNER", "position": { "x": 194.33596801757812, "y": 159.67575073242188, "z": -4.268338680267334 } }, { "type": "LEFT_EYE_BOTTOM_BOUNDARY", "position": { "x": 183.50257873535156, "y": 163.54299926757812, "z": -2.01901912689209 } }, { "type": "LEFT_EYE_LEFT_CORNER", "position": { "x": 176.3940887451172, "y": 162.51254272460938, "z": 7.949547290802002 } }, { "type": "LEFT_EYE_PUPIL", "position": { "x": 184.0810546875, "y": 159.62258911132812, "z": -1.7658048868179321 } }, { "type": "RIGHT_EYE_TOP_BOUNDARY", "position": { "x": 238.2580108642578, "y": 148.54916381835938, "z": -22.66112518310547 } }, { "type": "RIGHT_EYE_RIGHT_CORNER", "position": { "x": 252.5885009765625, "y": 153.1426239013672, "z": -19.092214584350586 } }, { "type": "RIGHT_EYE_BOTTOM_BOUNDARY", "position": { "x": 238.85826110839844, "y": 156.89532470703125, "z": -21.54038429260254 } }, { "type": "RIGHT_EYE_LEFT_CORNER", "position": { "x": 228.52256774902344, "y": 155.40780639648438, "z": -16.135316848754883 } }, { "type": "RIGHT_EYE_PUPIL", "position": { "x": 239.66233825683594, "y": 152.96682739257812, "z": -21.758270263671875 } }, { "type": "LEFT_EYEBROW_UPPER_MIDPOINT", "position": { "x": 180.4531707763672, "y": 138.4478759765625, "z": -0.8508222699165344 } }, { "type": "RIGHT_EYEBROW_UPPER_MIDPOINT", "position": { "x": 239.37245178222656, "y": 131.46533203125, "z": -21.863447189331055 } }, { "type": "LEFT_EAR_TRAGION", "position": { "x": 176.57542419433594, "y": 208.13528442382812, "z": 70.0703353881836 } }, { "type": "RIGHT_EAR_TRAGION", "position": { "x": 306.7492980957031, "y": 195.07302856445312, "z": 27.771272659301758 } }, { "type": "FOREHEAD_GLABELLA", "position": { "x": 207.62928771972656, "y": 139.41769409179688, "z": -18.9888858795166 } }, { "type": "CHIN_GNATHION", "position": { "x": 213.51324462890625, "y": 251.314208984375, "z": -38.98262405395508 } }, { "type": "CHIN_LEFT_GONION", "position": { "x": 175.279296875, "y": 237.49163818359375, "z": 37.2729377746582 } }, { "type": "CHIN_RIGHT_GONION", "position": { "x": 287.4442138671875, "y": 224.81277465820312, "z": -3.0539612770080566 } } ], "boundingPoly": { "vertices": [ { "x": 136, "y": 65 }, { "x": 332, "y": 65 }, { "x": 332, "y": 292 }, { "x": 136, "y": 292 } ], "normalizedVertices": [] }, "fdBoundingPoly": { "vertices": [ { "x": 148, "y": 103 }, { "x": 308, "y": 103 }, { "x": 308, "y": 262 }, { "x": 148, "y": 262 } ], "normalizedVertices": [] }, "rollAngle": -1.3059591054916382, "panAngle": -20.222259521484375, "tiltAngle": 14.978519439697266, "detectionConfidence": 0.9348809123039246, "landmarkingConfidence": 0.7418720722198486, "joyLikelihood": "LIKELY", "sorrowLikelihood": "VERY_UNLIKELY", "angerLikelihood": "VERY_UNLIKELY", "surpriseLikelihood": "VERY_UNLIKELY", "underExposedLikelihood": "VERY_UNLIKELY", "blurredLikelihood": "VERY_UNLIKELY", "headwearLikelihood": "VERY_UNLIKELY" } ], "landmarkAnnotations": [], "logoAnnotations": [], "labelAnnotations": [], "textAnnotations": [], "localizedObjectAnnotations": [], "safeSearchAnnotation": null, "imagePropertiesAnnotation": null, "error": null, "cropHintsAnnotation": null, "fullTextAnnotation": null, "webDetection": null, "productSearchResults": null, "context": null } ] }
音声書き起こし
コマンドライン:
curl -X POST -F file=@./Sample.wav http://localhost:8080/v1/gcp/transcript結果:
{"success":true,"result":[{"text":"こんにちは"}]}