OBS StudioのウィンドウキャプチャはWSL2のopencv-pythonで出力したウィンドウもキャプチャ可能でした

はじめに

Web会議の際にWebカメラからの入力を加工したい時があります。

例えばZoomを使用している時はZoomに組み込まれた「バーチャル背景設定」で人物以外の背景をぼかしたり好みの写真に切り替えたりすることが可能です。

でも、それではなんだかつまらないです。

自分でカメラからの入力を加工してWeb会議に参加したいというのが今回の動機です。

いろいろ方法はあると思いますが今回はOBS StudioとPythonOpenCVとPyTorch)を使います。

OBS StudioとPythonの両方をWindowsで実行する場合には「pyvirtualcam」というモジュールを使用するとできるようです。

今回PythonはWSL2上で実行します。Windows上のOBS Studioとどう連携すればよいかあれこれ考えました。

行きついた方法は普通にウィンドウ出力してそれをOBS Studioでキャプチャするという簡単なものでした。

WSL2でカメラを使う方法はこちらを参照して下さい。

iPhoneなどをカメラとして使用する場合→こちら
WebカメラやPC付属のカメラを使用する場合→こちら

方法

OBS StudioとOBS Virtualcamのインストール

こちらからOBS Studioをインストール(Ver 27.1.3)
こちらからOBS Virtualcamをインストール(Ver 2.0.5)

カメラからの入力を加工して表示する

この部分のみWSL2上のPythonでの作業になります。

今回はこちらを使わせて頂きました。
github.com
事前準備として「torch」「torchvision」「opencv-python」をインストールします。
すべてpipでインストール可能です。

pip install torch==1.10.2+cu113 torchvision==0.11.3+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html
pip install opencv-python

実行するPythonスクリプトは以下のようになります。

import torch
from  torchvision import transforms
import cv2
import numpy as np

device = 'cuda' if torch.cuda.is_available() else 'cpu'

net = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="paprika")
net.eval().to(device)

cap=cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()

    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    img_tensor = transforms.ToTensor()(frame).unsqueeze(0)
    img_tensor = -1 + 2 * img_tensor

    with torch.no_grad():
        out = net(img_tensor.to(device))

    out= out[0].to('cpu').numpy()
    out = ((out + 1) * 127.5).clip(0, 255).astype('uint8')
    out = np.transpose(out, (1, 2, 0))

    out = cv2.cvtColor(out, cv2.COLOR_BGR2RGB)

    cv2.imshow('animegan2', out)

    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

OBS Studioでウィンドウキャプチャ

ソースの追加で「ウィンドウキャプチャ」を選択します。
f:id:touch-sp:20220202095526p:plain:w400



適当な名前を付けて新規作成します。
f:id:touch-sp:20220202113643p:plain:w400



ウィンドウは適切なものを選択。
キャプチャ方法は「Windows 10(1903以降)」を選択。
今回選択したウィンドウは「[mstsc.exe] animegan2(Ubuntu-20.04)」でした。
f:id:touch-sp:20220202100513p:plain:w400

OBS Studioの設定

「編集」>「変換」>「画面に合わせる」を選択します。
f:id:touch-sp:20220202105709p:plain:w400



次に「編集」>「変換」>「変換の編集」を選択します。
f:id:touch-sp:20220202105721p:plain:w400



クロップの項目を左 40、右 40、上 90、下 90にします。それによってウィンドウの枠が消せます。
f:id:touch-sp:20220202105736p:plain:w400

VirtualCamの開始

「ツール」>「VirtualCam」を選択して「Start」を押します。
f:id:touch-sp:20220202110146p:plain:w400
f:id:touch-sp:20220202110158p:plain:w400



ここまで来ると後はZoomなどで利用するカメラとしてOBS-Cameraを指定するだけで問題なく動作すると思います。

注意

GPUがないとカクカクになると思います。
GPU搭載ノートPCで実行するとそれなりにファンが回ってうるさいです。会議に支障をきたすかも(笑)。
GPU搭載デスクトップPCで使用することをお勧めします。
最近は声以外のノイズを消してくれるかしこいマイクもあるようですが。

動作環境

WSL2とCUDA Toolkitの設定はこちらを参照して下さい。

Windows 11
Ubuntu 20.04 on WSL2

Python 3.8.10
CUDA Toolkit 11.3
autogluon.core==0.3.1
autograd==1.3
bcrypt==3.2.0
boto3==1.20.46
botocore==1.23.46
certifi==2021.10.8
cffi==1.15.0
charset-normalizer==2.0.11
click==8.0.3
cloudpickle==2.0.0
ConfigSpace==0.4.19
cryptography==36.0.1
cycler==0.11.0
Cython==0.29.27
dask==2022.1.1
dill==0.3.4
distributed==2022.1.1
fonttools==4.29.1
fsspec==2022.1.0
future==0.18.2
graphviz==0.19.1
HeapDict==1.0.1
idna==3.3
Jinja2==3.0.3
jmespath==0.10.0
joblib==1.1.0
kiwisolver==1.3.2
locket==0.2.1
MarkupSafe==2.0.1
matplotlib==3.5.1
msgpack==1.0.3
numpy==1.21.5
opencv-python==4.5.5.62
packaging==21.3
pandas==1.4.0
paramiko==2.9.2
partd==1.2.0
Pillow==9.0.0
pkg_resources==0.0.0
psutil==5.9.0
pycparser==2.21
PyNaCl==1.5.0
pyparsing==3.0.7
python-dateutil==2.8.2
pytz==2021.3
PyYAML==6.0
requests==2.27.1
s3transfer==0.5.0
scikit-learn==0.24.2
scipy==1.6.3
six==1.16.0
sortedcontainers==2.4.0
tblib==1.7.0
threadpoolctl==3.1.0
toolz==0.11.2
torch==1.10.2+cu113
torchvision==0.11.3+cu113
tornado==6.1
tqdm==4.62.3
typing_extensions==4.0.1
urllib3==1.26.8
zict==2.0.0