Submit Search
Upload
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
•
1 like
•
1,431 views
M
mganeko
Follow
tensorflow.js, Chrome Extension をつかってバーチャル背景を作る話。WebRTC Meetup Online #1 の発表資料です。
Read less
Read more
Technology
Report
Share
Report
Share
1 of 32
Download now
Download to read offline
Recommended
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
onozaty
Twitterのsnowflakeについて
Twitterのsnowflakeについて
moai kids
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
Kohsuke Yuasa
TiDBのトランザクション
TiDBのトランザクション
Akio Mitobe
コンテナを止めるな! PacemakerによるコンテナHAクラスタリングとKubernetesとの違いとは
コンテナを止めるな! PacemakerによるコンテナHAクラスタリングとKubernetesとの違いとは
ksk_ha
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
Kazuho Oku
Wireguard 実践入門
Wireguard 実践入門
Kazuhiro Nishiyama
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
Preferred Networks
Recommended
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
onozaty
Twitterのsnowflakeについて
Twitterのsnowflakeについて
moai kids
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
Kohsuke Yuasa
TiDBのトランザクション
TiDBのトランザクション
Akio Mitobe
コンテナを止めるな! PacemakerによるコンテナHAクラスタリングとKubernetesとの違いとは
コンテナを止めるな! PacemakerによるコンテナHAクラスタリングとKubernetesとの違いとは
ksk_ha
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
Kazuho Oku
Wireguard 実践入門
Wireguard 実践入門
Kazuhiro Nishiyama
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
Preferred Networks
Pythonによる黒魔術入門
Pythonによる黒魔術入門
大樹 小倉
実践イカパケット解析
実践イカパケット解析
Yuki Mizuno
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
Kohei Tokunaga
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Masahito Zembutsu
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方
Shohei Koyama
例外設計における大罪
例外設計における大罪
Takuto Wada
Marp Tutorial
Marp Tutorial
Rui Watanabe
545人のインフラを支えたNOCチーム!
545人のインフラを支えたNOCチーム!
Masayuki Kobayashi
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
yoku0825
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
yoku0825
DockerとPodmanの比較
DockerとPodmanの比較
Akihiro Suda
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
Akihiro Suda
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
Yoshinori Matsunobu
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
Kentaro Matsui
initとプロセス再起動
initとプロセス再起動
Takashi Takizawa
PHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったこと
gree_tech
Linux packet-forwarding
Linux packet-forwarding
Masakazu Asama
コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話
Yuta Shimada
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
モノビット エンジン
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Hiro H.
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
mganeko
How to create your own Azure Pipeline's image
How to create your own Azure Pipeline's image
Kazushi Kamegawa
More Related Content
What's hot
Pythonによる黒魔術入門
Pythonによる黒魔術入門
大樹 小倉
実践イカパケット解析
実践イカパケット解析
Yuki Mizuno
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
Kohei Tokunaga
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Masahito Zembutsu
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方
Shohei Koyama
例外設計における大罪
例外設計における大罪
Takuto Wada
Marp Tutorial
Marp Tutorial
Rui Watanabe
545人のインフラを支えたNOCチーム!
545人のインフラを支えたNOCチーム!
Masayuki Kobayashi
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
yoku0825
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
yoku0825
DockerとPodmanの比較
DockerとPodmanの比較
Akihiro Suda
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
Akihiro Suda
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
Yoshinori Matsunobu
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
Kentaro Matsui
initとプロセス再起動
initとプロセス再起動
Takashi Takizawa
PHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったこと
gree_tech
Linux packet-forwarding
Linux packet-forwarding
Masakazu Asama
コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話
Yuta Shimada
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
モノビット エンジン
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Hiro H.
What's hot
(20)
Pythonによる黒魔術入門
Pythonによる黒魔術入門
実践イカパケット解析
実践イカパケット解析
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方
例外設計における大罪
例外設計における大罪
Marp Tutorial
Marp Tutorial
545人のインフラを支えたNOCチーム!
545人のインフラを支えたNOCチーム!
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
DockerとPodmanの比較
DockerとPodmanの比較
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
initとプロセス再起動
initとプロセス再起動
PHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったこと
Linux packet-forwarding
Linux packet-forwarding
コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Similar to Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
mganeko
How to create your own Azure Pipeline's image
How to create your own Azure Pipeline's image
Kazushi Kamegawa
Nano Server First Step
Nano Server First Step
Kazuki Takai
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
irgaly
WebRTCでドラゴンボールごっこ
WebRTCでドラゴンボールごっこ
girigiribauer
Webカメラ画像のリアルタイム識別 / Web Cam Image Recognition with Inception V3
Webカメラ画像のリアルタイム識別 / Web Cam Image Recognition with Inception V3
moto2g
Chromebook 「だけ」で WebRTCを動かそう
Chromebook 「だけ」で WebRTCを動かそう
mganeko
Tizen web app について調べたよ
Tizen web app について調べたよ
Naruto TAKAHASHI
Golang tokyo #7 qtpm
Golang tokyo #7 qtpm
Yoshiki Shibukawa
Mithril
Mithril
Yoshiki Shibukawa
Mvc conf session_5_isami
Mvc conf session_5_isami
Hiroshi Okunushi
機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編
Daiyu Hatakeyama
.NET Coreとツール類の今
.NET Coreとツール類の今
Yuki Igarashi
ToolChainを使った次世代DevOps環境の作り方
ToolChainを使った次世代DevOps環境の作り方
Harada Kazuki
NPAPIを使ったandroid標準ブラウザの拡張方法
NPAPIを使ったandroid標準ブラウザの拡張方法
Naruto TAKAHASHI
Mautic Meetup Tokyo #3 データベース不要CMS:Gravの紹介
Mautic Meetup Tokyo #3 データベース不要CMS:Gravの紹介
Kohei Nishikawa
Fabric + Amazon EC2で快適サポート生活 #PyFes
Fabric + Amazon EC2で快適サポート生活 #PyFes
Sho Shimauchi
Engine Yardで作る NetCommons3のクラウド環境
Engine Yardで作る NetCommons3のクラウド環境
Yusuke Ando
Windows 8 Developers カンファレンス
Windows 8 Developers カンファレンス
Kaoru NAKAMURA
Essentials of container
Essentials of container
Toru Makabe
Similar to Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
(20)
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
How to create your own Azure Pipeline's image
How to create your own Azure Pipeline's image
Nano Server First Step
Nano Server First Step
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East
WebRTCでドラゴンボールごっこ
WebRTCでドラゴンボールごっこ
Webカメラ画像のリアルタイム識別 / Web Cam Image Recognition with Inception V3
Webカメラ画像のリアルタイム識別 / Web Cam Image Recognition with Inception V3
Chromebook 「だけ」で WebRTCを動かそう
Chromebook 「だけ」で WebRTCを動かそう
Tizen web app について調べたよ
Tizen web app について調べたよ
Golang tokyo #7 qtpm
Golang tokyo #7 qtpm
Mithril
Mithril
Mvc conf session_5_isami
Mvc conf session_5_isami
機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編
.NET Coreとツール類の今
.NET Coreとツール類の今
ToolChainを使った次世代DevOps環境の作り方
ToolChainを使った次世代DevOps環境の作り方
NPAPIを使ったandroid標準ブラウザの拡張方法
NPAPIを使ったandroid標準ブラウザの拡張方法
Mautic Meetup Tokyo #3 データベース不要CMS:Gravの紹介
Mautic Meetup Tokyo #3 データベース不要CMS:Gravの紹介
Fabric + Amazon EC2で快適サポート生活 #PyFes
Fabric + Amazon EC2で快適サポート生活 #PyFes
Engine Yardで作る NetCommons3のクラウド環境
Engine Yardで作る NetCommons3のクラウド環境
Windows 8 Developers カンファレンス
Windows 8 Developers カンファレンス
Essentials of container
Essentials of container
More from mganeko
Amazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみた
mganeko
Build Node.js-WASM/WASI Tiny compiler with Node.js
Build Node.js-WASM/WASI Tiny compiler with Node.js
mganeko
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
mganeko
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
mganeko
WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3
mganeko
WebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample update
mganeko
ブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみた
mganeko
WebRTC SFU mediasoup sample
WebRTC SFU mediasoup sample
mganeko
Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2
mganeko
Node.js with WebRTC DataChannel
Node.js with WebRTC DataChannel
mganeko
WebRTC Build MCU on browser
WebRTC Build MCU on browser
mganeko
PeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecorder
mganeko
ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴
mganeko
Webrtc bootcamp handson
Webrtc bootcamp handson
mganeko
WebRTC multitrack / multistream
WebRTC multitrack / multistream
mganeko
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
mganeko
WebRTC multistream
WebRTC multistream
mganeko
Inside WebM
Inside WebM
mganeko
MediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live Streaming
mganeko
Infocom webrtc conference japan
Infocom webrtc conference japan
mganeko
More from mganeko
(20)
Amazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみた
Build Node.js-WASM/WASI Tiny compiler with Node.js
Build Node.js-WASM/WASI Tiny compiler with Node.js
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3
WebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample update
ブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみた
WebRTC SFU mediasoup sample
WebRTC SFU mediasoup sample
Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2
Node.js with WebRTC DataChannel
Node.js with WebRTC DataChannel
WebRTC Build MCU on browser
WebRTC Build MCU on browser
PeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecorder
ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴
Webrtc bootcamp handson
Webrtc bootcamp handson
WebRTC multitrack / multistream
WebRTC multitrack / multistream
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC multistream
WebRTC multistream
Inside WebM
Inside WebM
MediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live Streaming
Infocom webrtc conference japan
Infocom webrtc conference japan
Recently uploaded
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
sugiuralab
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
iPride Co., Ltd.
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
iPride Co., Ltd.
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
osamut
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
Shota Ito
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
sugiuralab
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
Atomu Hidaka
Recently uploaded
(7)
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
1.
Google Meet でも バーチャル背景を使いたい WebRTC
Meetup Online #1 2020.07.16 @massie_g がねこまさし
2.
バーチャル背景とは Web会議システムZoomで注目された、背景を画像や映像に差し替える機能 Microsoft Teams でも最近サポートされたらしい 残念ながら Google
Meet は 未サポート (対応予定、開発中) https://support.google.com/a/table/ 7539891?hl=ja https://support.zoom.us/hc/ja/articles/210707503-バーチャル背景
3.
Google Meet でバーチャル背景を使う方法 仮想カメラソフトを利用すれば可能 ●
Snap Camera ○ Snap Chat が提供する仮想カメラ ○ Lensと呼ばれるエフェクトをダウンロード、利用可能 ○ OSやブラウザからは、外部カメラの 1つとして認識される ○ ※なにやらハードと相性悪いことも ■ 会社のWindows PCで試したら、内臓カメラを認識しなくなった ● OBS Studio + OBS-VirtualCam ● Cam Twist でも、できればブラウザだけで実現したい
4.
ブラウザで実現するための要素 ● 人物部分と背景部分の判定 ● 映像ストリームの取得 ●
既存Webアプリへの介入 ● 細かい処理 全部通信の手間の話です。あしからず
5.
今日の元ネタ 色々な人の取り組みを利用しています。ありがとうございます ● tensorflow.jsとWebRTCを組み合わせて、プライバシー保護のビデオチャットを 作ってみた前編/後編(私の記事) ○ https://qiita.com/massie_g/items/af3f8eb1e2bf5e807ba6 ○
https://qiita.com/massie_g/items/6018861a7d2ca3f3b1de ● Google MeetのWebカメラを加工してみよう!... Chrome Extension ○ https://techblog.securesky-tech.com/entry/2020/04/30/ ● 任意のバーチャル背景を使えるページを作った … body-pix の詳しい処理 ○ https://qiita.com/knok/items/b3eb87769151ac04efeb ● Google Meetでもバーチャル背景を使いたい(私の記事) ○ https://qiita.com/massie_g/items/667627b6d12acc0163af
6.
人物部分と背景部分の判定 tensorflow.js + body-pix
7.
tensorflow.js とは? ● tensorflow
… Google が開発したフレームワーク ○ https://github.com/tensorflow/tensorflow ○ 数値解析や機械学習、ディープラーニング向け ○ 複数マシンで分散処理が可能 ○ python と C++ で実装 ○ 色々な言語から呼び出すためのバインディングを備えている ● tensorflow.js … JavaScritpに移植したもの ○ https://github.com/tensorflow/tfjs ○ 学習済みモデルを利用することが主だが、学習も可能(転移学習など)
8.
body-pix ● body-pix …
tensoflow.js 向けの学習済みモデルの1つ ○ https://github.com/tensorflow/tfjs-models/tree/master/body-pix ○ 画像からの人体検出、部位のセグメンテーション
9.
使ってみる(準備) JSの読み込み <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.2"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/body-pix@2.0"></script> モデルのロード(非同期) let
net = null; async function loadModel() { net = await bodyPix.load(); } loadModel();
10.
使ってみる(検出) function segmentPerson(img, net)
{ const option = { flipHorizontal: false, internalResolution: 'medium', segmentationThreshold: 0.7, maxDetections: 4, scoreThreshold: 0.5, nmsRadius: 20, minKeypointScore: 0.3, refineSteps: 10 }; return net.segmentPerson(img, option); // 非同期、Promiseを返す } segmentPerson(img, net).then(segmentation => { /* … */ })
11.
使ってみる(背景をグレイでマスク) function maskCanvas(canvas, img,
segmentation) { // マスクの作成 const fgColor = { r: 0, g: 0, b: 0, a: 0 }; // 人物部分はマスク透明(alpha=0) const bgColor = { r: 127, g: 127, b: 127, a: 255 }; // 背景部分はグレイ const colorMask = bodyPix.toMask(segmentation, fgColor, bgColor); // マスクを使って描画 const opacity = 1.0; const flipHorizontal = false; const maskBlurAmount = 0; bodyPix.drawMask(canvas, img, colorMask, opacity, maskBlurAmount, flipHorizontal); } 1コマ分の処理 動画ならこれを繰り返す
12.
デモ(時間があれば) 画像 https://mganeko.github.io/bodypix_ayame/image_mask.html カメラ(動画) https://mganeko.github.io/bodypix_ayame/video_mask.html
13.
背景の置き換え body-pix が提供する処理では、背景の置き換えはダイレクトにできない maskの中身を走査しながら、自分でピクセル毎に処理 (1)背景をコピー 背景用画像 合成用Canvas カメラ映像 [0,0,0,1,0,0,
0,0,1,1,1,0, 0,0,0,1,0,0, 0,0,1,1,1,0, ....] 人体セグメンテーション (1次元配列) (2)セグメンテーションが「 1」のピクセルを上書き 人物合成後
14.
セグメント更新と、描画のタイミング バーチャル背景の動画には、2つの処理を継続的に行うことが必要 今回は次の作戦で実行 ● (a) リアルタイム映像から1コマ取り出し、背景と人物を合成して描画 ○
window.requestAnimationFrame() で可能な限り高頻度で呼び出し … 最大 60fps ○ その際に直近の(b)で取得したセグメンテーションを利用 ● (b) 人体セグメンテーションの取得 … 時間がかかる ○ 数十ms~100msかかるので、(a)よりも低頻度で呼び出し ○ 検出時間も一定ではないので、 setInterval()ではなく、毎回setTimeout(10ms) で呼び出し
15.
映像の取得 canvas.captureStream()
16.
body-pixでマスクしたCanvasから、映像を取得 https://developer.mozilla.org/ja/docs/Web/API/HTMLCanvasElement/captureStrea m より
17.
映像と音声の連結 これを PeerConnectionに 渡して通信する
18.
既存Webアプリへの介入 Chrome Extention
19.
これを Google Meet
で使うには? ● ここまでの処理を、自作アプリに組み込むことは可能 ○ tensorflow.js+bodypix → canvas.captureStream() ● これを、既存のGoogle Meetなどの Webアプリで使うには? ○ Google Meetも内部的にはWebRTC(+独自拡張)を利用 ○ navigator.mediaDevices.getUserMedia()で、カメラ映像を取得 ○ RTCPeerConnectionで通信 ■ P2Pでなく、SFUサーバーを経由している ○ JavaScriptの処理を改造できれば良いが ... ? → 諦めていたところ、「Chrome Extension を使え」との天啓アリ Google MeetのWebカメラを加工してみよう! https://techblog.securesky-tech.com/entry/2020/04/30/
20.
やりたいこと getUserMedia()をフック navigator.mediaDevices .getUserMedia() MediaStream PeerConnection カメラ映像
通信
21.
やりたいこと getUserMedia()をフック navigator.mediaDevices .getUserMedia() MediaStream PeerConnection navigator.mediaDevices .getUserMedia() <video>
<Canvas> MediaStream PeerConnection drawImage canvas .captureStream() 関数をフックして 置き換える カメラ映像 通信
22.
manifest.json { "manifest_version" : 2, "content_scripts"
: [ { "matches": [ "https://meet.google.com/*" , ], "js": [ "loader.js" ], "run_at": "document_start" } ], "permissions": [ "https://meet.google.com/" , ], "web_accessible_resources" : [ "cs.js" ] } 対象ページに、コンテンツを差し込む役割 ※対象となるページとは異なるglobalコンテキスト で動く 対象ページのJSよりも先に動かす 対象ページに差し込まれ、同じコンテ キストで動く 対象となるページに JavaScriptを差し込んだり DOM構造をいじったりできる
23.
loader.js の流れ async function
load() { // 差し込むJSファイルを読み込む const res = await fetch(chrome.runtime.getURL('cs.js'), { method: 'GET' }); const js = await res.text(); // スクリプトタグを作って、差し込む const script = document.createElement('script'); script.textContent = js; document.body.insertBefore(script, document.body.firstChild); }
24.
cs.js中身:Hookするコード(概略) // 元の処理を取っておく navigator.mediaDevices._getUserMedia =
navigator.mediaDevices.getUserMedia; // 新しい処理に置き換える navigator.mediaDevices.getUserMedia = function(constraints) { return new Promise((resolve, reject) => { // プロミスを返す navigator.mediaDevices._getUserMedia(constraints) // 元の処理を呼び出す .then(stream => { video.srcObject = stream; // 一旦Videoに表示 video.play(); requestAnimationFrame(_updateCanvasWithMask); // この関数でCanvas描画 const canvasStream = canvas.captureStream(10); // Canvasから映像取得 resolve(canvasStream); // 映像を返す }) .catch(err => reject(err)); }); }
25.
Contents Scriptの動くタイミング ● loader.js
… 対象ページのJSよりも先に動ける ○ "run_at": "document_start" の場合 ● cs.js … (差し込み方によるが) ○ window.onload(), body.onload()よりも先に動くことができる ○ が、bodyなどに直接書かれたスクリプトの方が先に動く ● → Google Meet は、開いた途端にbodyにあるgetUserMedia()が動くので、フック を仕込むのが間に合わない ...万事休す
26.
Google Meet の回避策 ●
カメラoff → カメラon で、映像を再取得している (getUserMediaを呼ぶ) ● そのため、一度手動で off → on してあげれば、フックした処理が動く → めでたし、めでたし
27.
細かい話
28.
track.stop()の伝搬
29.
停止処理の概略 const canvasVideoTrack =
canvasStream.getVideoTracks()[0]; // 元の処理を取っておく canvasVideoTrack._stop = canvasVideoTrack.stop; // 処理を置き換える(hook) canvasVideoTrack.stop = function () { keepAnimation = false; // バーチャル背景映像の更新を行うかどうかのフラグ canvasVideoTrack._stop(); // 元の処理を呼び出す userMediaVideoTrack.stop(); // 元々取得していたカメラ映像を停止 };
30.
スクリーンキャプチャーと同時に使えない件 ● Google Meet
の画面共有は ○ mediaDevices.getDisplayMedia()ではなく ○ mediaDevices.getUserMedia({video:{mandatory:{chromeMediaSource:"desktop"}}}) を利用 ● そのため、今回Extensionでフックした getUserMedia() が呼ばれる ○ カメラの代わりに画面キャプチャーを取得 ○ 人物が映っていない →すべて背景と判定→画像に置き換えられてしまう … ● 慌ててバイパス処理を昨日(7/13)追加
31.
Thank you! ● Google
Meetでもバーチャル背景を使いたい(私の記事) ○ https://qiita.com/massie_g/items/667627b6d12acc0163af ● Chrome ウェブストア でも公開中 ○ https://chrome.google.com/webstore/detail/chrome-virtual-camera/dphplfdpilhebmikohheeiblila jfmin/ ○ ※注意:もともとtensorflow.js を使っているページではうまく動かない ○ ※スクリーンキャプチャーのバイパス処理は未反映 ● GitHubでコード公開 ○ https://github.com/mganeko/chrome_virtual_camera ○ Chromeの「拡張機能」ページで、デベロッパーモードをオン ○ ダウンロードした拡張機能を読み込むと使える ○ manifest.jsonを編集すれば、好きなページで利用可能
32.
https://chrome.google.com/webstore/detail/chrome-virtual-camera/dphplfdpilhebmikohheeiblilajfmin/
Download now