🔗

JavaScriptで動物検出AIをやる!

2024/11/21に公開


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Animal Detection</title>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd"></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      text-align: center;
      padding: 20px;
    }
    canvas {
      border: 1px solid black;
      max-width: 100%;
    }
    #fileInput {
      margin: 20px;
    }
  </style>
</head>
<body>
  <h1>Animal Detection</h1>
  <p>Upload an image to detect animals!</p>
  <input type="file" id="fileInput" accept="image/*">
  <canvas id="canvas"></canvas>

  <script>
    const fileInput = document.getElementById('fileInput');
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    let model;

    // COCO-SSDモデルを読み込む
    cocoSsd.load().then((loadedModel) => {
      model = loadedModel;
      console.log("Model loaded!");
    });

    // 画像ファイルが選択されたときに処理を開始
    fileInput.addEventListener('change', async (event) => {
      const file = event.target.files[0];
      if (!file) return;

      const img = new Image();
      img.onload = async () => {
        // キャンバスサイズを画像に合わせる
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0);

        // モデルで画像を解析
        const predictions = await model.detect(canvas);

        // 動物を検出してバウンディングボックスを描画
        predictions.forEach((prediction) => {
          const { bbox, class: detectedClass, score } = prediction;

          // 動物クラスの場合のみ描画
          if (["cat", "dog", "bird", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe"].includes(detectedClass)) {
            const [x, y, width, height] = bbox;

            // バウンディングボックス
            ctx.strokeStyle = "red";
            ctx.lineWidth = 2;
            ctx.strokeRect(x, y, width, height);

            // ラベル
            ctx.fillStyle = "red";
            ctx.font = "16px Arial";
            ctx.fillText(`${detectedClass} (${(score * 100).toFixed(1)}%)`, x, y - 10);
          }
        });
      };

      // ファイルをデータURLに変換して画像を読み込む
      img.src = URL.createObjectURL(file);
    });
  </script>
</body>
</html>

Discussion