LoginSignup
5
7

More than 1 year has passed since last update.

WebRTCで顔認識+バーチャル背景

Last updated at Posted at 2020-05-02

agoraがよくわかる!無料セミナー実施中!>

zoomのバーチャル背景がバズっていますが、WebRTCでも顔認識や体の認識ができるOSSがあるので試してみました。
今回は顔だけ認識させて、顔の部分だけ映像として生成するサンプルになります。
ブラウザで顔+体を認識させるには処理能力的に限界がありそうで、実質顔だけ認識させるのが現実的な実装のように思います。

利用するライブラリ

今回、顔の認識についてはpico.jsを利用しました。
その他にはclmtrackrもよく知られているようです。

完成イメージ

スクリーンショット_0002-05-03_0_28_58.png
canvasの背景として画像をセットし、顔認識できた範囲に対して円でくり抜きをしています。

サンプルコードはこちらに公開しています。

コードの説明

主なポイントは4つです。
・Webカメラの映像をcanvasに描画
・カメラ映像を解析
・顔の範囲を円でくり抜き
・配信する映像ソースとして設定

Webカメラの映像をcanvasに描画

index.html

navigator.mediaDevices.getUserMedia({ auduo: false, video: { width: videoSource.width, height: videoSource.height } }).then(stream => {
  videoSource.srcObject = stream;
  videoSource.onloadedmetadata = function () {
    drawLoop();
  };
});
//中略
context.globalCompositeOperation = 'source-over';
context.drawImage(videoSource, 0, 0, videoSource.width, videoSource.height);

WebRTCではおなじみのgetUserMediaでカメラ映像を取得し、canvasに描画します。

カメラ映像を解析

index.html
dets = pico.run_cascade(image, facefinder_classify_region, params);
dets = update_memory(dets);
dets = pico.cluster_detections(dets, 0.2);

このあたりは本家のコードをそのまま利用しています。

顔の範囲を円でくり抜き

index.html
context.globalCompositeOperation = 'destination-in';

if(dets.length >= 1 && dets[0][3] > qthresh){
  dx = dets[0][1];
  dy = dets[0][0];
  radius = dets[0][2]/2*0.8;//積極的に背景を隠す
  context.beginPath();
  context.arc(dx, dy, radius, 0, Math.PI*2, false);
  context.fill();
}else{
  context.beginPath();
  context.arc(dx, dy, radius, 0, Math.PI*2, false);
  context.fill();
}

destination-inは「重なった領域のみが描画される」という設定になります。
又、背景を隠すという意味で円の半径も解析値より0.8倍程度に補正をかけています。

配信する映像ソースとして設定

index.html
rtc.maskedStream = canvas.captureStream(15);
//中略
rtc.localStream = AgoraRTC.createStream({
  streamID: rtc.params.uid,
  audio: true,
  video: true,
  screen: false,
  microphoneId: option.microphoneId,
  videoSource: rtc.maskedStream.getVideoTracks()[0]
  //cameraId: option.cameraId
})

こちらはagoa.io SDKのAPI部分になります。canvasのストリームを取得して、videoSourceのパラメータとして設定しています。

微妙に残った課題

今回の実装方法では背景画像について送信するストリームに乗ってきません。実際、もう少しcanvas部分に手を加えれば可能かもしれません。
その他の方法としては利用している背景画像のURLを相手にも通知してcssで表示させるというやり方になります。

最後に

agora.ioに関するお問い合わせはこちらから
agoraがよくわかる!無料セミナー実施中!

スクリーンショット 0001-08-15 13.41.56.png

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7