機械学習というキーワードはここ数年、IT業界でのトレンドになっています。画像や動画、テキストなどを解析して、そこにある情報を抽出したり、カテゴリ分けするのに使われています。データの解析には多くの時間と計算量が必要ですが、その結果になるモデルができあがれば、スマートフォンなどでも利用が可能です。

JavaScriptを使って機械学習を行うライブラリとしてはTensorflow.jsが有名です。今回はそのTensorflow.jsをベースに顔認識機能を提供するface-api.jsを使って、Monacaアプリに顔認識機能を付けてみたいと思います。

justadudewhohacks/face-api.js: JavaScript API for face detection and face recognition in the browser and nodejs with tensorflow.js

今回は、JavaScriptを使って機械学習を行うライブラリの中でも有名な「Tensorflow.js」をベースにした「face-api.js」を使って、Monacaアプリに顔認識機能を追加します。

face-api.jsの特徴

  • Tensorflow.jsをベースにしている
  • 顔認識に特化している
  • ブラウザやNode.js環境で動作する

※ face-api.jsはモバイルアプリではAndroidのみ動作確認ができています

それでは、実際に実装していきましょう!

Step 1: face-api.jsを導入する

face-api.jsの導入は意外と簡単です。以下の手順で進めていきましょう。

  1. face-api.min.jsをダウンロードし、Monacaプロジェクトのwww/jsフォルダにアップロード。

  2. weightsフォルダ内の全ファイルをwww/modelsフォルダにアップロード。

  3. HTMLファイルに以下のスクリプトを追加:

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
<script src="js/face-api.min.js"></script>

豆知識:weightsフォルダの中身

weightsフォルダには様々な学習済みモデルが入っています。例えば:

  • age_gender_model: 年齢と性別を判定
  • face_expression_model: 表情を分類
  • face_landmark_68_model: 顔の68の特徴点を検出
  • その他にも様々なモデルがあります

Step 2: 顔認識機能を実装する

では、実際にコードを書いていきましょう。

HTML部分

<style>
  canvas#photo {
    width: 100%;
    height: 100%;
  }
</style>
<body>
  <h1>写真を選んで顔認識してみよう!</h1>
  <!-- ファイル選択用の入力フィールド。PNG と JPEG のみ受け付ける -->
  <input type="file" id="file" accept="image/png, image/jpeg" />
  <!-- 選択された画像と顔認識結果を表示するためのキャンバス -->
  <canvas id="photo"></canvas>
</body>

JavaScript部分

主要な関数を見ていきましょう:

  1. モデルの読み込みと写真選択のイベント設定
document.addEventListener("DOMContentLoaded", async (e) => {
  // face-api.js の顔検出モデルを読み込む
  await faceapi.nets.ssdMobilenetv1.loadFromUri("./models")

  // ファイル選択入力フィールドを取得
  const input = document.getElementById("file")

  // ファイルが選択されたときのイベントリスナーを設定
  input.onchange = function() {
    selectPhoto(this.files[0])  // 選択されたファイルを処理する関数を呼び出す
  }
})
  1. 写真の読み込みと表示
const selectPhoto = function(file) {
  if (!file) return  // ファイルが選択されていない場合は処理を中断

  const fr = new FileReader()
  fr.onload = function() {
    loadPhoto(this.result)  // ファイル読み込み完了後、画像を読み込む関数を呼び出す
  }
  fr.readAsDataURL(file)  // ファイルをData URL形式で読み込む
}

const loadPhoto = async function (src) {
  const image = new Image();
  image.src = src;
  image.onload = function() {
    drawPhoto(this)  // 画像の読み込みが完了したら、キャンバスに描画する関数を呼び出す
  }
}

const drawPhoto = async function(img) {
  // アプリの横幅に合わせてキャンバスサイズを調整
  const max = window.innerWidth
  const scale = max / img.width
  const height = img.height * scale

  // キャンバス要素を取得し、サイズを設定
  const canvas = document.getElementById("photo")
  const context = canvas.getContext("2d")
  canvas.width = max
  canvas.height = height

  // 画像をキャンバスに描画(サイズは横幅に合わせて調整)
  context.drawImage(img, 0, 0, img.width, img.height, 0, 0, max, height)

  detectFace(canvas)  // 顔認識処理を実行
}
  1. 顔認識の実行
const detectFace = async function(canvas) {
  // face-api.jsを使用して顔を検出
  const detections = await faceapi.detectAllFaces(canvas)

  if (detections.length === 0) {
    return  // 顔が検出されなかった場合は処理を終了
  }

  // 検出された顔を四角で囲む処理
  const context = canvas.getContext("2d")
  context.beginPath()

  for (const { box } of detections) {
    // 各検出された顔に対して青い四角を描画
    context.rect(box.x, box.y, box.width, box.height)
    context.lineWidth = "2"
    context.strokeStyle = "blue"
    context.stroke()
  }
}

動作確認:実際に試してみよう!

実装が完了したら、実際に写真をアップロードして顔認識を試してみましょう。小さな顔でも認識できるはずです!

顔認識の結果例

まとめ

いかがでしたか?思ったより簡単に顔認識機能を実装できたのではないでしょうか。

Tensorflow.jsを使えば、Monacaアプリ上でも機械学習を活用したアプリが開発できます。今回は顔認識でしたが、画像分類、テキスト解析など、応用分野は無限大です。

ぜひ、この記事を参考に自分なりのアイデアを形にしてみてください。みなさんの素晴らしいアプリ開発を楽しみにしています!

参考リンク