対顔弾幕、つまりビデオ画面内のキャラクターを遮らずに大量の弾幕が飛び交い、キャラクターの背後から浮遊しているように見えます。
機械学習は数年前から普及していますが、多くの人はこれらの機能がブラウザでも実行できることを知りません;
この記事では、ビデオの集中砲火における実践的な最適化プロセスを紹介します。記事の最後に、このソリューションが適用できるいくつかのシナリオについて説明し、いくつかのアイデアが生まれることを期待しています。
mediapipe デモ(https://google.github.io/mediapipe/)は、
主流の対顔弾幕実装原理を示します
オンデマンド
up ビデオのアップロード
サーバーのバックグラウンド計算により、ビデオ画面のポートレート領域が抽出され、SVG ストレージに変換されます
クライアントがビデオを再生している間、サーバーからsvgをダウンロードします 弾幕と組み合わせると、ポートレートエリアには弾幕が表示されません
ライブブロードキャスト
- アンカーがストリームをプッシュすると、ポートレートエリアがストリームから抽出されますリアルタイムで画面 (ホスト デバイス) を表示し、svg に変換します
- svg データをビデオ ストリーム (SEI) にマージし、ストリームをサーバーにプッシュします #クライアントが再生すると同時に、ビデオ、ビデオ ストリーム (SEI) から SVG を解析します。
- 箇条書きで SVG をコンパイルします。画面合成、ポートレート領域には弾幕が表示されません。
- 機械学習オープンソース ライブラリを使用して、ボディ セグメンテーション (https://github.com/tensorflow/tfjs) など、ビデオ画像からポートレートの輪郭をリアルタイムで抽出します。 -models/blob/master/body-segmentation/README.md)
- ポートレートのアウトラインを画像にエクスポートし、弾幕レイヤーのマスク画像を設定します (https://developer.mozilla.org/) zh-CN/docs/ Web/CSS/mask-image)
- 実装が簡単; 必要なビデオタグは 1 つだけ パラメータ、マルチエンド調整の必要なし
- #ネットワーク帯域幅の消費なし
- #欠点:
理論上のパフォーマンス限界は従来のソリューションよりも劣っており、ネットワーク リソースのパフォーマンス リソースを交換するのと同等です
- 直面する問題
BlazePose (https://github.com/tensorflow/tfjs-models/blob/master/pose-detection/src/blazepose_mediapipe/README.md)
戻りデータ構造の例
[{score: 0.8,keypoints: [{x: 230, y: 220, score: 0.9, score: 0.99, name: "nose"},{x: 212, y: 190, score: 0.8, score: 0.91, name: "left_eye"},...],keypoints3D: [{x: 0.65, y: 0.11, z: 0.05, score: 0.99, name: "nose"},...],segmentation: {maskValueToLabel: (maskValue: number) => { return 'person' },mask: {toCanvasImageSource(): ...toImageData(): ...toTensor(): ...getUnderlyingType(): ...}}}]MediaPipe SelfieSegmentation (https://github.com/tensorflow/tfjs-models/blob/) master /body-segmentation/src/selfie_segmentation_mediapipe/README.md) 精度は優れており (効果は BlazePose モデルと一致しています)、CPU 使用率は BlazePose モデルよりも約 15% 低く、パフォーマンスは優れていますが、返されるデータには手足が含まれていません。 ポイント情報返されるデータ構造の例
{maskValueToLabel: (maskValue: number) => { return 'person' },mask: {toCanvasImageSource(): ...toImageData(): ...toTensor(): ...getUnderlyingType(): ...}}最初のバージョンの実装MediaPipe SelfieSegmentation モデルの公式実装を参照してください ( https://github.com/tensorflow/tfjs-models/blob /master/body-segmentation/README.md#bodysegmentationdrawmask)、最適化しないと、CPU が約 70% を占有します
const canvas = document.createElement('canvas')canvas.width = videoEl.videoWidthcanvas.height = videoEl.videoHeightasync function detect (): Promise<void> {const segmentation = await segmenter.segmentPeople(videoEl)const foregroundColor = { r: 0, g: 0, b: 0, a: 0 }const backgroundColor = { r: 0, g: 0, b: 0, a: 255 } const mask = await toBinaryMask(segmentation, foregroundColor, backgroundColor) await drawMask(canvas, canvas, mask, 1, 9)// 导出Mask图片,需要的是轮廓,图片质量设为最低handler(canvas.toDataURL('image/png', 0)) window.setTimeout(detect, 33)} detect().catch(console.error)</void>
抽出頻度を減らしますパフォーマンスとエクスペリエンスのバランスを調整します。一般的なビデオは 30FPS ですが、弾幕マスク (以下、マスクと呼びます) の更新頻度を 15FPS に下げてみてください。これはエクスペリエンスの観点からはまだ許容範囲です。
window.setTimeout(detect, 66) // 33 => 66At今回は、CPU が約 50% を占有します。パフォーマンスのボトルネックを解決します
フレーム グラフを分析すると、パフォーマンスのボトルネックが次の場所にあることがわかります。 toBinaryMask と toDataURL
async function detect (): Promise<void> {const segmentation = await segmenter.segmentPeople(videoEl) context.clearRect(0, 0, canvas.width, canvas.height)// 1. 将`ImageBitmap`绘制到 Canvas 上context.drawImage(// 经验证 即使出现多人,也只有一个 segmentationawait segmentation[0].mask.toCanvasImageSource(),0, 0,canvas.width, canvas.height)// 2. 设置混合模式context.globalCompositeOperation = 'source-out'// 3. 反向填充黑色context.fillRect(0, 0, canvas.width, canvas.height)// 导出Mask图片,需要的是轮廓,图片质量设为最低handler(canvas.toDataURL('image/png', 0)) window.setTimeout(detect, 66)}</void>ステップ 2 と 3 は、CSS (マスクイメージ) と連携するために、ポートレート領域の外側のコンテンツを黒で塗りつぶす (逆塗りつぶし ImageBitmap) と同等です (マスクイメージ)。 Only when 弾幕は、ポートレート領域に浮かんだときにのみ表示されます (ターゲット効果の正反対)。
globalCompositeOperation MDN(https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation)
此时,CPU 占用 33% 左右
多线程优化
我原先认为toDataURL是由浏览器内部实现的,无法再进行优化,现在只有优化toDataURL这个耗时操作了。
虽没有替换实现,但可使用 OffscreenCanvas (https://developer.mozilla.org/zh-CN/docs/Web/API/OffscreenCanvas)+ Worker,将耗时任务转移到 Worker 中去, 避免占用主线程,就不会影响用户体验了。
并且ImageBitmap实现了Transferable接口,可被转移所有权,跨 Worker 传递也没有性能损耗(https://hughfenghen.github.io/fe-basic-course/js-concurrent.html#%E4%B8%A4%E4%B8%AA%E6%96%B9%E6%B3%95%E5%AF%B9%E6%AF%94)。
// 前文 detect 的反向填充 ImageBitmap 也可以转移到 Worker 中// 用 OffscreenCanvas 实现, 此处略过 const reader = new FileReaderSync()// OffscreenCanvas 不支持 toDataURL,使用 convertToBlob 代替offsecreenCvsEl.convertToBlob({type: 'image/png',quality: 0}).then((blob) => {const dataURL = reader.readAsDataURL(blob)self.postMessage({msgType: 'mask',val: dataURL})}).catch(console.error)
可以看到两个耗时的操作消失了
此时,CPU 占用 15% 左右
降低分辨率
继续分析,上图重新计算样式(紫色部分)耗时约 3ms
Demo 足够简单很容易推测到是这行代码导致的,发现 imgStr 大概 100kb 左右(视频分辨率 1280x720)。
danmakuContainer.style.webkitMaskImage = `url(${imgStr})
通过canvas缩小图片尺寸(360P甚至更低),再进行推理。
优化后,导出的 imgStr 大概 12kb,重新计算样式耗时约 0.5ms。
此时,CPU 占用 5% 左右
启动条件优化
虽然提取 Mask 整个过程的 CPU 占用已优化到可喜程度。
当在画面没人的时候,或没有弹幕时候,可以停止计算,实现 0 CPU 占用。
无弹幕判断比较简单(比如 10s 内收超过两条弹幕则启动计算),也不在该 SDK 实现范围,略过
判定画面是否有人
第一步中为了高性能,选择的模型只有ImageBitmap,并没有提供肢体点位信息,所以只能使用getImageData返回的像素点值来判断画面是否有人。
画面无人时,CPU 占用接近 0%
发布构建优化
依赖包的提交较大,构建出的 bundle 体积:684.75 KiB / gzip: 125.83 KiB
所以,可以进行异步加载SDK,提升页面加载性能。
- 分别打包一个 loader,一个主体
- 由业务方 import loader,首次启用时异步加载主体
这个两步前端工程已经非常成熟了,略过细节。
运行效果
总结
过程
- 选择高性能模型后,初始状态 CPU 70%
- 降低 Mask 刷新频率(15FPS),CPU 50%
- 重写开源库实现(toBinaryMask),CPU 33%
- 多线程优化,CPU 15%
- 降低分辨率,CPU 5%
- 判断画面是否有人,无人时 CPU 接近 0%
CPU 数值指主线程占用
注意事项
- 兼容性:Chrome 79及以上,不支持 Firefox、Safari。因为使用了OffscreenCanvas
- 不应创建多个或多次创建segmenter实例(bodySegmentation.createSegmenter),如需复用请保存实例引用,因为:
- 创建实例时低性能设备会有明显的卡顿现象
- 会内存泄露;如果无法避免,这是mediapipe 内存泄露 解决方法(https://github.com/google/mediapipe/issues/2819#issuecomment-1160335349)
经验
- 优化完成之后,提取并应用 Mask 关键计算量在 GPU (30%左右),而不是 CPU
- 性能优化需要业务场景分析,防挡弹幕场景可以使用低分辨率、低刷新率的 mask-image,能大幅减少计算量
- 该方案其他应用场景:
- 替换/模糊人物背景
- 人像马赛克
- 人像抠图
- 卡通头套,虚拟饰品,如猫耳朵、兔耳朵、带花、戴眼镜什么的(换一个模型,略改)
- 关注Web 神经网络 API (https://mp.weixin.qq.com/s/v7-xwYJqOfFDIAvwIVZVdg)进展,以后实现相关功能也许会更简单
本期作者
刘俊
Bilibili シニア開発エンジニア
以上がウェブ上の顔面ブロック攻撃に対するリアルタイム保護 (機械学習に基づく)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

導入 数週間で作物の進行を毎日観察する農民がいるとします。彼は成長率を見て、さらに数週間で彼の植物がどれほど背が高くなるかについて熟考し始めます。 thから

ソフトAIは、おおよその推論、パターン認識、柔軟な意思決定を使用して特定の狭いタスクを実行するように設計されたAIシステムとして定義されていますが、曖昧さを受け入れることにより、人間のような思考を模倣しようとします。 しかし、これはBusineにとって何を意味しますか

答えは明確です。クラウドコンピューティングには、クラウドネイティブセキュリティツールへの移行が必要であるため、AIはAIの独自のニーズに特化した新しい種類のセキュリティソリューションを要求します。 クラウドコンピューティングとセキュリティレッスンの台頭 で

起業家とAIと生成AIを使用して、ビジネスを改善します。同時に、すべてのテクノロジーと同様に、生成的AIが増幅器であることを覚えておくことが重要です。厳密な2024年の研究o

埋め込みモデルのパワーのロックを解除する:Andrew Ngの新しいコースに深く飛び込む マシンがあなたの質問を完全に正確に理解し、応答する未来を想像してください。 これはサイエンスフィクションではありません。 AIの進歩のおかげで、それはRになりつつあります

大規模な言語モデル(LLM)と幻覚の避けられない問題 ChatGpt、Claude、GeminiなどのAIモデルを使用した可能性があります。 これらはすべて、大規模なテキストデータセットでトレーニングされた大規模な言語モデル(LLMS)、強力なAIシステムの例です。

最近の研究では、AIの概要により、産業と検索の種類に基づいて、オーガニックトラフィックがなんと15〜64%減少する可能性があることが示されています。この根本的な変化により、マーケティング担当者はデジタルの可視性に関する戦略全体を再考することになっています。 新しい

Elon UniversityがDigital Future Centerを想像している最近のレポートは、300人近くのグローバルテクノロジーの専門家を調査しました。結果のレポート「2035年に人間である」は、ほとんどがTを超えるAIシステムの採用を深めることを懸念していると結論付けました。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

WebStorm Mac版
便利なJavaScript開発ツール
