以前、オープンソース プロジェクトをやったことがあります。GitHub ログインが完成した後、もっと高級感を出したいと思い、顔認識ログインを追加することにしました。開発スケジュールが遅いため、1 週間後にようやく時間が取れました。 ソースコードは記事の最後にあります 実は、最近は記事を書くことに少し抵抗を感じています。自分の書いたものを読んでくれる人は誰もいないし、いつも少しがっかりしています。幸い、同僚の指導のおかげで自信を取り戻すことができました。考え方を変えました。私が共有するものがみんなの役に立つ限り、それでいいのです。どれだけの人が読むかは運命次第です! では早速、ダイナミック顔認識効果を見てみましょう。モザイクが少し濃く、見た目があまり良くありません。 [[335574]] 実施原則 顔認識ログインを実装する一般的なプロセス、3 つの主なステップを見てみましょう。 フロントエンドのログインページでカメラを開き、顔認識を実行します。注意: 写真に顔があるかどうかのみを認識します。 顔を認識したら写真を撮り、現在の画面画像をアップロードします バックエンドは画像を受け取り、顔ライブラリ SDK を呼び出して肖像画を比較します。合格するとログインが成功し、肖像画の情報が顔ライブラリとローカル MySQL に登録されます。 フロントエンド実装 前述のように、フロントエンドで顔を認識する必要があるため、ここではツールを使用する必要があります。私は、軽量のフロントエンド顔認識フレームワークであるtracking.jsを使用します。 フロントエンドの Vue コードの実装ロジックは比較的シンプルです。tracking.js はカメラを開いて顔情報を認識した後、ビデオ画像の写真を撮影し、画像情報をバックグラウンドにアップロードし、画像比較の結果を待ちます。 - データ() {
- 戻る {
- showContainer: true, // 表示
- トラッカー: null、
- tipFlag: false, // デバイスが検出されたことをユーザーに通知する
- flag: false, // 写真が撮影されたかどうかを確認します
- context: null, // キャンバスコンテキスト
- removePhotoID: null, // 画像の変換を停止
- scanTip: '顔認識を実行中...', // プロンプトテキスト
- imgUrl: '', // base64 形式の画像
- キャンバス: null
- }
- },
- マウント() {
- this.playVideo()
- },
- メソッド: {
- ビデオを再生する(){
- varビデオ=ドキュメント.getElementById('ビデオ');
- this.canvas =ドキュメント.getElementById('canvas');
- this.context = this.canvas.getContext('2d' ) ;
- this.tracker =新しいtracking.ObjectTracker('face');
- this.tracker.setInitialScale(4);
- this.tracker.setStepSize(2);
- this.tracker.setEdgesDensity(0.1);
- トラッキングの追跡('#video', this.tracker, {カメラ: true});
- this.tracker.on('track', this.handleTracked);
- },
- 追跡イベントを処理する{
- this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
- イベントデータの長さが 0 の場合
- this.scanTip = '顔が検出されませんでした'
- } それ以外 {
- if (!this.tipFlag) {
- this.scanTip = '認識に成功しました。写真を撮っています。動かないでください〜'
- }
- // 1秒後に1回だけ写真を撮影します
- if (!this.flag) {
- this.scanTip = '写真を撮っています...'
- this.flag = true
- this.removePhotoID = setTimeout (() = > {
- this.tackPhoto()
- this.tipFlag = true
- },
- 2000
- )
- }
- イベントデータごとにプロットします。
- }
- },
- プロット(rect){
- this.context.strokeStyle = '#eb652e' ;
- this.context.strokeRect(rect.x, rect.y, rect.width, rect.height);
- this.context.font = '11px Helvetica' ;
- this.context.fillStyle = "#fff" ;
- this.context.fillText('x: ' + rect.x + 'px', rect.x + rect.width + 5, rect.y + 11);
- this.context.fillText('y: ' + rect.y + 'px', rect.x + rect.width + 5, rect.y + 22);
- },
- // 写真
- タックフォト() {
- this.context.drawImage(this.$refs.refVideo, 0, 0, 500, 500)
- // base64形式で保存
- this.imgUrl = this.saveAsPNG(this.$refs.refCanvas)です
- varフォームデータ=新しいフォームデータ();
- formData.append("ファイル", this.imgUrl);
- this.scanTip = 'ログイン中です。お待ちください〜'
- アクシオス({
- メソッド: 'post'、
- url: '/faceDiscern',
- データ: フォームデータ、
- }).then(関数 (応答) {
- アラート(応答データデータ);
- window.location.href = "http://127.0.0.1:8081/home" ;
- }).catch(関数(エラー) {
- コンソール.log(エラー);
- });
- this.close()
- },
- // png、base64 形式の画像として保存
- PNGとして保存(c) {
- c.toDataURL('image/png', 0.3) を返します
- },
- // リソースを閉じてクリーンアップする
- 近い() {
- this.flag = false
- this.tipFlag = false
- this.showContainer = false
- this.tracker && this.tracker.removeListener('track', this.handleTracked) && tracking.track('#video', this.tracker, {camera: false});
- this.tracker = null
- this.context = null
- this.scanTip = ''
- タイムアウトをクリアします(this.removePhotoID)
- }
- }
顔認識 以前、「Java ベースで実装した顔認識機能(ソースコード付き)」という顔認識案件をやったことがあるのですが、SDK の呼び出し方が面倒でコード量が膨大になってしまいました。そこで今回は、実装を簡素化するために、Baidu の顔認識 API に切り替えてみたところ、意外と簡単にできました。 なぜ独自の顔認識ツールを書かないのかと聞かないでください。聞かないでください。やり方が分からないだけです。 Baidu Cloud https://console.bce.baidu.com/ai/?_=1595996996657&fromai=1#/ai/face/app/list にアプリケーションを登録し、その後のトークン取得のために API キーとシークレット キーを取得します。 Baidu Cloud Face Recognition API は非常にユーザーフレンドリーで、さまざまな操作のデモがすでに作成されています。それを入手して、簡単な変更を加えるだけで済みます。 最初のステップは、Baidu 顔認識 API を呼び出すための基礎となるトークンを取得することです。 - https://aip.baidubce.com/oauth/2.0/token?
- grant_type =クライアント資格情報&
- client_id = [Baidu Cloud ApplicationのAK] &
- client_secret = [Baidu Cloud アプリケーション SK]
次に、写真を比較します。Baidu Cloud はオンライン顔データベースを提供しています。ユーザーがログインすると、まず顔データベースに肖像画が存在するかどうかを照会します。存在する場合は、ログインが成功したことを意味します。存在しない場合は、顔データベースに登録されます。各画像には一意の識別子 face_token があります。 Baidu 顔認識 API の実装は比較的簡単です。次の 3 つのタイプがあるパラメータ image_type に特に注意する必要があります。 - BASE64: 画像の base64 値、base64 でエンコードされた画像データ。エンコードされた画像のサイズは 2M を超えません。
- URL: 画像の URL アドレス (ネットワークなどの理由により、画像のダウンロードに時間がかかる場合があります)。
- FACE_TOKEN: 顔画像の一意の識別子。顔検出 API を呼び出すと、各顔画像に一意のトークンが割り当てられます。
FACE_TOKEN、同じ画像を複数回検出して得られた FACE_TOKEN は同じです。 ここでは BASE64 画像ファイルを使用しているため、image_type は BASE64 に設定する必要があります。 - @オーバーライド
- パブリック BaiDuFaceSearchResult faceSearch(文字列ファイル) {
- 試す {
- byte[]デコード= Base64.decode (Base64Util.base64Process(ファイル));
- 文字列faceFile = Base64Util .encode(decode);
- マップ<文字列、オブジェクト> map =新しいHashMap < > ();
- map.put("画像", faceFile);
- map.put("liveness_control", "NORMAL");
- map.put("group_id_list", "ユーザー");
- map.put("image_type", "BASE64");
- map.put("quality_control", "LOW");
- 文字列パラメータ= GsonUtils.toJson (マップ);
- 文字列結果= HttpUtil .post(faceSearchUrl、this.getAccessToken()、"application/json"、param);
- BaiDuFaceSearchResult のsearchResult = JSONObject .parseObject(result, BaiDuFaceSearchResult.class);
- log.info(" faceSearch: {}", JSON.toJSONString(searchResult));
- searchResult を返します。
- } キャッチ (例外 e) {
- log.error("faceSearch エラー {} を取得", e.getStackTrace());
- e.getStackTrace();
- }
- null を返します。
- }
- @オーバーライド
- パブリック BaiDuFaceDetectResult faceDetect(文字列ファイル) {
- 試す {
- byte[]デコード= Base64.decode (Base64Util.base64Process(ファイル));
- 文字列faceFile = Base64Util .encode(decode);
- マップ<文字列、オブジェクト> map =新しいHashMap < > ();
- map.put("画像", faceFile);
- map.put("face_field", "faceshape,facetype");
- map.put("image_type", "BASE64");
- 文字列パラメータ= GsonUtils.toJson (マップ);
- 文字列結果= HttpUtil .post(faceDetectUrl、this.getAccessToken()、"application/json"、param);
- BaiDuFaceDetectResult検出結果= JSONObject .parseObject(結果、BaiDuFaceDetectResult.class);
- log.info(" 検出結果: {}", JSON.toJSONString(検出結果));
- 検出結果を返します。
- } キャッチ (例外 e) {
- log.error("faceDetect エラー {} を取得", e.getStackTrace());
- e.getStackTrace();
- }
- null を返します。
- }
- @オーバーライド
- パブリック BaiDuFaceAddResult addFace(String file, UserFaceInfo userFaceInfo) {
- 試す {
- byte[]デコード= Base64.decode (Base64Util.base64Process(ファイル));
- 文字列faceFile = Base64Util .encode(decode);
- マップ<文字列、オブジェクト> map =新しいHashMap < > ();
- map.put("画像", faceFile);
- map.put("グループID", "ユーザー");
- map.put("user_id", userFaceInfo.getUserId());
- map.put("user_info", JSON.toJSONString(userFaceInfo));
- map.put("liveness_control", "NORMAL");
- map.put("image_type", "BASE64");
- map.put("quality_control", "LOW");
- 文字列パラメータ= GsonUtils.toJson (マップ);
- 文字列結果= HttpUtil .post(addfaceUrl、this.getAccessToken()、"application/json"、param);
- BaiDuFaceAddResultを追加します。
- log.info("addResult: {}", JSON.toJSONString(addResult));
- addResult を返します。
- } キャッチ (例外 e) {
- log.error("addFace エラー {} を取得", e.getStackTrace());
- e.getStackTrace();
- }
- null を返します。
- }
プロジェクトはフロントエンドとバックエンドに分かれていますが、学習の便宜上、顔認識ページをバックエンドプロジェクトに統合しました。 最後に、FireControllerApplication を実行し、アドレス http://localhost:8082/face にアクセスします。 |