【p5.js】阿炎の四股を手で再現できるかチャレンジしたら、阿炎の凄さを再認識しました

至高の四股・ABI

大相撲九州場所、熱戦が続いて良かったです!

芋の里

個人的には最後の熱海富士インタビューがグッときました!

美しい阿炎の四股

いつも思っていましたが、阿炎の四股は見事ですよね。

芋の里

四股の綺麗な力士の横綱土俵入りを見たいです!

幕内以下では休場しましたが輝鵬の四股は綺麗でした。更に琴手計、雷鵬など四股の綺麗な力士はたくさんいます!

芋の里

youtubeに動画があったので紹介します!

輝鵬の四股など

琴手計の四股など

こちらは直接youtubeでご覧ください。

雷鵬の四股など

勝負に入る前の所作で既に沸くところも相撲の面白さですね!

芋の里

北勝富士の時間いっぱいからのルーティン、最近は見ていませんが天空海、そして照強の豪快な塩撒きなど!

芋の里はもちろん90度くらいしか開脚が出来ないのですが、

芋の里

何とか阿炎のあの四股で沸いた時の気持ち良さを体験したい!

と考えて、個人的に使用しているp5.jsのhandposeというのを使ってみることにしました。

至高の四股・ABI

まずこちら、試してもらえればと思います(注:webカメラを使用します)。
スマホだと難しいかもしれません。

手を出すと、数秒後に阿炎の似顔絵(下手ですが愛をこめて描いています!)と体っぽい棒人間が出てきます。

残念ながら、身体つきを表現するレベルまでは芋の里のプログラミング力はないので、棒人間で廻しも付けられませんでしたが、頑張れば四股っぽい動きもできるかと思います。

やってみると難しいですが、やり方によっては四股っぽく見えたりもします。

芋の里

上手く行かない時もなかなか怪しい動きになるので結構楽しいです!

阿炎が見えやすいように少しビデオを暗くしています。

芋の里が試してみたyoutube動画です。

プログラムの説明

p5.jsというのは、クリエイティブ・コーディングがしやすいJavaScriptライブラリです。主にビジュアルアート、インタラクティブアート、ウェブベースのプロジェクトなどの分野で使われています。

web上でプログラムが作れ、簡単にwebカメラを使った作品などが出来ますので、

芋の里

プログラミングで何か面白いものを作ってみたい!
という人にはお勧めのツールです。

やってみたこと

通常は手を抽出する点を利用して、つなぐ番号を変えて棒人間に変更した形です。
ハンドパペット、配列部分の説明
動画画像を反対にすることで、阿炎の左に手が出るので、指をどのように動かせばいいか、少し分かりやすくしています。

常に膝に手を置いているポーズにしたので、四股だけに集中できる形になっているかと思います。

芋の里

バーチャルハンドパペット力士を作ったという感じでしょうか。

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.8.0/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.8.0/addons/p5.sound.min.js"></script>
    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>

    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <main>
    </main>
    <script src="sketch.js"></script>
  </body>
</html>

これは基本のp5.jsのコードですが、

    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>

この部分が重要です。これでml5という機械学習ライブラリを読み込みます。

JavaScript

let video;
let handpose;
let predictions = []; // 空の配列を準備
let imgdata; // 画像を保存する変数

function preload() {
  // 画像を読み込む
  imgdata = loadImage('abi_01.png');
}

function setup() {
  createCanvas(640, 480);

  // ビデオのキャプチャ
  video = createCapture(VIDEO);
  video.size(width, height);
  video.hide();
  handpose = ml5.handpose(video, modelReady);

  // モデルが新しい予測をした際に呼ばれる関数をセット
  handpose.on("predict", results => {
    predictions = results; // 予測結果を predictions 配列に保存
  });
}

function modelReady() {
  console.log("Model ready!");
}

