TL;DR
ソースコードはこちら!
はじめに
今回は以前のこの記事を使って、実際にWEB会議などで自前で実装したフィルターをかけた状態の画像を使ってみよう!
前のものに数行追加すればできる話ではあるが、今回は別のソフトが必要になってくるので、別途インストールが必要。
考え方としては画像処理を行った結果を仮想カメラに渡し、WEB会議ではその仮想カメラを利用すること。
手順
今回のフォルダ構成は以前の記事と同じで、プログラムの大まかな処理は下記の通り:
- Configの読み込む
- Mediapipeのインスタンス化
- カメラからの画像取得
- フィルター適用
- 結果を仮想カメラへ送信する
OBSについて
OBSとはオーペンソースの仮想カメラのソフトで、ゲーム中継や動画配信によく使われている。使い方は様々だが、今回は「仮想カメラ」として利用する。
まずはダウンロードして、インストールしよう!
ツール
OBSとpythonを連携させるため、pyvirtualcamというライブラリーを利用する。
まずはインストール
$ pip install pyvirtualcam
この記事は非常に参考になったので、ぜひご参考まで!
ソースコード
ソースコードはほとんど前回と同じだが、今回は仮想カメラを利用するので、それをクラス化しよう
import pyvirtualcam
class VirtualCamera():
def __init__(self, width, height, fps) -> None:
self.v_cam = pyvirtualcam.Camera(width=width, height=height, fps=fps)
def _send(self, image):
self.v_cam.send(image)
self.v_cam.sleep_until_next_frame()
次に既存カメラクラス(class Camera)の中に仮想カメラを起動しする。
class Camera():
# 画像サイズを同調させるため、予め横軸を定義する。
def __init__(self, index, config, detector, width:int=1920, height:int=1080, fps:int=30) -> None:
self.config = config
self.detector = detector
self.width = width
self.height = height
self.fps = fps
self.start(index)
def start(self, index) -> None:
self.cap = cv2.VideoCapture(index)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
success, frame = self.cap.read()
if not success:
logger.error(f"Camera not successful: video input: {index}")
sys.exit()
self.mask = np.zeros((frame.shape[0], frame.shape[1], 3), dtype=np.uint8)
# 仮想カメラを始動する。
self.v_cam = VirtualCamera(width=self.width, height=self.height, fps=self.fps)
最後に画像処理の結果を送信する。
def capture(self) -> None:
logger.info("Catpuring images from video input... (press 'q' to exit.)")
while True:
_, frame = self.cap.read()
frame.flags.writeable = False
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.detector(frame)
frame.flags.writeable = True
frame, mask = self.detector.post_processing(self.mask, self.config.yaml_cfg)
mask = cv2.flip(mask, 1)
# 結果を送信する。
self.v_cam._send(frame)
# マスクを表示する。
mask = cv2.resize(mask, dsize=(400, 320))
cv2.imshow("mask", cv2.cvtColor(mask, cv2.COLOR_BGR2RGB))
if cv2.waitKey(1) & 0xFF == ord('q'):
break
修正はこれだけ!
これでフィルターをかけた画像が仮想カメラへ送信され、あとは実際のWEB会議でその仮想カメラを選択するのみ!
詳細なやり方は割愛させていただくが、USBカメラを利用する時と同じである。
デモ
WEB会議で仮想カメラ(OBSカメラ)を選択する。
プログラムを実行する。
あとがき
今回は単純に前回のものに加え、仮想カメラを利用することで、WEB会議などで自前のフィルターを使えるようになった。
ぜひ既存するものを活かして、身の回りのことをスマートかつ面白くしよう!