miso_soup3 Blog

主に ASP.NET 関連について書いています。

Unityを使ってピアノロールと演奏動画を合成する方法

下の画像のように、ピアノロールのオブジェクトと演奏動画を合成したものを作成してみました。Unityでピアノロールのオブジェクトを生成しました。

完成した動画はこちらです:

Unity のコードはこちら:https://github.com/hhyyg/miso.music-midi-piano-roll-object-unity

ピアノロールの影も映っているのが如何にも合成っぽくて嬉しくなりました。細部に拘らなければ、意外にも手軽にできたので、その方法を紹介します。

全体の流れ

  • ピアノの演奏を録画し、同時にMIDIデータとして録音する
  • LiDARスキャナで自宅のピアノを3DデータとしてUnityに取り込む
  • Unity上で、MIDIデータから、四角いオブジェクトが上から降るように実装する
    • ピアノの3Dモデルの鍵盤の位置と、音を表す四角いオブジェクトの位置を一致させる
  • Unity上で、演奏動画と一致するカメラのポジションを探して設定する
  • ピアノの3Dモデルを緑色にしてレンダリング
  • 動画編集アプリなどで、演奏動画とレンダリングした動画を合成する

きっかけと試行錯誤

YouTube上のピアノ演奏の動画では、手と鍵盤の上にピアノロールが描画されているものが多いです。ここで言うピアノロールとは、音の高さとタイミングを長方形の図で表示したものをいいます。

視覚的にも楽しめるこの演出を、自分の動画でも取り入れたいと思い実際にやってみました。しかし、カメラをピアノの上に高く設置しなければいけないため、なかなか準備が大変です。ですので、自分はよくカメラを横に置く方法で録画しています。でもこの横からみるアングルだと、次の図のように、ピアノロールの位置と実際の鍵盤の位置がずれてしまいます。

ピアノロールの動画を、少し変形させてみればいいのではないか、と試してみたものが次の図です。遠近法のルールが適用されていないので、やはり位置がずれてしまいます。 (ちなみに、Shotcutという動画編集のアプリでCorner Pinのフィルターを使用しました。)

そこで、今回のように、Unityでピアノロールのオブジェクトを生成して、演奏動画と一致するアングルのカメラからレンダリングすることで、位置がずれないようにしました。

ちなみに、この斜めからみたアングルでの演奏動画は、他の方も行われています。ピアノロールが透明ディスプレイみたいになっていてかっこいいです。

課題

  • 写真からカメラの空間座標を得る作業が大変
  • 取り込んだピアノの3Dモデルを綺麗に編集し、ノイズをなくしたい
  • ピアノロールのオブジェクトをテクスチャやエフェクトをかっこよくしたい

詳細な手順

最後に、詳細な手順を記載します。

自宅のピアノを3DデータとしてUnityに取り込む

iPhone 13 Pro で、Polycamというアプリでスキャンし、GLTG形式のファイルにエクスポートします。この形式であれば無料です。

UniGLTFプラグインを使い、Unityに取り込みます。参照: Unityにgltf glbファイルをインポートする方法

Unity上で、MIDIデータから、四角いオブジェクトが上から降るように実装する

ピアノの3Dモデルを配置し、ピアノロールを表示したい位置に四角い板のオブジェクトを仮配置します。板のオブジェクトの横幅と鍵盤の横幅が同じになるように調整します。

この板のオブジェクトの横幅を、52で割った数を、ピアノロールの一つのキーの横幅とします。52の数字は、ピアノの88鍵のうちの白鍵の数です。

板のオブジェクトの位置と、キーの横幅から、MIDIのノートナンバーに対応するオブジェクトの位置情報を計算します。たとえば、ノートナンバー60(真ん中のドの音)の場合は、x:100 y:200 z:300 の位置でオブジェクトを出現させる、といったようにです。

次に、MIDIファイルをUnity上で読み込み、先ほど計算した位置にピアノロールのキーが出現されるよう実装します。今回は、Smfliteというライブラリを使用しました。keijiro/smflite: A minimal class library for handling standard MIDI files on Unity.

これで、ピアノロールのオブジェトが上から降るような動画ができあがります。

Unity上で、演奏動画と一致するカメラのポジションを探して設定する

演奏動画の1コマの画像を、Unity上で前面に表示します。Canvasオブジェクトの下にImageオブジェクトを設置し、Imageには透明度を設定するための「Aspect Ratio Filter」コンポーネントを追加します。

カメラのオブジェクトをマウス操作で移動させるように実装します。参照: https://esprog.hatenablog.com/entry/2016/03/20/033322

カメラを移動できるようになったので、画像とピアノのオブジェクトが一致するように、カメラのポジションを探します。写真から空間座標値を得る方法は、きっとなにか確立された手法があると思うのですが、分からないまま暗中模索で時間がかかり一番苦労しました。

ピアノの3Dモデルを緑色にしてレンダリング

ピアノのオブジェクトに、適当な緑色のマテリアルを設定し、レンダリングします。

このとき、オブジェクトの凸凹な影が映っているため、合成した後の動画にもノイズがでてしまいました。本当は綺麗にしたかったのですが自分にはできませんでした。ピアノの3Dモデルを編集するといった方法があるでしょうか。

動画編集アプリなどで、演奏動画とレンダリングした動画を合成する

自分はCamtasiaの動画編集アプリを使用して合成しました。緑色を削除して合成します。