function draw() {
  // キャプチャした画像を表示
    // ビデオを左右反転させる
  push(); // 現在の描画状態を保存
  translate(width, 0); // キャンバスの幅分だけ右に移動
  scale(-1, 1); // X軸方向に反転
  image(video, 0, 0, width, height); // ビデオを描画
  pop(); // 描画状態を復元
  background(0,0,0,100); // 暗い背景色を設定。0は黒色。

  // 予測結果を基に、手のキーポイントを描画
  for (let i = 0; i < predictions.length; i += 1) {
    const prediction = predictions[i];

    // キーポイント間の線を描画
    stroke(255, 200, 144); // 肌色のストローク
    strokeWeight(15);
    const connections = [
      [4,6],[6,10],[10,14],[14,19],
      [10,12],[11,7],[7,6],[11,15],[15,14]
    ];
    for (let j = 0; j < connections.length; j++) {
      const start = prediction.landmarks[connections[j][0]]; //始点[]の左
      const end = prediction.landmarks[connections[j][1]]; //終点[]の右
      line(start[0], start[1], end[0], end[1]);
    }

    for (let j = 0; j < prediction.landmarks.length; j += 1) {
      const keypoint = prediction.landmarks[j];
      if (j === 12) {
        const angle = getAngle(prediction.landmarks[11], prediction.landmarks[12]);
        const imgWidth = imgdata.width / 15;
        const imgHeight = imgdata.height / 15;
        push(); // 現在の描画状態を保存
        translate(keypoint[0], keypoint[1]); // 座標系をキーポイントの位置に移動
        rotate(angle); // [11, 12] 接続の角度で回転
        image(imgdata, -imgWidth / 2, -imgHeight / 2, imgWidth, imgHeight);
        pop(); // 描画状態を復元
      }
    }
  }
}

// [11, 12] 接続の角度を計算する関数
function getAngle(point1, point2) {
  const dx = point2[0] - point1[0];
  const dy = point2[1] - point1[1];
  return atan2(dy, dx) + HALF_PI; // 90度(π/2)を引いて補正
}

どこから説明していいか分からないので、後日時間があったら説明文を入れます。

ざっくり言うと、

    const connections = [
      [4,6],[6,10],[10,14],[14,19],
      [10,12],[11,7],[7,6],[11,15],[15,14]
    ];
    

ここで手を着いた状態の棒人間の体を表示しています。

これで、指の動きに合わせて棒人間の体の位置が変化するようにしています。

そして、12番の所に顔の画像が行くようにしました。

いい感じの四股の踏み方

芋の里

ここからは誰にも需要がなさそうな解説に入ります!

1.指の位置を調整する

親指の先と小指の第一関節が足裏に当たるので、その2点をできる限り地面と平行になるようにします。
四股01

2.親指は少しずつ広げ、小指を上げていく

どうしても親指を内側に入れてしまいそうになりますが、手の平を広げる感じで親指と小指の間を最大限に広げていきながら、小指を上げていきます。
四股02

3.思い切り小指を下ろして1の状態にする

上げた小指を下ろしていきますが、小指と親指を地面と平行になるようにします。
四股03

4.1,2,3を親指と反対にする

これはかなり難しいです。手の向きなども結構大変なので、芋の里もかなりひどい出来になっています。
四股04

芋の里

全く誇れない技術なので、上手く出来なくても気にしないでください

作ってみた感想

やっぱり阿炎すごい!

手を使ってできないかとおもいましたが、全然阿炎レベルの四股は踏めませんでした。

手でも難しいのに、身体全体を使ってあの動きは素晴らしいですね!

芋の里

力士は本当に凄い!今後もファンとして皆さんの取組を楽しみにしています!

今後やりたいこと

廻しをつけたい!

まずはこれですね!現状だと「不浄負け」になってしまう状態なので、これは何とかしたいです。

四股の綺麗な力士が増えたら顔のパターンを増やしたい!

輝鵬、琴手計、雷鵬などが幕内に上がってきたら、是非顔のパターンを増やして選択できるようにしたいと思います!

力士を2人登場させるようにしたい

ml5.jsのHandposeだと手は1つしか検出できないようですが、mediapipeを使用すると複数の手も検出できるようです。

なので、阿炎と他の四股が美しい力士が幕内に上がってきて対戦したら、今日の四股競演の再現ができます!

芋の里

その時は是非mediapipeでの四股メーカーを作りたいと思います!