LoginSignup
0
2

More than 1 year has passed since last update.

ml5.jsのImage Classifierをブラウザでアップした画像に対して実行する

Posted at

ブラウザ上で手軽に機械学習もでるを扱えるml5.jsを使って、ローカルからアップした画像を認識させるための手順。

ソース

<html>

<head>
  <meta charset="UTF-8">
  <title>画像をアップロードすると画像認識してくれるページ</title>
  <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
  <style></style>
</head>

<body>
  <h1>画像をアップロードすると画像認識してくれるページ</h1>
    <p id="label">label:</p>
    <p id="confidence">confidence:</p>
<div class="upload"><input type="file" name="file" id="file"></div>
<canvas id="canvas"></canvas>

  <script>
  let file = document.getElementById('file');
  let canvas = document.getElementById('canvas');
  let canvasWidth = 400;
  let canvasHeight = 300;
  let uploadImgSrc;
  let label = document.querySelector("#label");
  let confidence = document.querySelector("#confidence");

  // 作成したモデルのURL
  const imageModelURL = 'Teachable Machineで作成したモデルのURL';

  // Canvasの準備
  canvas.width = canvasWidth;
  canvas.height = canvasHeight;
  let ctx = canvas.getContext('2d');

  let classifier = ml5.imageClassifier(imageModelURL + 'model.json', () => {
      // ロード完了
      console.log('Model Loaded!');
    });

//画像を読み込む関数
  function loadLocalImage(e) {
    // ファイル情報を取得
    let fileData = e.target.files[0];

    // 画像ファイル以外は処理を止める
    if (!fileData.type.match('image.*')) {
      alert('画像を選択してください');
      return;
    }

    // FileReaderオブジェクトを使ってファイル読み込み
    let reader = new FileReader();
    // ファイル読み込みに成功したときの処理
    reader.onload = function () {
      // Canvas上に表示する
      uploadImgSrc = reader.result;
      canvasDraw();
    }
    // ファイル読み込みを実行
    reader.readAsDataURL(fileData);
  }

  // ファイルが指定された時にloadLocalImage()を実行
  file.addEventListener('change', loadLocalImage, false);

  // Canvas上に画像を表示する関数
  function canvasDraw() {
    // canvas内の要素をクリアする
    ctx.clearRect(0, 0, canvasWidth, canvasHeight);

    // Canvas上に画像を表示
    let img = new Image();
    img.src = uploadImgSrc;
    img.onload = function () {
     if (this.width / this.height > canvasWidth / canvasHeight) {
        // 幅に合わせて画像サイズ設定
        var imgWidth = canvasWidth;
        var imgHeight = Math.floor(this.height * (canvasWidth / this.width));
      } else {
        // 高さに合わせて画像サイズ設定
        imgHeight = canvasHeight;
        imgWidth = Math.floor(this.width * (canvasHeight / this.height));
      }

      ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
    }
    classifyCanvas();
  }

  function classifyCanvas() {
    classifier.classify(canvas, gotResult);
  }

  // 画像認識結果を表示する関数
  function gotResult(error, results) {
    if (error) {
      console.error(error);
    }
    console.log(results);
    // 結果のラベルと信頼度を表示
    label.textContent = `Label: ${results[0].label}`;
    confidence.textContent = `Confidence: ${results[0].confidence.toFixed(4)}`;
  }
  </script>
</body>

</html>

モデルの準備

モデルのURLを指定してコールバック関数を呼び出すだけです。

// 作成したモデルのURL
const imageModelURL = 'Teachable Machineで作成したモデルのURL';
let classifier = ml5.imageClassifier(imageModelURL + 'model.json', () => {
    // ロード完了
    console.log('Model Loaded!');
});

イメージのアップロード

HTML要素としてinputをtype="file"で利用

<input type="file" name="file" id="file">

アップロード処理は以下の部分

  function loadLocalImage(e) {
    // ファイル情報を取得
    let fileData = e.target.files[0];

    // 画像ファイル以外は処理を止める
    if (!fileData.type.match('image.*')) {
      alert('画像を選択してください');
      return;
    }

    // FileReaderオブジェクトを使ってファイル読み込み
    let reader = new FileReader();
    // ファイル読み込みに成功したときの処理
    reader.onload = function () {
      // Canvas上に表示する
      uploadImgSrc = reader.result;
      canvasDraw();
    }
    // ファイル読み込みを実行
    reader.readAsDataURL(fileData);
  }

  // ファイルが指定された時にloadLocalImage()を実行
  file.addEventListener('change', loadLocalImage, false);

Canvasへの描画

画像ファイルを読み込むと以下の関数が実行される

  function canvasDraw() {
    // canvas内の要素をクリアする
    ctx.clearRect(0, 0, canvasWidth, canvasHeight);

    // Canvas上に画像を表示
    let img = new Image();
    img.src = uploadImgSrc;
    img.onload = function () {
     if (this.width / this.height > canvasWidth / canvasHeight) {
        // 幅に合わせて画像サイズ設定
        var imgWidth = canvasWidth;
        var imgHeight = Math.floor(this.height * (canvasWidth / this.width));
      } else {
        // 高さに合わせて画像サイズ設定
        imgHeight = canvasHeight;
        imgWidth = Math.floor(this.width * (canvasHeight / this.height));
      }

      ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
    }
    classifyCanvas();
  }

最初に宣言したcanvasのサイズ(今回は横400,縦300)に画像側をリサイズして描画している。

画像認識処理の実行

先ほどの描画関数の最後でclassifyCanvas()を呼んでいる。
認識処理完了したらコールバック関数で結果を画面表示。

  function classifyCanvas() {
    classifier.classify(canvas, gotResult);
  }

  // 画像認識結果を表示する関数
  function gotResult(error, results) {
    if (error) {
      console.error(error);
    }
    console.log(results);
    // 結果のラベルと信頼度を表示
    label.textContent = `Label: ${results[0].label}`;
    confidence.textContent = `Confidence: ${results[0].confidence.toFixed(4)}`;
  }
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2