2
3

TensorFlow.jsを使用して骨格推定。骨格のライン推定 with TensorFlow.js

Posted at

スクリーンショット 2024-09-10 145927.png

ダウンロード (20).png

ダウンロード (1).png

TensorFlow.jsを使用して骨格推定。骨格のライン推定 with TensorFlow.js

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>TensorFlow.js 骨格推定 - 画像ファイル処理</title>
  
  <!-- TensorFlow.jsとPoseNetモデルの読み込み -->
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/posenet"></script>
  
  <style>
    /* ページ全体を中央揃えにするスタイル */
    body { text-align: center; margin-top: 20px; }
    /* 画像とcanvasのサイズ指定 */
    img, canvas {
      max-width: 640px;
      max-height: 480px;
    }
  </style>
</head>
<body>
  <h1>TensorFlow.js 骨格推定 - 画像ファイル処理</h1>
  
  <!-- 画像ファイルを選択するための入力フォーム -->
  <input type="file" id="fileInput" accept="image/*"><br><br>
  
  <!-- 選択された画像を表示するためのimgタグ -->
  <img id="image" style="display:none;">
  
  <!-- 骨格推定結果を描画するためのcanvasタグ -->
  <canvas id="output"></canvas>

  <script>
    // HTMLからimgとcanvas要素を取得
    const img = document.getElementById('image');
    const canvas = document.getElementById('output');
    const ctx = canvas.getContext('2d');
    const fileInput = document.getElementById('fileInput');

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

      // 画像を読み込み、表示する
      const reader = new FileReader();
      reader.onload = (e) => {
        img.src = e.target.result;
        img.onload = () => {
          // 画像が読み込まれた後にcanvasのサイズを画像に合わせる
          canvas.width = img.width;
          canvas.height = img.height;
          
          // 画像を描画してから骨格推定を行う
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
          estimatePose();
        };
      };
      reader.readAsDataURL(file); // 画像ファイルをData URLとして読み込む
    });

    // 骨格推定を行う関数
    async function estimatePose() {
      // PoseNetモデルをロード
      const net = await posenet.load();

      // 画像に対してポーズを推定
      const pose = await net.estimateSinglePose(img, {
        flipHorizontal: false // 鏡像反転しない設定
      });

      // キーポイントを描画
      drawKeypoints(pose.keypoints, ctx);
      // 骨格のラインを描画
      drawSkeleton(pose.keypoints, ctx);
    }

    // キーポイント(関節)を描画する関数
    function drawKeypoints(keypoints, ctx) {
      // 推定されたすべてのキーポイントを順番に処理
      keypoints.forEach(keypoint => {
        // 信頼度が高いキーポイント(0.5以上)だけ描画
        if (keypoint.score > 0.5) {
          const { y, x } = keypoint.position; // 座標を取得
          ctx.beginPath();
          ctx.arc(x, y, 5, 0, 2 * Math.PI); // 円を描画
          ctx.fillStyle = 'red'; // 赤色の円
          ctx.fill();
        }
      });
    }

    // キーポイント同士を線で結んで骨格を描画する関数
    function drawSkeleton(keypoints, ctx) {
      // 関節間の推定ペア(隣接キーポイント)を取得
      const adjacentKeyPoints = posenet.getAdjacentKeyPoints(keypoints, 0.5);

      // 各ペアの関節間に線を引く
      adjacentKeyPoints.forEach(keypoints => {
        const [start, end] = keypoints; // 線を引く開始点と終了点
        ctx.beginPath();
        ctx.moveTo(start.position.x, start.position.y); // 開始点に移動
        ctx.lineTo(end.position.x, end.position.y); // 終了点まで線を引く
        ctx.lineWidth = 2; // 線の太さ
        ctx.strokeStyle = 'blue'; // 線の色は青
        ctx.stroke();
      });
    }
  </script>
</body>
</html>

  1. HTMLファイルの構成
    : ユーザーが画像ファイルを選択できるようにするための入力フィールド。accept="image/*" は画像ファイルだけを選択可能にするための指定です。
    : 選択された画像を表示し、PoseNetモデルが処理できるようにします。スタイルとして display:none を指定して、画像自体は表示しないようにしています。
    : 骨格推定結果を描画する領域。画像に重ねて結果が表示されます。
  2. JavaScriptコードの詳細
    fileInput.addEventListener('change', async (event)):

画像ファイルが選択されると、このイベントハンドラーが呼び出されます。
FileReader オブジェクトを使って選択された画像ファイルを読み込み、img 要素に画像を表示します。
画像が読み込まれると、canvas のサイズを画像に合わせて調整し、骨格推定を実行します。
estimatePose():

PoseNetモデルをロードして、画像に対して骨格推定を行います。
骨格推定が完了すると、キーポイントと骨格ラインを canvas に描画します。
drawKeypoints():

キーポイント(関節の位置)を赤い円で描画します。信頼度が 0.5 以上のものだけを描画対象にしています。
drawSkeleton():

PoseNetの getAdjacentKeyPoints() を使って、隣接するキーポイントを線で結び、青い線で骨格のラインを描画します。
3. デザインとスタイル
画像ファイルのサイズに合わせて のサイズを動的に変更しているため、選択した画像に対して正確に骨格推定結果が表示されます。
使い方
このHTMLファイルをローカルで開くと、ファイル選択ダイアログが表示されます。
画像ファイルを選択すると、その画像に対してリアルタイムで骨格推定が行われ、推定結果が表示されます。

2
3
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
2
3