Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Canvasで簡易背景ぼかしをやってみた
Search
mganeko
September 22, 2023
Technology
0
760
Canvasで簡易背景ぼかしをやってみた
WebRTC Meetup #25 の発表資料です
mganeko
September 22, 2023
Tweet
Share
More Decks by mganeko
See All by mganeko
WebCodecsの実装状況 / Status of WebCodecs
mganeko
0
1.2k
M1 Macと将棋AIとUSI
mganeko
1
1.2k
Small Tips to use Bun with WebSocket Server and WebAssembly Modules
mganeko
0
5k
Build Node.js–WASM/WASI tiny compiler with Node.js
mganeko
0
660
Node.js x Chrome headless for WebRTC MCU
mganeko
1
3.2k
Extend User Experience of WebRTC with Cool Sensor Devices
mganeko
0
600
Playing with OSS WebRTC SFU meidasoup (update for v1.2)
mganeko
0
760
Build WebRTC iOS Gateway on Browser
mganeko
0
1.2k
Playing with OSS WebRTC SFU meidasoup
mganeko
0
560
Other Decks in Technology
See All in Technology
株式会社EventHub・エンジニア採用資料
eventhub
0
4.3k
Two Blades, One Journey: Engineering While Managing
ohbarye
3
990
Windows の新しい管理者保護モード
murachiakira
0
200
JavaにおけるNull非許容性
skrb
1
2.2k
AWS Well-Architected Frameworkで学ぶAmazon ECSのセキュリティ対策
umekou
2
110
Cracking the Coding Interview 6th Edition
gdplabs
14
28k
わたしのOSS活動
kazupon
2
340
「正しく」失敗できる チームの作り方 〜リアルな事例から紐解く失敗を恐れない組織とは〜 / A team that can fail correctly
i35_267
2
720
Amazon Aurora のバージョンアップ手法について
smt7174
1
130
利用終了したドメイン名の最強終活〜観測環境を育てて、分析・供養している件〜 / The Ultimate End-of-Life Preparation for Discontinued Domain Names
nttcom
2
360
抽象化をするということ - 具体と抽象の往復を身につける / Abstraction and concretization
soudai
27
15k
PHPで印刷所に入稿できる名札データを作る / Generating Print-Ready Name Tag Data with PHP
tomzoh
0
180
Featured
See All Featured
Writing Fast Ruby
sferik
628
61k
Rails Girls Zürich Keynote
gr2m
94
13k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
27
1.6k
Documentation Writing (for coders)
carmenintech
67
4.6k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.7k
The Language of Interfaces
destraynor
156
24k
Docker and Python
trallard
44
3.3k
The Pragmatic Product Professional
lauravandoore
32
6.4k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Into the Great Unknown - MozCon
thekraken
35
1.6k
It's Worth the Effort
3n
184
28k
Building Your Own Lightsaber
phodgson
104
6.2k
Transcript
Canvasで簡易背景ぼかしを やってみた WebRTC Meetup #25 2023.09.22 @massie_g / がねこまさし
背景ぼかし • Web会議ツールで必須の機能 ◦ AIを使って人の輪郭を抽出 ◦ 背景をぼかしたり、仮想背景に差し替えたりする ◦ 良いところ ▪
人が動いても、(ほぼ)追従する ◦ 辛いところ ▪ 結構マシンパワーが必要、ファンが唸ったりする • 原始的な背景ぼかしをやってみた ◦ 良いところ ▪ 軽い ▪ 作るのが手軽 ◦ 辛いところ … 人が頑張る
カメラ映像取得から、通信まで • navigator.mediaDevices.getUserMedia() で、映像/音声を取得 ◦ MediaStreamを取得、MediaStreamTrack (Video, Audio) をもつ •
RTCPeerConnectionのインスタンスを生成 • そのインスタンスに、 addTrack()でMediaStreamTrackを追加 • その後、シグナリングを行い通信を開始 navigator.mediaDevices.getUserMedia() MediaStream MediaStreamTrack MediaStreamTrack video audio RTCPeerConnection addTrack() addTrack()
映像の加工はCanvasで • 取得したカメラ映像(MediaStream)を<video>要素で表示 • drawImage()をつかって<canvas>要素に描画 ◦ ※requestAnimationFrame()を使って繰り返す • <canvas>要素から、captureStream()を使って映像(MediaStream)を取得 MediaStream
MediaStreamTrack MediaStreamTrack video audio RTCPeerConnection addTrack() <video> VideoElement <canvas> Canvas drawImage() captureStream() MediaStream MediaStreamTrack video addTrack() requestAnimationFrame()で繰り返す
背景の簡易ぼかし • まじめなぼかし処理ではなく • 縮小→拡大による簡易ぼかし video canvas workCanvas ※以前どこかの記事で見かけたやり方です。元ネタのページは忘れてしまいました
縮小、拡大で簡易ぼかし function drawMosaicBackground () { // モザイクのブロックのサイズ blockWidth, blockHeight をあらかじめ指定
// 縮小後の画像サイズ const smallWidth = video.videoWidth / blockWidth; const smallHeight = video.videoHeight / blockHeight; // 画像を縮小して描画 ctxWork.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, // src 0, 0, smallWidth, smallHeight //dest ); // 画像を再拡大 // zoomLeft, zoomTop, zoomWidth, zoomHeight は計算しておく ctx.drawImage(canvasWork, 0, 0, smallWidth, smallHeight, // src zoomLeft, zoomTop, zoomWidth, zoomHeight //dest ); }
Demo https://mganeko.github.io/webrtc_begins/background_mosaic.html
顔映像の切り抜き • 固定位置を切り抜く ◦ AIモデルは利用していないので、顔検出や追跡はできない ◦ 自分で頑張ってその位置に顔を持って行く video canvas
円形にくりぬいて描画 function drawClipedVideo() { ctx.save(); // コンテキストの情報を保存 /* -- 円を指定
--*/ // r:半径、円の中心(centerX, centerY) を指定しておく ctx.beginPath(); ctx.arc(centerX, centerY, r, 0, Math.PI * 2, false); ctx.clip(); // 画像を描画 // srcR, srcLeft, srcTop, srcWidth, srcHeight を計算しておく ctx.drawImage(video, srcLeft, srcTop, srcWidth, srcHeight, // src (left, top, width, height) centerX - r, 0, r * 2, r * 2, // dest (left, top, width, height) ); ctx.restore(); // コンテキストの情報を復元 }
Demo https://mganeko.github.io/webrtc_begins/camera_crop.html
合体 • 縮小→拡大による簡易ぼかし • 顔の切り抜き video canvas workCanvas
requestAnimationFrame()で連続描画 let requestId = null; // 描画開始 function startDraw() {
requestId = requestAnimationFrame(draw); } // 描画停止 function stopDraw() { if (requestId) { cancelAnimationFrame(requestId); requestId = null; } } // 描画 function draw() { drawMosaicBackground(); drawClipedVideo(); requestId = requestAnimationFrame(draw); }
Demo • video は display:none • workCanvasは OffScreenCanvasに • canvasもdisplay:none
https://mganeko.github.io/webrtc_begins/ https://mganeko.github.io/webrtc_begins/crop_mosaic.html https://mganeko.github.io/webrtc_begins/crop_mosaic_slim.html
Demo Skyway 経由の P2P通信 ※ファイルはローカル(未公開)
まとめ、注意点 • Canvasを使うと、映像を加工して、さらに映像として取り出すことができる ◦ Chrome/Edge, Firefox, Safariで利用可能 • AIモデルを使えば、人の輪郭も抽出できる ◦
例) body-segmentation ▪ https://github.com/tensorflow/tfjs-models/tree/master/body-segmentation • requestAnimationFrame() 利用時の注意 ◦ ブラウザのタブ/ウィンドウが完全に非表示になると ◦ → アニメーションイベントが発生しない ◦ → canvasへの描画が止まる ◦ → 映像が止まる • この欠点を回避するには、MediaStreamTrackProcessorが利用できる ◦ ※Chrome/Edgeのみ
参考 • GitHub でソースを見る ◦ https://github.com/mganeko/webrtc_begins ◦ camera_crop.html … カメラを丸く切り取る
◦ background_mosaic.html … 背景を簡易ぼかし ◦ crop_mosaic.html … カメラ切り抜きと背景ぼかしの合成 ◦ crop_mosaic_slim.html … 余計な要素を隠してすっきりさせたもの • GitHub Pages で試す ◦ https://mganeko.github.io/webrtc_begins/