JavaScript 绿幕抠图实现

js 前端抠图 性能优化 原文链接: js 前端抠图 性能优化 上一篇: ... 阅读详情
AI摘要

本文介绍如何利用WebGL和片元着色器在浏览器中实现高性能的绿幕抠图,支持图片与视频背景去除。通过YUV颜色空间计算像素差异,结合相似度、平滑度与饱和度参数优化边缘效果,可在720P视频上实现实时处理,单帧耗时低于1ms。

先体验 DEMO,基于 WebAV 实现

  • 移除图片背景

  • 移除视频背景

背景

因为视频相关标准及浏览器的实现问题,很难在主流浏览器中顺利播放背景透明的视频。

有两种方法可以为最通用的视频格式(MP4,H264)移除背景,实现透明效果:

  1. 原视频配上绿幕,使用本文介绍方法移除背景绿幕

    • 优点:制作使用简单

    • 缺点:抠图可能不完美,导致偏色

  2. 将视频中的 alpha 通道与画面并排放置,在客户端混合

    • 优点:精确还原

    • 缺点:分辨率增加,视频变大;可能适应场景小,原视频制作需要精确的 alpha 通道

方法二参考:https://juejin.cn/post/6885673542642302984

绿幕抠图原理

  1. 传入四个参数

    1. 目标颜色,期望抠除背景色,可以不是绿色

    2. 相似度阈值

    3. 平滑度敏感系数

    4. 颜色饱和度敏感系数

  2. 使用 WebGL(片元着色器) 逐个比对原像素与目标颜色

  3. 计算过程

    1. 将颜色转换到 UV 空间,计算出当前像素与目标颜色的距离

    2. 将距离 - 相似度阈值,小于 0 则判定为绿幕,将像素点设置为全透明(alpha=0)

    3. 与平滑度参数计算,将相似度转换成 alpha 通道值,越大越不透明

    4. 计算出原像素点的灰度值

    5. 将相似度与饱和度参数计算,然后与原像素点的灰度值混合,越大越靠近原像素点,越小越就接近灰度
      (后两步为了移除前景边缘与绿幕反光,导致的前景像素点混合了绿幕背景颜色)

实现

参考:Production-ready green screen in the browser

需要先了解一下 YUV 颜色编码

Shader 代码

#version 300 es
precision mediump float;
out vec4 FragColor;
in vec2 v_texCoord;

uniform sampler2D frameTexture;
uniform vec3 keyColor;

// 色度的相似度阈值
uniform float similarity;
// 透明度的平滑度计算
uniform float smoothness;
// 降低绿幕饱和度,提高抠图准确度
uniform float spill;

vec2 RGBtoUV(vec3 rgb) {
return vec2(
rgb.r * -0.169 + rgb.g * -0.331 + rgb.b * 0.5 + 0.5,
rgb.r * 0.5 + rgb.g * -0.419 + rgb.b * -0.081 + 0.5
);
}

void main() {
// 获取当前像素的rgba值
vec4 rgba = texture(frameTexture, v_texCoord);
// 计算当前像素与绿幕像素的色度差值
vec2 chromaVec = RGBtoUV(rgba.rgb) - RGBtoUV(keyColor);
// 计算当前像素与绿幕像素的色度距离(向量长度), 越相似则色度距离越小
float chromaDist = sqrt(dot(chromaVec, chromaVec));
// 设置了一个相似度阈值,baseMask < 0,则像素是绿幕,> 0 则像素点可能属于前景(比如人物)
float baseMask = chromaDist - similarity;
// 与平滑度参数计算,将 baseMask 转换成 alpha 通道值,越大越不透明
float fullMask = pow(clamp(baseMask / smoothness, 0., 1.), 1.5);
rgba.a = fullMask;
// 如果 baseMask < 0,spillVal 等于 0;baseMask 越小,像素点饱和度越低
float spillVal = pow(clamp(baseMask / spill, 0., 1.), 1.5);
// 计算当前像素的灰度值
float desat = clamp(rgba.r * 0.2126 + rgba.g * 0.7152 + rgba.b * 0.0722, 0., 1.);
rgba.rgb = mix(vec3(desat, desat, desat), rgba.rgb, spillVal);
FragColor = rgba;
}

上面算法使用 CPU(纯 js 代码)也能实现,但性能会差很多

除了上面分析的核心代码之外还有一些为了让 Shader 运行起来的辅助代码,属于 WebGL 的基础知识,查看完整代码

如何使用

1、静态图片抠图示例 

import { createChromakey } from '@webav/av-cliper';

const cvs = document.querySelector('#canvas') as HTMLCanvasElement;
const ctx = cvs.getContext('2d', { alpha: true })!;
(async () => {
  const img = new Image();
  img.src = './public/img/green-dog.jpeg';
  await new Promise((resolve) => {
    img.onload = resolve;
  });
  const chromakey = createChromakey({
    // 目标颜色不传,则取第一个像素点当做背景色
    similarity: 0.35,
    smoothness: 0.05,
    spill: 0.05,
  });
  ctx.drawImage(await chromakey(img), 0, 0, cvs.width, cvs.height);
})();

2、 使用 @webav/av-cliper 对 mp4 视频进行逐帧抠图,体验 DEMO:mp4(chromakey) 合成视频的效果

import { createChromakey, MP4Clip } from '@webav/av-cliper';
const chromakey = createChromakey({
  similarity: 0.4,
  smoothness: 0.1,
  spill: 0.1,
});
const clip = new MP4Clip((await fetch('<mp4 url>')).body!);
clip.tickInterceptor = async (_, tickRet) => {
  if (tickRet.video == null) return tickRet;
  return { ...tickRet, video: await chromakey(tickRet.video) };
};

传入一张 720P 的图片给 chromakey 首次执行(包括初始化)大概耗时 20ms,后续每次执行基本在 1ms 之内;
所以性能方面实现视频实时抠图没有压力,将 Video 标签传给 chromakey 即可

async function render() {
  ctx.drawImage(await chromakey(videoElement), 0, 0, cvs.width, cvs.height);
  requestAnimationFrame(render); // 注意:后台页面 requestAnimationFrame 停止执行
}

render();

其它实现

以下是另一个实现抠图的 shader 的代码实现、使用相对简单;
但相对上面的实现,边缘可能会存在黑边。

precision mediump float;
uniform sampler2D u_texture;
uniform vec4 keyRGBA; // key color as rgba
uniform vec2 range; // the smoothstep range

varying vec2 v_texCoord;

vec2 RGBToCC(vec4 rgba) {
float Y = 0.299 * rgba.r + 0.587 * rgba.g + 0.114 * rgba.b;
return vec2((rgba.b - Y) * 0.565, (rgba.r - Y) * 0.713);
}

void main() {
// 从贴图获取源像素
vec4 srcColor = texture2D(u_texture, v_texCoord);
// 源像素 RGB 转换为 YUV
vec2 srcCC = RGBToCC(srcColor);
// 目标颜色转换为 YUV
vec2 keyCC = RGBToCC(keyRGBA);

// 计算距离
float mask = sqrt(pow(keyCC.x - srcCC.x, 2.0) + pow(keyCC.y - srcCC.y, 2.0));
// 对距离值在range中进行平滑映射取值
mask = smoothstep(range.x, range.y, mask);

// 低于range下限
if (mask == 0.0) { discard; }
// 超过range上限
else if (mask == 1.0) { gl_FragColor = srcColor; }
// 处于range之中
else {
// 某些源像素(如头发边缘)混合了绿幕颜色,需要减去绿幕颜色,否则边缘会有绿斑
gl_FragColor = max(srcColor - (1.0 - mask) * keyRGBA, 0.0);
}
}

关于优联前端

        武汉优联前端科技有限公司由一批从事前端10余年的专业人才创办,是一家致力于H5前端技术研究的科技创新型公司,为合作伙伴提供专业高效的前端解决方案,合作伙伴遍布中国及东南亚地区,行业涵盖广告,教育, 医疗,餐饮等。有效的解决了合作伙伴的前端技术难题,节约了成本,实现合作共赢。承接Web前端,微信小程序、小游戏,2D/3D游戏,动画交互与UI广告设计等各种技术研发。

浏览器实现视频转序列帧:绿幕抠图与sprite sheet生成全指南 在2D游戏和Web动效开发中,序列帧动画依然是表现力最稳定的技术方案之一。如何将一段真人动作视频高效转化为引擎可用的精灵表,是许多独立开发者绕不开的环节。借助浏览器原生能力,通过canvas逐帧绘制与色度键控算法,即可完成绿幕背景的实时抠像,并自动裁剪、对齐、拼合为带透明通道的sprite sheet。这一过程无需安装桌面软件,数据留在本地,配合JavaScript即可实现参数化调优,兼顾效率与可控性。从视频抽帧的三种路径,到RGB与YCbCr色彩空间下的抠图原理,再到精灵表网格布局与边缘防串色处理,整套流 阅读详情

相关推荐

WebGL Shader 实战:从原理到代码,打造高性能实时绿幕抠图

本文深入解析WebGL Shader实现实时绿幕抠图的技术原理与实战技巧。通过YUV色彩空间转换、色度距离计算等核心算法,结合相似度阈值和平滑度参数调整,实现高性能的Chromakey效果。文章还提供调参指南、性能优化技巧及常见问题解决方案,帮助开发者快速掌握WebGL绿幕抠图技术。

weixin_29271263的博客 171

20 行核心(shader)代码实现实时绿幕抠图

武汉优联前端科技有限公司由一批从事前端10余年的专业人才创办,是一家致力于H5前端技术研究的科技创新型公司,为合作伙伴提供专业高效的前端解决方案,合作伙伴遍布中国及东南亚地区,行业涵盖广告,教育, 医疗,餐饮等。有效的解决了合作伙伴的前端技术难题,节约了成本,实现合作共赢。除了上面分析的核心代码之外还有一些为了让 Shader 运行起来的辅助代码,属于 WebGL 的基础知识,查看完整代码。将相似度与饱和度参数计算,然后与原像素点的灰度值混合,越大越靠近原像素点,越小越就接近灰度。

ufrontend的博客 1776

网页端抠图实现 H5抠图 canvas抠图 在线抠图

网页端抠图实现 H5抠图 canvas抠图 在线抠图,这个是一个抠图的demo,可以直接运行使用

什么是色度键(Chroma Key)?

色度键是一种编辑技术,它将两幅图像合成在一起,形成一幅完整的图像。这种编辑技术有时被称为蓝色或绿色屏幕,指的是用来拍摄一幅受色度键过程影响的图像的背景。这种编辑技术在电影和电视中被广泛使用,以产生一系列的特效... 色度键是一种编辑技术,它将两幅图像合成在一起,形成一幅完整的图像。这种编辑技术有时被称为蓝色或绿色屏幕,指的是用来拍摄一幅受色度键过程影响的图像的背景。这种编辑技术在电影和电视中被广泛使用,以产生一系列的特效,因此许多影迷都熟悉这个基本概念 色度键是一种编辑技术,它将两个图像合.

qq_26900671的博客 4286

js+html5 canvas实现ps钢笔抠图

主要介绍了js+html5 canvas实现ps钢笔抠图,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

逆向工程师的Shopee爬虫避坑指南:af-ac-enc-dat参数生成原理与反反爬策略

本文深入剖析了Shopee电商平台的反爬虫加密机制,重点解析了核心请求头参数x-sap-ri、x-sap-sec及af-ac-enc-dat的生成原理与联动关系。文章从逆向工程视角,提供了定位加密代码、分析算法逻辑的实战方法,并分享了基于JS执行环境模拟与无头浏览器控制的可持续反反爬策略,为高效、稳定地采集数据提供专业指南。

weixin_28607671的博客 1496

【pixi.js】pixijs实现绿幕抠图和视频

本文展示了一个基于WebGL和WebGPU的实时视频处理实现,参考OBS Studio的架构。代码包含两个版本的着色器实现:WebGL版本(GLSL)和WebGPU版本(WGSL),均实现了视频帧的几何变换、颜色校正、色度键控等功能。WebGL版本包含完整的顶点着色器和片段着色器,实现了非线性颜色转换、对比度/亮度调节、伽马校正以及色度键去背等特效。WebGPU版本则采用WGSL语言,通过结构体组织统一变量,展示了类似的顶点变换逻辑。两种实现都支持输入输出尺寸调整、UV坐标计算等核心功能,为构建跨平台的实时

weixin_48213294的博客 2507

瑞芯微Android固件修改实战:从解包到root提权完整流程(附工具包)

本文详细解析了瑞芯微Android固件深度定制全流程,涵盖从固件包解包、系统镜像修改到植入root提权与分区调整的实战步骤。通过工具链操作与原理剖析,指导开发者安全实现系统精简、权限获取及存储扩容,最终完成固件重新打包与刷机验证,适用于追求设备完全控制权的技术爱好者。

ujm56789012的博客 699

php画像素点,canvas像素点操作之视频绿幕抠图-

这篇文章主要介绍了canvas像素点操作之视频绿幕抠图的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧本文介绍了canvas像素点操作之视频绿幕抠图,分享给大家,具体如下:用法:context.putImageData(imgData, x, y, dX, dY, dWidth, dHeight);该栗子纯属为了演示功能而做,如果只强调效果而不在乎数据的话,用...

weixin_33603397的博客 317

还在手敲LaTeX公式?用Rime小狼毫打造你的专属数学输入法(附完整配置包)

本文介绍如何利用Rime小狼毫输入法引擎打造专属数学公式输入方案,显著提升LaTeX公式输入效率。通过详细配置教程和智能补全技巧,帮助科研人员和学生实现3-5倍的输入速度提升,特别适合学术写作和技术文档创作场景。

weixin_32520601的博客 282

Latex | IEEE双栏排版中长公式的排版

IEEE双栏排版中,有时候公式过于长了,过宽,导致单栏排版不下。

qq_43466146的博客 1万+

webgl 绿布视频抠图

1、项目介绍 输入有背景色的视频,MP4格式,每一帧画面进行处理。 输入要替换的背景图,jpg格式图片 最终抠图合成效果 2 开发环境介绍 开发语言 :webgl 、js 测试浏览器:火狐 IDE :webstorm 3 开发步骤 主要在片元着色器中进行处理 计算当前像素点RGB值对应的HSV值 设定HSV三个分量的权重,根据权重计算当前像素点的HSV值到给定背景色的HSV值的欧式距离 将欧式距离用smoothstep做平滑,0.5以下的一定要滤掉 将

热带宇林 2117

初学者入门机器学习 (ML)的推荐教程

了解基本的机器学习概念并不难。有大量免费的在线博客文章、视频和编码教程可以引导您了解基础知识——从介绍性内容到常见应用程序,再到算法和应用技能。这篇文章总结了一些用于介绍 ML 的最佳免费选项。它按逻辑顺序排列,每个概念都建立在上一个概念的基础上。

u010542847的博客 4622

WebGL Chromakey 实时绿幕抠图

20 行核心(shader)代码实现实时绿幕抠图先体验 DEMO,基于WebAV实现移除图片背景移除视频背景。

ufrontend的博客 1822

操作系统知识点汇总(王道)

操作系统不论是就业还是升学都是核心的一门课程,对于大部分工科更是必修课程。本文章是对《王道操作系统》所有知识点的总结笔记,以供大家学习以及在备考期间复习使用。让我们一起把知识往脑子里旋好吗!!!......

S mile0804的博客 5万+

Python爬虫实战:基于异步爬虫与机器学习的数据采集——以电商平台在线评论有用性分析为例

内容涵盖爬虫原理、反爬虫策略应对、数据清洗、数据存储以及简单的数据分析预览,并为后续利用机器学习模型(如逻辑回归、随机森林)分析评论有用性打下坚实的数据基础。特别是在电子商务领域,在线评论作为UGC的一种主要形式,深刻影响着消费者的购买决策和商家的信誉体系。然而,平台上的评论质量参差不齐,充斥着大量无意义的灌水、广告甚至虚假评论。因此,如何自动识别和筛选出“有用”的评论,成为了学术界和工业界共同关注的焦点。我们选择目前Python爬虫领域最前沿、效率最高的技术组合,以确保爬虫的稳定性、速度和可扩展性。

2201_76125261的博客 107

直播绿幕抠图的例子(绿幕抠图直播实例参考)

直播绿幕抠图的例子(绿幕抠图直播实例参考)直播背后的那群人,屏幕前可能就一两个主播,但是现场幕后是一个几十人甚至上百人的团队在支持

阿酷tony 5736

使用 Simulink 实现基于相控阵雷达的波束形成技术

摘要:本文详细介绍了利用MATLAB Simulink和Phased Array System工具箱实现相控阵雷达波束形成的完整流程。主要内容包括:1)创建Simulink模型;2)设计天线阵列参数;3)信号生成模块配置;4)波束形成算法实现;5)结果可视化方法;6)仿真调试与优化;7)代码导出与部署。通过分步指导,读者可以掌握从理论到实践的完整开发流程,包括关键参数设置和算法实现示例。该方案适用于军事、气象等领域的雷达系统开发,并支持后续嵌入式和智能算法集成。

xiaoheshang_123的博客 182

整个世界都是你的绿幕:这个视频抠图换背景的方法太惊艳了!

点击上方“视学算法”,选择加"星标"或“置顶”重磅干货,第一时间送达本文转载自:机器之心 | 参与:Racoon、张倩绿幕是影视剧中抠图、换背景的利器,但如果不在绿...

zandaoguang的博客 5230

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

canvas像素点操作 —— 视频绿幕抠图

原文地址 主要内容 上篇文章学习了canvas像素点的获取 —— 传送门, 今天学一下canvas像素点操作。 一个方法:putImageData putImageData 用法: context.p...

weixin_39037804的博客 987

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

html5 自动扣图,canvas像素点操作之视频绿幕抠图

本文介绍了canvas像素点操作之视频绿幕抠图,分享给大家,具体如下:用法:context.putimagedata(imgdata, x, y, dx, dy, dwidth, dheight);参数描述imgdata规定要放回画布的 imagedata 对象。ximagedata 对象左上角的 x 坐标,以像素计。yimagedata 对象左上角的 y 坐标,以像素计。dx可选。水平值(x),...

weixin_35672512的博客 1034

纯浏览器实现视频转sprite sheet:从抽帧到绿幕抠图的完整指南

前端视频处理和图像合成技术让开发者无需依赖专业软件,就能在浏览器中完成复杂的视觉素材制作。其核心原理是利用Canvas和WebCodecs API对视频帧进行解码、像素级操作与再编码,再结合色度键算法实现绿幕背景的实时移除。这种方案不仅降低了操作门槛,还兼顾了数据隐私与交互效率,特别适合需要快速处理动作素材的游戏开发、2D动画和动效设计场景。从视频抽帧、色度键调参到sprite sheet网格排版,一套纯前端流程即可轻松完成,让'从视频到游戏素材'的转化变得高效且直观。

weixin_30430677的博客 183

保姆级教程:用WebGL Shader实现实时绿幕抠图,20行核心代码搞定

本文详细介绍了如何使用WebGL Shader实现实时绿幕抠图技术,通过20行核心代码解析和性能优化技巧,帮助开发者高效处理视频流。文章涵盖颜色空间转换、核心算法解密及实战优化方案,适用于在线视频会议等实时应用场景。

weixin_33719619的博客 304

huashu-art-motion 里的人物怎么做:AI生帧+绿幕抠图+代码合成的完整角色工作流

在 **huashu-art-motion**(35 种艺术风格、9 种解说语法的艺术动画 skill)里做动画,场景完全可以纯代码画,但"人"——脸、衣服、动作——最省事的做法是:**AI 生帧+绿幕抠图+代码合成**。这套角色工作流在官方成片里被反复验证过:人物交给生图模型出帧,代码只负责位置、朝向、换帧和材质。本文用 3 步讲清楚它是怎么跑的。 ## 先看全貌:人物实现的 3 种方式 同

gitblog_00576的博客 196

无需绿幕!用CV-UNet大模型镜像实现智能背景移除

本文介绍了基于“星图GPU”平台自动化部署CV-UNet Universal Matting基于UNET快速一键抠图批量抠图 二次开发构建by科哥镜像的完整方案,实现无需绿幕的智能背景移除。该镜像支持本地化运行与批量处理,适用于电商商品图换底、人像摄影后期等AI图像处理场景,开箱即用,显著提升内容创作效率。

weixin_42376614的博客 804

RMBG-2.0多场景落地:数字人直播(实时绿幕替换)、虚拟展会(展品抠图)

本文介绍了如何在星图GPU平台上自动化部署RMBG-2.0轻量级 AI 图像背景去除工具镜像,显著提升数字人直播中的实时绿幕替换效率。该镜像可在消费级GPU上低延迟运行,支持摄像头直连与OBS无缝集成,实现端到端的AI语义抠图,大幅降低虚拟直播与虚拟展会的内容制作门槛。

weixin_42613360的博客 308
上一篇: 20 行核心(shader)代码实现实时绿幕抠图
下一篇: Postman、Apifox、Apipost用哪个?
优联前端
博客等级 码龄5年 1832粉丝 171原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值