Python/OpenCVでGStreamerを使って仮想のWebカメラを作る
画面キャプチャをやってみた先ほどの記事に引き続き、Python/OpenCV + GStreamerで遊んでみた記事です。 今度はv4l2sinkというプラグインを使って仮想Webカメラを作ってみました。
組み合わせるとOBSやFaceRigのように画面キャプチャやWebカメラの入力を混ぜて、結果をWebカメラとして出力するソフトを作れるはず。
v4l2loopbackの準備をする
まずは、v4l2loopbackをインストールします。 Gentooなら以下のような感じで。
$ sudo emerge v4l2loopback
これは特別なコンパイルオプションとか必要無いので、Ubuntuでも以下のように普通にaptで入るっぽい。
$ sudo apt install v4l2loopback-dkms
インストール出来たら、カーネルモジュールの読み込みを行ないます。
$ sudo modprobe v4l2loopback exclusive_caps=1
exclusive_caps
はChromeとかで認識させるために必要っぽい。
一時的なら上記のコマンドだけで大丈夫ですが、再起動後も使いたい場合は永続化の設定をしてください。 永続化の方法は環境に合わせてよしなに。
v4l2loopbackの読み込みが出来たら、/dev/video0
とかそんな名前で仮想Webカメラが追加されているはずです。
番号を変えたいときはmodprobeするときに以下のようにオプションを渡します。
$ sudo modprobe v4l2loopback video_nr=42,123 exclusive_caps=1
この例だと、/dev/video42
と/dev/video123
の二つを生やします。
以下の例では/dev/video42
にしたということにして進めます。
GStreamerだけでv4l2sinkの動作確認
v4l2loopbackの準備が出来たので、一旦gst-launchコマンドで動作確認をしてみます。
$ gst-launch-1.0 videotestsrc ! videoconvert ! videorotate ! video/x-raw,format=I420 ! v4l2sink device=/dev/video42
上手くいけば、これで/dev/video42
にテスト用の映像が流れているはずです。
mplayerがインストールされていれば、以下のコマンドで流れている映像を確認出来ます。 もちろんそれ以外のWebカメラの映像を見れるソフトでも可。
$ mplayer tv:// device=/dev/video42
Pythonからv4l2sinkに出力する
GStreamerからキャプチャしたときと同じで、gst-launchコマンドに渡したのと同じようなものを渡せばOKです。
さきほどテスト用に使ったvideotestsrc
の代わりに、今度はappsrc
を映像ソースとして使います。
これがOpenCVからの出力になるイメージ。
import cv2
import numpy
out = cv2.VideoWriter(
'appsrc ! videoconvert ! videoscale ! video/x-raw,format=I420 ! v4l2sink device=/dev/video42',
0, # 出力形式。今回は0で。
30, # FPS
(320, 240), # 出力画像サイズ
True, # カラー画像フラグ
)
while cv2.waitKey(1) != 27:
img = numpy.random.randint(0, 255, (240, 320, 3), numpy.uint8) # いわゆる砂嵐画像を生成
cv2.imshow('preview', img)
out.write(img)
複雑な映像を用意するのが面倒だったので、乱数で砂嵐映像を生成して流し込んでみました。
実行すると、プレビュー用にウィンドウが開いてGStreamerに長しているものと同じ砂嵐が表示されるはずです。
この状態で先ほどと同じ方法で/dev/video0
を確認すると、同じ映像が見れるはずです。
これでいつでもビデオ通話の相手に砂嵐を送ることが出来ますね(?)
参考: