Ultralytics の SAM2 で狭い部屋でも合成演奏動画を作る


日本の家は狭い。でも複数楽器を弾いてアンサンブル動画を作りたい。そこで SAM2 と Ultralytics を使って人物をセグメンテーションし,複数の演奏動画を合成する仕組みを作った。

背景:狭い部屋でアンサンブル動画を作りたい

日本に住んでいると,どうしても部屋が狭い。楽器をいくつも並べるスペースはほぼない。
一方,私はギター・ベース・ドラム・鍵盤など複数の楽器を弾く,いわゆる multi-instrumentalist だ。

YouTube などでよく見る「一人アンサンブル動画」や「ループパフォーマンス動画」を作りたいと思っても,各楽器を別々のカットで撮影して合成する必要がある。昔ながらのアプローチは,グリーンバック(クロマキー)を使う方法だが,狭い部屋でグリーンバックを展開するのも一苦労だ。

もっと手軽にできないか? → 2024 年に登場した SAM2 (Segment Anything Model 2) を使えば,グリーンバックなし・通常の室内撮影だけで人物をきれいにくり抜けるはず,と考えた。


SAM2 とは

Meta が 2024 年に公開した Segment Anything Model 2 (SAM2) は,画像だけでなく 動画に対してもリアルタイムにセグメンテーション ができるモデルだ。


Ultralytics を使う理由

Meta 公式の SAM2 API を直接使う方法もあるが,依存関係のセットアップが煩雑だったり,API がやや扱いにくい面がある。

そこで Ultralytics を使う。Ultralytics は YOLO シリーズで有名なフレームワークで,最新版では YOLO と SAM を同一の Python API で扱える。

1pip install ultralytics
1from ultralytics import SAM
2
3model = SAM("sam2_b.pt")  # SAM2 Base モデルをロード

これだけで SAM2 が使える。モデルの重みは初回実行時に自動ダウンロードされる。


処理パイプライン

全体の流れは以下のとおりだ。

1入力動画 (各楽器の演奏動画)
23  SAM2 でフレームごとに人物マスクを生成
45  マスクを使って人物領域を切り抜き → RGBA 動画として書き出し
67  背景動画 (or 画像) の上に各パート動画を重ねて合成
89  合成動画の完成

① SAM2 で人物をセグメント

1from ultralytics import SAM
2import cv2
3import numpy as np
4
5model = SAM("sam2_b.pt")
6
7# 最初のフレームでクリックポイントを指定して人物を追跡
8results = model.track(
9    source="guitar_take.mp4",
10    points=[[320, 240]],   # 画面中央付近の人物をクリック
11    labels=[1],            # 1 = foreground
12    stream=True,
13)
14
15masks = []
16for r in results:
17    if r.masks is not None:
18        masks.append(r.masks.data[0].cpu().numpy())
19    else:
20        masks.append(None)

② マスクを使って RGBA 動画を生成

1cap = cv2.VideoCapture("guitar_take.mp4")
2fourcc = cv2.VideoWriter_fourcc(*"mp4v")
3out = cv2.VideoWriter("guitar_masked.mp4", fourcc, 30, (width, height))
4
5for i, mask in enumerate(masks):
6    ret, frame = cap.read()
7    if not ret or mask is None:
8        break
9    alpha = (mask * 255).astype(np.uint8)
10    rgba = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)
11    rgba[:, :, 3] = alpha
12    out.write(rgba)

③ 背景の上に合成

1# 背景画像の上に各パートを alpha blending で重ねる
2def composite(bg, fg_rgba):
3    alpha = fg_rgba[:, :, 3:4] / 255.0
4    fg_rgb = fg_rgba[:, :, :3]
5    return (fg_rgb * alpha + bg * (1 - alpha)).astype(np.uint8)

GPU vs Apple Silicon の推論速度

Google Colab の T4 GPU と MacBook Pro M4 (Apple Silicon) で推論速度を比較したところ,それほど大きな差が出なかった

環境1 フレームあたりの推論時間 (目安)
Google Colab (T4 GPU)約 30〜50 ms
MacBook Pro M4 (MPS)約 40〜60 ms

これはなぜか?Ultralytics 側で モデルの量子化・TensorRT / CoreML への変換・バッチ処理の最適化 など,推論を高速化するための工夫が多数施されているためと考えられる。Apple Silicon の Metal Performance Shaders (MPS) バックエンドも有効活用されている。

実際のところ,今回のユースケース(数十秒〜数分の短い演奏動画)では,どちらの環境でも十分なスループットが出た。


結果

各楽器のテイク動画から人物をくり抜いて合成した結果,グリーンバックなしでも十分きれいに合成できた。

合成演奏動画のキャプチャ (placeholder)

↑ ギター・ベース・ドラムの 3 パートを合成した例(プレースホルダ)

SAM2 によるマスク生成の例 (placeholder)

↑ SAM2 が生成したフレームごとのマスク(プレースホルダ)


まとめ

  • Ultralytics を使えば SAM2 を 1 行でロードでき,依存関係のトラブルなしに使える
  • YOLO による人物検出と SAM2 によるセグメンテーションを 同一 API で組み合わせられる
  • GPU (Colab T4) と Apple Silicon M4 の推論速度は意外なほど近く,M4 Mac だけでも実用的なパイプラインが組める
  • グリーンバックなしの室内撮影から手軽に合成演奏動画が作れるようになった