顔決済機能の実装をベースにしたHTML5+tracking.js
最近、顔決済が非常にホットなので、もちろん上司もその流れに乗りたいので、顔決済のプロジェクトがあります。この記事では、HTML5環境に顔認証を実装する方法と、その開発過程で発生した問題点について解説しています。
1.カメラ1.1カメラを取得するために入力します。
html5でユーザーカメラを取得するには、inputを使用して、以下の2つの方法があります。
<input type="file" capture="camera" accept="image/*"/>
また、アルバムを開きたい場合は、このようにします。
<input type="file" accept="img/*">
しかし、どちらのアプローチにも互換性の問題があることは、使ったことのある人ならご存じでしょう。
1.2 getUserMediaはカメラ画像を取得する
getUserMediaはhtml5の新しいapiで、公式の定義のビットは
MediaDevices.getUserMedia()
はユーザーにメディア入力の使用許可を求めるプロンプトを表示し、メディア入力によって
MediaStream
は、要求されたメディアタイプのトラックを含む。このストリームには、ビデオトラック(カメラ、ビデオキャプチャデバイス、画面共有サービスなどのハードウェアまたは仮想ビデオソースから)、オーディオトラック(マイク、A/D変換器などのハードウェアまたは仮想オーディオソースから)、または他のトラックタイプが含まれる可能性があります。
簡単に言うと、ユーザーカメラにアクセスできるようになるのです。
上記のinputと同様、この方法には互換性の問題がありますが、以下のように他のアプローチで解決することが可能です。 MediaDevices.getUserMedia() ドキュメントには、"Using the new API in older browsers"の記述があります。また、ここのWebで、getUserMediaの比較的包括的なバージョンをまとめた参考文献があり、以下のようなコードになっています。
// Accessing user media devices
getUserMedia(constraints, success, error) {
if (navigator.mediaDevices.getUserMedia) {
// Latest standard API
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
} else if (navigator.webkitGetUserMedia) {
//webkit kernel browser
navigator.webkitGetUserMedia(constrains).then(success).catch(error);
} else if (navigator.mozGetUserMedia) {
//Firefox browser
navagator.mozGetUserMedia(constraints).then(success).catch(error);
} else if (navigator.getUserMedia) {
//Older version of API
navigator.getUserMedia(constraints).then(success).catch(error);
} else {
this.scanTip = "Your browser does not support access to user media devices"
}
}
1.3 ビデオ再生画面
get deviceメソッドには、成功時と失敗時の2つのコールバック関数があります。成功した場合は、動画の再生が開始されます。ビデオ画面を再生するには、実際には、ビデオのURLを設定し、playメソッドを呼び出します。URLは、さまざまなブラウザの互換性を考慮して設定されます。
success(stream) {
this.streamIns = stream
// Set the URL for playback, for webkit browsers
this.URL = window.URL || window.webkitURL
if ("srcObject" in this.$refs.refVideo) {
this.$refs.refVideo.srcObject = stream
} else {
this.$refs.refVideo.src = this.URL.createObjectURL(stream)
}
this.$refs.refVideo.onloadedmetadata = e => {
// Play the video
this.$refs.refVideo.play()
this.initTracker()
}
},
error(e) {
this.scanTip = "Access to user media failed" + e.name + "," + e.message
}
注意事項
- ビデオ画面の再生メソッドは、onloadmetadata コールバック関数内に記述するのが最適です。そうしないと、エラーが報告される可能性があります。
- 動画を再生する場合、セキュリティ上の理由から、ローカル環境でテストする必要があります。つまり http://localhost/xxxx または https://xxxxx 環境でないと、クロスドメインで問題が発生する可能性があります。
- 以下で使用する initTracker() メソッドも、この onloadedmetadata コールバック関数内に置くことができ、そうでない場合はエラーも報告されます。
2. 顔のキャプチャ
2.1 tracking.jsで顔をキャプチャする
画面が正常に動画で再生されると、こちらのサードパーティーの機能を使って、顔認識を開始します。 tracking.js という、海外の神様が書いたJavaScriptの画像認識プラグインです。肝心のコードは以下の通りです。
// Face capture
initTracker() {
this.context = this.$refs.refCanvas.getContext("2d") // canvas
this.tracker = new tracking.ObjectTracker(['face']) // tracker instance
this.tracker.setStepSize(1.7) // set step size
this.tracker.on('track', this.handleTracked) // bind the listener method
try {
tracking.track('#video', this.tracker) // start tracking
} catch (e) {
this.scanTip = "Access to user media failed, please retry"
}
}
顔を取り込んだら、ページ上に小さなボックスでマークアップすることで、ある程度インタラクティブな表現ができるようになります。
// The tracking event
handleTracked(e) {
if (e.data.length === 0) {
this.scanTip = 'No face detected'
} else {
if (!this.tipFlag) {
this.scanTip = 'Detected successfully, taking a picture, please hold still for 2 seconds'
}
// take a picture after 1 second, only once
if (!this.flag) {
this.scanTip = 'Taking picture...'
this.flag = true
this.removePhotoID = setTimeout(() => {
this.tackPhoto()
this.tipFlag = true
}, 2000)
}
e.data.forEach(this.plot)
}
}
ページ上に顔を識別するためのボックスをいくつか描きます。
<div class="rect" v-for="item in profile"
:style="{ width: item.width + 'px', height: item.height + 'px', left: item.left + 'px', top: item.top + 'px'}"></div>
// Plot the tracking box
plot({x, y, width: w, height: h}) {
// Create the box object
this.profile.push({ width: w, height: h, left: x, top: y })
}
2.2 写真撮影
写真を撮るには、ビデオを画像ソースとして使用し、キャンバスに画像をダウンして保存します。なお、ここでtoDataURLメソッドを使用する場合、第2パラメータqualityを0から1の間で設定することができます。
// Take a photo
tackPhoto() {
this.context.drawImage(this.$refs.refVideo, 0, 0, this.screenSize.width, this.screenSize.height)
// Save as base64 format
this.imgUrl = this.saveAsPNG(this.$refs.refCanvas)
// this.compare(imgUrl)
this.close()
},
// Base64 to file
getBlobBydataURI(dataURI, type) {
var binary = window.atob(dataURI.split(',')[1]);
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {
type: type
});
},
// Save as a png,base64 image
saveAsPNG(c) {
return c.toDataURL('image/png', 0.3)
}
写真を撮影したら、バックエンドにファイルを送って比較・検証することができます。このとき、AliCloudのインターフェイスを使用します。
3. 最終結果
3.1 リファレンスコード・デモ
最後に デモ githubに置いてあるので、興味のある方は開いてみてください。
効果は以下の通りです。
3.2 プロジェクトへの着地
最後に、プロジェクトに入れ、最後のステップよりも何もない、比較の成功の結果によると、インターフェイスの比較を呼び出すには、成功または失敗、顔の支払いまたは元のパスワードの支払いを使用して継続するかどうかを決定するために、効果は次のとおりです。
追記:ここで顔比較に失敗したのは、マスクをしているので、歯をむき出しにして顔を見せているわけではないからです。
概要
今回の記事は、HTML5+tracking.jsによる顔認証決済についてです。HTML5の顔決済については、スクリプトハウスの過去記事を検索していただくか、引き続き以下の記事をご覧ください。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン