在浏览器中把视频变成线稿:WebGL 2、Sobel 边缘提取与结构参考素材实践

简介: Timeline Studio 新增线稿功能:基于WebGL 2本地实时处理,通过亮度转换、平滑降噪、Sobel梯度计算生成可调细节与粗细的轮廓线稿(PNG/WebM),支持裁剪/变速映射及源音频保留,与深度视频互补提供结构参考。

此前,我们在开源视频编辑器 Timeline Studio 中加入了深度视频能力:从原始画面中提取远近层次,将其转化为可复用的结构素材。

现在,我们又增加了一种表达方式——线稿图与线稿视频。

深度图描述物体之间的远近关系,线稿则突出轮廓、姿态、构图与画面中的结构变化。两者都可以作为后续创作的参考:在支持相应条件输入的图像或视频生成工作流中,保留一部分原始结构,再尝试改变外观、材质和风格。

这篇文章先介绍线稿功能的实现:如何在浏览器本地处理图片和视频,如何让预览与生成结果使用相同算法,以及如何保持裁剪、变速后的时间关系。

项目源码:Timeline Studio
在线体验:打开编辑器

一、先明确这版“线稿”的技术路线

当前版本采用传统图像处理,没有调用神经网络模型。

处理流程是:

图片 / 视频帧
      ↓
亮度转换
      ↓
平滑降噪
      ↓
Sobel 梯度计算
      ↓
阈值与软过渡
      ↓
白底黑线 / 黑底白线
      ↓
PNG 图片 / WebM 视频

这条路线的优点是启动轻、参数直接、无需下载模型,适合先建立一个完整的浏览器处理闭环。

它也有明确限制:算法依据局部亮度变化寻找边缘,缺少语义理解。因此,背景纹理、衣服褶皱和高频噪声也可能变成线条。

所以,这版输出更准确地说是经过平滑处理的轮廓线稿。它能够提供结构参考,但并不等于模型生成的语义线稿或专业描线结果。

二、用 WebGL 2 完成两遍处理

核心实现位于:

src/lib/lineArt.js

渲染器接收一个画布、输出尺寸和媒体帧,在 WebGL 2 中完成两遍绘制:

  1. 将输入帧平滑处理,写入中间纹理。
  2. 从中间纹理提取边缘,绘制到输出画布。

中间结果保留在 GPU 纹理中,避免每一遍处理都把像素读回 JavaScript。

输入纹理
   │
   ▼
平滑着色器
   │
   ▼
中间纹理 + Framebuffer
   │
   ▼
边缘着色器
   │
   ▼
输出 Canvas

对于视频,每一帧重复使用已经创建的着色器程序、纹理和帧缓冲,而不是逐帧重新初始化渲染环境。

三、第一步:把颜色转换为亮度

轮廓提取首先需要一个单通道的亮度表示。

实现使用下面的加权方式:

float gray(vec2 p) {
  return dot(
    texture(source, p).rgb,
    vec3(0.2126, 0.7152, 0.0722)
  );
}

绿色通道权重更高,蓝色通道权重较低。

后续计算关注的是相邻位置的亮度变化,因此即使画面颜色丰富,进入边缘检测阶段后,也会被归结为亮度结构。

这同样解释了一种常见情况:两个颜色不同、亮度接近的区域,边界不一定明显。

四、第二步:先平滑,减少碎线

直接对原图做边缘检测,容易把细碎纹理全部提取出来。

当前实现先使用一个 3×3 加权平滑核:

1  2  1
2  4  2
1  2  1

总权重:16

中心像素权重为 4,上下左右为 2,四个角为 1。

这一步能够压低部分高频变化,让后续计算更关注较明显的边缘。

不过,降噪与保留细节之间存在取舍。平滑过强会损失小结构,平滑不足又容易留下碎线。当前版本采用固定的轻量平滑,再通过细节参数调节边缘保留程度。

五、第三步:用 Sobel 计算边缘强度

Sobel 算子分别计算横向和纵向的亮度梯度。

对应卷积核为:

Gx:                 Gy:

-1   0   1           -1  -2  -1
-2   0   2            0   0   0
-1   0   1            1   2   1

两个方向的结果合成为梯度强度:

gradient = sqrt(Gx² + Gy²)

梯度越大,说明附近的亮度变化越明显,越有可能形成可见边缘。

