Jasna 源码拆解:本地 GPU 视频马赛克修复流水线完整指南

发布时间:2026/10/27 18:45:46
Jasna 源码拆解:本地 GPU 视频马赛克修复流水线完整指南 Jasna 源码拆解本地 GPU 视频马赛克修复流水线完整指南【免费下载链接】jasnaVideo restoration tool项目地址: https://gitcode.com/GitHub_Trending/ja/jasna手里有一段 3 分 22 秒的 1080p 视频画面里有几处马赛克遮挡。上传到云端工具意味着等排队、等下载素材还得离开本机用纯 CPU 软件解码逐帧处理一分钟素材要熬十分钟。Jasna 是另一条路它把解码、检测、跟踪、裁剪、重建、回填、编码整条链路压进一块本地 GPU视频马赛克修复变成显卡上的即时计算——1080p 全程约 34 秒典型显存占用 4.8 GB。本文基于仓库源码拆解这条流水线检测—裁剪—重建—回填四个环节在代码里如何落地以及每个设计对应的代价。输入到输出七个环节如何摊进四个线程一条完整修复链包含七个环节NVDEC/AMF 硬件解码 → 逐帧检测马赛克默认rfdetr-v6→ 跨帧跟踪聚合成 clip → 每 clip 按 256×256 送 BasicVSR 重建 → 可选二级修复UNet 4x / RTX Super Res / Topaz TVAI→ 按 mask 把结果混回原帧 → NVENC/AMF 硬件编码。这些环节不是单线程顺序执行而是拆成四个并发循环用有界队列衔接见 jasna/pipeline_threads.pydecode_detect_loopGPU 解码 逐帧检测 跟踪产出带原始裁剪序列的ClipRestoreItemprimary_restore_loop对每个 clip 跑 BasicVSR产出PrimaryRestoreResultsecondary_restore_loop可选二级修复产出 uint8 帧序列blend_encode_loop第二次解码原始视频把修复结果按 mask 混合进原帧后编码输出。解码、检测、重建、编码四类负载因此在时间上互相重叠解码线程推进第 N 批帧时重建线程在处理第 N-1 批 clip。队列的水位多少帧缓冲动态决定各线程何时让路——这是后文背压一节的主角。把全帧缩小成 256×256 的 patch检测双输出与 bbox 生长核心矛盾马赛克只占画面的一小部分对全帧跑超分网络等于把算力浪费在没被遮挡的像素上。Jasna 的解法是把任务拆成两问——哪里要修交给轻量检测模型怎么修只在定位到的 patch 上重建。README 把这条不变量写得很直白The rest of the picture is not touched.其余画面一律不动。检测环节的关键决策是选RF-DETR 而不是 YOLORF-DETR 同时输出 bbox 和逐像素 mask后者是回填阶段的混合权重依据。Detections数据结构jasna/mosaic/detections.py把两者分置 CPU/GPUdataclass(frozenTrue) class Detections: boxes_xyxy: list[np.ndarray] # (N_i, 4) xyxy in pixels, CPU masks: list[torch.Tensor] # (N_i, Hm, Wm) bool, GPUbbox 是整数坐标走 numpy 做跟踪矩阵运算不占显存带宽mask 是布尔张量留在 GPU 上等待后续逐像素混合。这是一次按谁消费、消费在哪做的设备分工。模型参数按型号预配置在 jasna/mosaic/detection_registry.py模型输入分辨率置信度阈值batchrfdetr-v6默认5760.35动态rfdetr-v6-large7680.40动态rfdetr-vr-v17680.40动态rfdetr-v57680.25固定 4NVIDIA 上检测模型在首次运行时被编译成 TensorRT 引擎jasna/mosaic/rfdetr.py 的compile_rfdetr_engineworkspace_gb20给 FP16 编译留足工作区AMD 则直接加载 torch 权重走RfDetrTorchRunner。代价是 NVIDIA 首跑要等编译收益是引擎产物缓存在model_weights目录、跨版本复用。拿到 bbox 后裁剪逻辑在 jasna/crop_buffer.py 里把小框生长成 256×256 的输入RESTORATION_SIZE 256 BORDER_RATIO 0.06 MIN_BORDER 20 MAX_EXPANSION_FACTOR 1.0expand_bbox先用max(20, 长边×0.06)的边距向外扩一圈上下文再向 256 的宽高比生长扩张总量不超过原框的一倍。为什么要带上下文边距因为时序重建模型靠 patch 边缘的未遮挡像素推断遮挡区的内容纯马赛克框给它没有参照物。扩完的裁剪序列经prepare_crops_for_restoration统一预处理按整批最大尺寸只降不升地缩放再用反射填充补齐到 256×256同时记录pad_offsets与resize_shapes两组元数据——它们要一路携带到回填阶段把修复像素精确映射回原帧坐标。跟踪、拆 clip 与交叉淡化时序重建的接缝怎么办核心矛盾BasicVSR 是时序模型靠 clip 内前后帧互推信息但 clip 不能无限长——显存扛不住而且马赛克可能持续几十秒。clip 一拆边界处就会出现两个 clip 各修各的、风格不一致的接缝闪烁。跨帧关联在 jasna/tracking/clip_tracker.py 的ClipTracker.update里新帧的每个检测框与上一帧所有存活 track 算 IoU贪心匹配阈值 0.3。匹配不上的检测开新 track匹配不上的 track 进入 coast用最后一帧的 bbox/mask 合成延续上限max_detection_gap或直接收尾。同一帧内重叠的框会先按 IoU 连通分组合并避免一个马赛克被切成两个 track。场景切换由 jasna/tracking/scene_detector.py 的SceneCutDetector处理帧被降到 192px 宽相邻帧平均亮度差超过近期窗口中位数的 3 倍即判为硬切clip 强制断在镜头边界——这是两个不同镜头的像素永远不会混进同一个时序模型的保证。clip 达到max_clip_size上限基准测试默认 180 帧时不是硬切而是带重叠拆分新 track 从2 × temporal_overlap帧之前开始复制尾部的 bbox 与 mask 序列继续跟踪。同一时间窗因此被相邻两个 clip 各修一遍回填时按权重融合。权重在 jasna/pipeline_overlap.py 里生成for j in range(2 * bf): local_idx d - bf j weights[local_idx] (j 0.5) / (2 * bf)bf temporal_overlap // 3是交叉淡化窗口权重在重叠区中心从 1/4 线性爬升到 3/4与父 clip 侧互补——重叠区两帧结果各占一部分边界不再跳变。compute_keep_range再配合续接 clip 的开头d - bf帧直接丢弃父 clip 已覆盖只有因超长被拆的 clip 才保留尾部d - bf帧参与淡化。代价是重叠帧被重建两次temporal_overlap调大以重叠计算量换边界平滑度基准测试统一取 15 帧。mask 驱动回填lerp 贴回与乱序到帧的竞态核心矛盾修复结果活在 256×256 patch 坐标系里而原帧在原始分辨率且多个 clip 的完成顺序与帧号无关——第 100 帧可能等的是第 500 帧那个 clip 的重建。直接修完就写会产生竞态帧还没凑齐就被编码走。回填在 jasna/blend_buffer.py 的BlendBuffer里分两层。第一层是就绪判定register_frame为每帧登记它依赖哪些 trackis_frame_ready只有在该帧所有 track 的结果都到达后才放行blend_encode_loop据此阻塞等待修到一半就编码从结构上不可能。第二层是像素混合original_crop blended[:, y1:y2, x1:x2].float() original_crop.lerp_(resized_back, blend_mask.unsqueeze(0)) .blend_mask 为检测 mask 膨胀渐隐后的权重 original_crop.round_().clamp_(0, 255)流程是按pad_offsets/resize_shapes把 256 patch 里的有效区裁出来双线性放大回裁剪尺寸再以检测 mask经膨胀与边缘渐隐为权重对原帧区域做lerp——mask 内部完全采用修复像素边缘平滑过渡回原像素clamp_保证 uint8 不溢出。若某帧同时有多个 track后到的 clip 以差分方式叠加delta (resized - original) * mask避免互相覆盖。还有一个容易忽略的事实blend_encode_loop用的是第二个VideoReader把原片从头再硬件解码一遍取原帧。Jasna 宁可多付一次解码硬件解码 4K 约 681 fps见 benchmarks/2026-07-21_v0.8.2_e2e_decode_backends.md也不在解码线程里缓存整片原帧——缓存的显存代价远高于一次 NVDEC 重放。VR180 路径下回填走project_region/source_region_from_patch的差分投影只把修复图减原图的差值反投影回源坐标因为 patch 内马赛克之外的区域模型本就不改差值约等于 0重投影误差不会被摊到未触碰的像素上。背压与双解码四线程如何不互相卡死四个循环之间的队列不是普通Queue而是 jasna/frame_queue.py 的FrameQueue——按帧数而非条目数限流def put(self, item, frame_count0): with self._cond: if frame_count 0: while self._current_frames 0 and \ self._current_frames frame_count self._max_frames: self._cond.wait() self._deque.append((item, frame_count)) self._current_frames frame_count一个 clip 项携带它覆盖的帧数队列水位按帧累计生产者试图放入会超水位的数据时挂起等待。这意味着瓶颈自动反传到最上游重建慢了解码线程在队列满时停手硬件解码器不再无谓地吐帧占显存。配合解码侧的_BatchPrefetcher独立预取线程解码与消费重叠以及JASNA_DECODE_BACKEND环境变量在vali/pyav-hw/pyav-sw之间切换jasna/media/video_decoder.py其中 AV1 被强制改用带 NVDEC 配置的 FFmpeg 原生解码器因为 PyAV 默认的 libdav1d 不带硬件加速配置整条链路在任意一环变慢时都会以上游停手而非队列无限膨胀的方式收敛。数据账本fps、显存与关键参数以下均为仓库内官方基准benchmarks/实测值非估算。端到端吞吐RTX 5090v0.9.1 系列BasicVSR--max-clip-size 180 --temporal-overlap 15见 benchmarks/2026-07-28_engine_batch_vram.md输入端到端耗时吞吐VRAM 典型/峰值720p H.26431.9 s190.0 fps4312 / 4720 MiB1080p H.26433.8 s179.4 fps4867 / 5779 MiB2160p H.26463.3 s95.7 fps7326 / 11176 MiBREADME 汇总为 GB 计720p 4.2/4.6、1080p 4.8/5.6、2160p 7.2/10.9——8 GB 显存显卡可完整跑通 1080p。同机对比 Lada 0.11.01080p 3.6 倍、2160p 4.7 倍README.md代价是 Jasna 显存占用更高Lada 1080p 约 2.0/3.3 GB。关键参数账源码常量与基准配置参数值出处重建输入尺寸256×256crop_buffer.py裁剪上下文边距max(20px, 长边×6%)同上track 匹配 IoU 阈值0.3clip_tracker.py交叉淡化窗口temporal_overlap ÷ 3pipeline_threads.pyTensorRT 编译工作区20 GBrfdetr.py预处理/上采样固定 batch60 / 30benchmarks/2026-07-28_engine_batch_vram.mdclip 长度的显存-速度权衡1080poverlap 8clip size 扫描clip 帧数端到端VRAM 典型3051.4 s3411 MiB9034.4 s4095 MiB18035.0 s5047 MiB72033.0 s8159 MiB短 clip 慢在重叠区反复重算超过 180 帧后速度基本不动、显存线性上涨——180 是速度/显存的拐点显存吃紧时官方建议先把它降到 60。v0.9.1 还有一笔显存账preprocess/upsample 子引擎曾按 clip 全长180 帧编译TensorRT 为最大 profile 预留 scratch常驻 4560 MiB改为固定 batch 60/30 后降到 916 MiB端到端耗时不变benchmarks/2026-07-27_v0.9.1_e2e_cudagraphs.md。适用边界与已知妥协首跑税NVIDIA 上首次运行需为当前显卡现场编译检测与重建引擎官方口径 15–60 分钟期间不能动电脑model_weights目录可拷给新版本复用但升级 LTX 模型时需重新下载。硬件门槛NVIDIA 需 compute capability ≥ 7.5GTX 10 系不支持AMD RX 7000/9000 仍标注 experimental 且二级修复不可用路径不含非英文字符不支持网络盘。模型分级BasicVSR 免费LTX扩散式重建更丰富细节4 遍 passStandard/Good/High/Top 四档速度与支持者许可绑定且需 8 GB VRAM 16 GB RAM。二级修复中 UNet 4x、RTX Super Res、Topaz TVAI 也分属不同许可档docs/en/models.md。被放弃的优化FP8 上采样引擎曾使 v0.9.1 显存回退 1.8 GB可发布路线编译出约 5.7 GB scratch 的 Myelin 节点最终整条移除loop_body 量化到 FP8/INT8 反而约慢 1.9 倍。这说明 TensorRT 量化收益高度依赖引擎结构不能照搬经验值benchmarks/2026-07-28_engine_batch_vram.md。权衡取舍用更高显存约为 Lada 两倍换 3–5 倍吞吐用一次重复解码换缓存显存用重叠帧双倍重建换 clip 边界无闪烁。每一项都有对应的回退旋钮max_clip_size、temporal_overlap、JASNA_DECODE_BACKEND调优入口见 docs/en/tuning.md。收束Jasna 的价值在于把马赛克只占画面一小块这个先验彻底兑现成工程RF-DETR 的 mask 定位、256×256 patch 域重建、lerp按权重回填、FrameQueue帧数背压四者共同守住了只改马赛克、不碰背景这条底线同时让 1080p 修复落在半分钟量级。建议从免费的 BasicVSR 路径起步跑通一遍完整作业用model_weights复用规避首跑编译再按显存余量决定是否需要 LTX 或二级修复。【免费下载链接】jasnaVideo restoration tool项目地址: https://gitcode.com/GitHub_Trending/ja/jasna创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询