当前着色器中的核心计算为:

float gradient = length(vec2(
  c + 2.0 * f + i - a - 2.0 * e - g,
  g + 2.0 * h + i - a - 2.0 * b - c
));

这里的字母代表采样中心周围的八个位置。

这种计算对每个输出像素独立执行,适合放到片元着色器中并行处理。

六、“细节”控制的是边缘阈值

界面中的“细节”范围为 0~100,默认值是 55。

它对应的核心变化是:

float threshold = mix(
  0.42,
  0.035,
  detail / 100.0
);

细节值越高,阈值越低,较弱的边缘也会保留下来;细节值越低,则优先保留明显轮廓。

为了避免硬阈值产生生硬的黑白跳变,实现使用 smoothstep:

float ink = smoothstep(
  threshold * 0.5,
  threshold,
  gradient
);

这让阈值附近的边缘具有一定软过渡。

需要注意,高细节不一定意味着更好的参考图。对于复杂背景,适当减少细节,反而能突出主体结构。

七、线条粗细如何适配不同分辨率

如果线条参数直接对应固定像素距离,换一个输出分辨率,视觉粗细就可能明显变化。

当前实现以最长边 1080 像素作为参考尺度:

scaledThickness =
  thickness * Math.max(width, height) / 1080;

再将这个数值用于边缘采样距离:

vec2 d = pixel * thickness;

界面提供 0.5~3 倍调节,默认值为 1。

这里的“粗细”通过改变采样间距影响边缘外观,并不是严格意义上对二值线条执行形态学膨胀。因此,参数变化也可能影响附近细节的响应。

黑白反转则直接切换输出亮度:

float value = inverted ? ink : 1.0 - ink;

默认输出白底黑线,也可以生成黑底白线。

八、预览与素材生成复用同一个渲染器

图像处理功能很容易出现一种问题:预览使用简化算法,生成时使用另一套实现,最后用户看到的结果与预览不一致。

这次我们让两个路径共同使用:

createLineArtRenderer(canvas, width, height)

它提供两个主要方法:

renderer.draw(media, options);
renderer.dispose();

调节参数时,预览重新绘制当前帧;生成素材时,则使用同一个渲染器处理图片或连续视频帧。

这减少了两套算法之间的偏差,也让后续维护集中在一个位置。

当前处理尺寸默认限制最长边不超过 1080,并保持比例、不放大小素材,同时将尺寸规整为偶数,以适配视频编码。

九、图片与视频如何进入同一条处理路径

图片和视频的输入方式不同,但最终都需要转换成可上传到 WebGL 的图像源。

图片路径为:

Blob
  ↓
ImageBitmap
  ↓
2D Canvas
  ↓
WebGL 纹理

这里额外经过一次 Canvas,是为了统一图像方向。

实际接入时发现,ImageBitmap 对纹理上传翻转设置的行为与其他图像源存在区别。先绘制到 Canvas,可以让图片和视频沿用一致的方向处理路径,避免生成结果上下颠倒。

视频路径则使用 Mediabunny 读取媒体轨道,通过 CanvasSink 获取指定时间对应的画面。

十、视频转换要保留裁剪与变速关系

视频线稿不能只从原始文件的第零秒开始逐帧处理。

用户选中的片段可能已经裁剪,也可能应用了固定倍速或速度曲线。

因此,输出视频的每个采样点,都需要先映射回源素材时间:

getVisualSourceTime(segment, localTime)

对于固定倍速,可以近似理解为:

源时间 = 素材入点 + 片段内时间 × 倍速

速度曲线则需要沿用编辑器既有的映射逻辑。

当前输出采用 24 fps:

const fps = 24;
const count = Math.ceil(duration * fps);

每一帧的片段内时间为:

t(i) = i / 24

处理流程为:

输出帧时间
    ↓
映射为源素材时间
    ↓
读取源画面
    ↓
提取线稿
    ↓
写入输出时间戳

这样,线稿视频才能跟随当前片段的裁剪范围和播放节奏。

24 fps 是当前生成素材的输出帧率,并不意味着处理过程在所有设备上都能达到实时速度。

十一、生成 WebM,并保留对应源音频

当前视频输出使用:

  • WebM 容器;
  • VP9 视频编码;
  • 约 4 Mbps 视频码率;
  • 有源音频时,使用 Opus 编码。

音频复用已有的源音频准备与离线混音流程,按照片段的源区间和变速关系生成对应声音。

这里保留的是该片段对应的源音频,不是把整个工程中的旁白、音乐和其他轨道一起混入线稿素材。

生成结束后,结果保存到“我的素材”,由用户决定何时插入时间线。

这也方便保留原片、线稿版本和后续生成版本,用于并排比较或继续组合。

十二、取消与资源清理也属于功能实现

长视频处理过程中,用户需要能够取消任务。

当前实现使用 AbortController,在读取源画面、处理帧、编码和最终封装等阶段检查取消信号。

结束或取消后,需要释放:

视频输入与解码资源
WebGL 纹理
Framebuffer
着色器与程序
顶点缓冲

界面进度也区分了逐帧处理和最终封装:帧处理阶段最多显示到 99%,完成封装并成功保存素材后,再显示完成。

这样,“处理完最后一帧”和“已经拿到可用文件”就不会被混为一谈。

十三、线稿与深度视频,分别提供什么参考

此前的深度视频与现在的线稿视频,可以看作两类不同的结构表达:

素材类型 主要表达 适合关注的内容
深度视频 远近关系、空间层次 前后景、空间布局、主体距离变化
线稿视频 边缘、轮廓、构图变化 主体形状、姿态轮廓、结构随时间的变化

例如,想保留一个镜头的前后景关系,可以考虑深度参考;想保留产品轮廓或人物动作的外形变化,可以考虑线稿参考。

“具有参考能力”指这些输出可以成为结构参考素材。 能否用于生成控制,还取决于下游工作流是否支持对应输入,以及它对预处理方式、分辨率、帧率和时间对齐的要求。

当前功能完成的是浏览器内的线稿提取与素材生成,并不代表已经自动接通所有图像或视频生成模型。

对于要求更干净语义轮廓的场景,传统边缘检测也可能不够,需要另外评估学习式线稿模型。

十四、功能入口与源码

当前入口位于:

效果 → 线稿图

支持:

  • 图片生成 PNG;
  • 视频生成 24 fps WebM;
  • 细节、线条粗细与黑白反转;
  • 参数实时预览;
  • 当前裁剪与速度曲线时间映射;
  • 对应源音频保留;
  • 取消任务与素材保存;
  • 13 种界面语言及手机布局。

核心源码入口:

src/lib/lineArt.js
    渲染器、媒体读取、视频生成与资源释放

src/components/LineArtPanel.jsx
    参数面板、预览、任务状态与取消

src/i18nLineArt.js
    多语言文案

从深度视频到线稿视频,我们希望逐步让编辑器具备生成“中间结构素材”的能力。原始视频可以继续承担内容表达,深度和轮廓则提供不同维度的参考,供后续剪辑、视觉实验和支持相应条件的生成工作流使用。

欢迎体验,也欢迎提交复杂背景、快速运动和细小轮廓等实际案例,帮助我们继续改进处理质量。

GitHub:MartinDelophy/ai-video-editor
在线体验:Timeline Studio

相关文章
|
6天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
2683 22
|
1天前
|
云安全 人工智能 安全
|
5天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)
|
6天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
1181 4
|
云安全 安全 网络安全
|
6天前
|
安全 算法 定位技术
《高性价比人生指南》完整原版:普通人用最少的资源,过好这一生的底层逻辑~How To Live Better
📖《高性价比人生指南》是一份基于实证、拒绝焦虑的生存手册,倡导以“人生时薪”为视角,重新计算时间、金钱与精力的成本与收益。它不承诺逆袭,只教人算清账:省下的钱若耗掉时间便亏;买体验比买物品更值;睡眠是最高杠杆的健康投资;关系贵在情绪价值而非表面热络;学习重在改变行为而非自我安慰。核心理念:用低成本、高回报的微小行动,换取长期的选择权——不是成为谁,而是掌控自己人生的主动权。
|
19天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
3325 52
|
11天前
|
人工智能 JSON Linux
【保姆级】ComfyUI部署教程(下载+安装+配置+工作流,2026最新)
ComfyUI 是一款开源节点式AI生成工具,支持图像、视频、音频及3D内容创作。通过拖拽连线组合模型加载、提示词、采样等节点,构建可复用、易修改的工作流,兼容SD1.5、SDXL、Flux、Qwen Image等主流模型。

热门文章

最新文章