简述
本文统一采用基于 Android Kawase V2 的滤波链, 从单相位冲激响应拟合出发, 检验降采样引起的相位误差, 再引入 《DPF: Differentiable Polyphase Filtering for Large-Kernel Approximation》(SIGGRAPH 2026)的多相监督方法。
最后, 将优化问题扩展到固定共享 Mip 核的降采样模糊, 讨论如何在固定采样预算下求解随模糊尺度变化的末端采样参数。
单相位优化 Kawase
1. Kawase 与 Gaussian 的形状差异
先观察目标 σ=4,8,16,40 时, 原分辨率 Gaussian 与 Android Kawase V2 在匹配模糊半径后, 同一张 512×512 sinc 测试图上的结果。
在 Dual Kawase 的实现里, 通过混合原图与模糊结果来保留高频信息, 模糊形状与相同尺度的 Gaussian 有相当明显的差异。
同一张 512×512 sinc 测试图 · 输出均无显示增益 · RMSE 在线性亮度域计算| 方法 | σ = 4 | σ = 8 | σ = 16 | σ = 40 |
|---|
| Gaussian |  图像 RMSE 0 |  图像 RMSE 0 |  图像 RMSE 0 |  图像 RMSE 0 |
|---|
| Android Kawase V2 |  blurRadius=6 匹配 σ≈3.9817 图像 RMSE 5.722e-2 |  blurRadius=17 匹配 σ≈8.0894 图像 RMSE 6.388e-3 |  blurRadius=32 匹配 σ≈16.0737 图像 RMSE 4.239e-3 |  blurRadius=90 匹配 σ≈39.8502 图像 RMSE 4.809e-3 |
|---|
2. Kawase 的处理链路
这里展开目标 σ=4 对应的 Android Dual Kawase 的链路: 首次四倍下采样, 再做一次二倍下采样;返回时先二倍重建并混合同层图像, 最后四倍重建并混合原图。
竖直虚线将上排保存的图像送入下排的混合步骤:Mᵢ(z) = αᵢ z + (1 − αᵢ) qᵢ;C_r(b) = β(r) b + (1 − β(r)) f。
上面的符号分别表示:
- f(x) 和 f′(x) 是原分辨率的输入与输出。x 表示重排前的空间坐标, k 表示重排后的离散像素索引;中间各级以该级输入像素为坐标单位。
- UKu(s) 使用采样核完成上采样重建, 其中 s 由 Android 实现根据
blurRadius 内部确定;pi 是重建后、混合前的图像。
- Mi 将重建结果与此前保存的同层下采样图像混合: Mi(z)=αiz+(1−αi)qi。
- Cr 执行小半径原图混合: Cr(z)=β(r)z+(1−β(r))f, 其中 r 是整数
blurRadius, β(r)=min(1,r/10)。
下面以 blurRadius=6 为例展示各阶段的产物: 5122→1282→642→1282→5122。
返回 1282 时的层间混合比例约为 0.3464, 最终输出包含 60% 模糊结果和 40% 原图。
因此这个小半径结果会保留清晰细节, 冲激响应也含有原图分量产生的尖峰;它本身并不是严格的 Gaussian。
3. 单相位冲激响应优化
为了量化 Kawase 和标准模糊核心之间的差异, 一种常用的方法是使用单相位冲激的处理结果作为复杂图形链路的等效卷积核心。
输入、输出与横截面
评测一条模糊链时, 可以构造离散冲激 δ: 一幅只有中心像素为 1、其余像素全为 0 的图像。把它送入完整处理链 P, 记录输出权重分布:
K=P(δ).
这样得到的 K 是输入所在位置的冲激响应。
观察二维图及中心行横截面, 就能比较扩散宽度、峰值和形状;与目标 Gaussian 做差, 还能得到可用于调参的误差指标。
下面使用 Android Kawase V2 (blurRadius=90), 展示相位 (0,0) 单位冲激的输出及中心行横截面。原分辨率 Gaussian 作为参考, 目标尺度仍为 σ=40。



A—A 标出横截面位置, 下方叠加该截面的原始值曲线, 灰色虚线为 Gaussian。
用这种方式进行的核心评测叫做单冲激评测。
不难发现, Kawase 基线虽然支撑范围与标准高斯模糊类似, 但峰值明显要低于高斯模糊, 形状更扁平。
体现在图中的结果就是看起来“方方”的。
单冲激评测与 LSI 条件
单冲激评测的理论依据是线性平移不变系统(LSI)的性质。如果 P 既线性又平移不变, 那么一个冲激响应就足以确定任意输入的输出:
P(δ)=K⟹∀f,P(f)=f∗K.
这时, 优化冲激响应就等价于优化整条链的卷积核。但事实上Dual Kawase 并不是一个LSI系统, 这也是本篇文章的核心问题。
在这里我们先沿用这个思路, 把 Dual Kawase 的单点响应尽量拟合到 Gaussian。下一节我们将引入新的方法来解决这个问题。
构造优化变量
各阶段的 Kernel 如下, 偏移量以该 pass 的输入 texel 为单位。各次取样均使用 bilinear。
Kd,4 · 四倍下采样
四个对角 · 每次采样 1/4
Kd,2 · 二倍下采样
中心 1/2 · 四个对角各 1/8
Ku(s) · 二倍上采样
中心 + 正七边形顶点 · 每次采样 1/8
图示Kernel及其重建权重覆盖统一将取样中心放在四个输入像素的交点: 方格是完整输入像素, 小点是像素中心, 空心圆是模板的采样中心。坐标以取样中心为原点, Δx 向右、Δy 向下, 采样偏移与代码一致。灰色深浅表示这一参考对齐下的累计像素权重, 三图共用色阶;覆盖区外额外保留一圈完整像素。上采样示例取 s=2(a=s/2=1), 虚线圆半径为 a。这是核模板的参考示意, 不代表实际输出相位;实际运行时, 取样中心相对于输入像素的位置随输出相位变化, 插值权重也随之变化。
观察这三个核心的设计思路, 可以简化成4个变量: 起始角度 θ;外围采样数 n;中心权重 wc;圆周半径 a。
外围 n 个点均匀分布在半径为 a 的圆上, 第 i 个点的角度为 θ+2πi/n, 每点权重为 (1−wc)/n;中心权重为 wc。拖动滑块或输入数值, 查看采样点与 bilinear 插值权重的变化。图中固定以四个输入像素的交点为取样中心, 灰度色阶保持不变, 坐标范围包含全部受影响像素;淡色空心点表示零权重的采样位置。
对应上方三个 Kawase 上采样及下采样核心:
| 核心 | 起始角度 θ | 外围采样数 n | 中心权重 wc | 圆周半径 a |
|---|
| Kd,4 | π/4 | 4 | 0 | 2 |
| Kd,2 | π/4 | 4 | 1/2 | 2 |
| Ku(s) | 0 | 7 | 1/8 | s/2 |
另外还有层间插值系数 α 和最终模糊结果的占比 β。对下面 σ=4 的链路, 三个核各有四个参数, 加上这两个混合系数, 一共是 3×4+2=14 个参数。其中三个采样数 n 是离散整数, 本次求解固定为 4,4,7;实际参与连续优化的是每个核的 (θ,wc,a) 以及 α,β, 共 3×3+2=11 个变量。
为了方便, 记 Ωk=(θk,nk,wc,k,ak)(k 依次取 d,4、d,2、u)为三个核各自的参数组, 一组完整的解即为 Ω=(Ωd,4,Ωd,2,Ωu,α,β)。
定义单相损失并梯度求解
把目标标准差为 σ 的原分辨率离散高斯核记为 Gσ, 完整 Kawase 链记为 FΩ。
求解过程就是在固定的中心位置(相位 (0,0))放置单位冲激 δ0, 最小化它与目标响应之间的平方误差:
Lsingle(Ω)=∥FΩ(δ0)−Gσ∥22.
Ω∗≈ΩargminLsingle(Ω).
记 DKd,4,4 和 DKd,2,2 分别为带核的四倍、二倍下采样, UKu,2 为带核的二倍上采样, R4 为固定的四倍双线性重建。对输入 f, 完整链路的各阶段产物与两次混合依次为
q0p0f′=DKd,4,4(f),=UKu,2(q1),=(1−β)f+βR4(p0).q1p0=DKd,2,2(q0),=(1−α)q0+αp0,
p0 对应第 1 节重建后、混合前的图像;f=δ0 时的输出 f′ 即损失中的 FΩ(δ0)。
下面的交互演示默认使用 Levenberg–Marquardt(LM)。它利用每个输出像素对参数的导数, 估计参数的敏感度及相互影响, 再求出联合更新方向,方法背景可参见 Ceres 的 LM 说明。
λ 1.00e+0 · 回退 0 次第 0 / 200 步 · Loss 35.059086
Kd,4 · 四倍下采样
n=4 · 使用一次 · 三个参数参与求解
Kd,2 · 二倍下采样
n=4 · 使用一次 · 三个参数参与求解
Ku(s) · 二倍上采样
n=7 · 使用一次 · 三个参数参与求解
冲激响应与 Gaussian
三个核与两次混合共同决定输出 · 目标 σ=4
这个方法可以进一步拓展到所有的 σ, 从而完成对任何半径高斯模糊的拟合。
对照单相优化结果
拖动滑条, 比较目标 σ=0…40 下的标准 Gaussian、修复后的 Android Kawase V2, 以及单相位冲激拟合结果。σ=0.5,1,…,40 共 80 档分别求解;σ=0 单独使用原图直通, 因而滑条共有 81 个位置。
正在加载响应数据…
Android Kawase V2 · 修复后
加载中…
上半部分为完整 sinc 图的模糊结果,始终以 1× 显示;下半部分为单冲激响应。两部分各自为 512×512,在各级采样中独立镜像延拓,分界处不互相影响。三种方法的冲激视野相同。冲激增强显示以目标 Gaussian 峰值为共同曝光基准,放大弱响应以查看轮廓。下方实线为冲激响应的中心行,灰色虚线为 Gaussian。三张卡片共用纵轴。灰度开关不改变 sinc 图、曲线原始权重及冲激误差指标。
Android 基线保留整数 blurRadius 的层数、采样核与混合调度, 修正上采样七边形 STEP_4.x、STEP_6.x 的符号, 并沿用相位零的固定对齐。每个目标 σ 选择平均响应宽度最接近的整数半径, 因此它的实际宽度不一定恰好等于目标值。优化链使用该档对应的层数, 固定外围采样数为 4,4,7, 拟合三个核的角度、中心权重和半径, 以及各层混合系数与原图混合系数。
每档只监督相位 (0,0) 的单位冲激, 使用完整二维平方误差, 从四组固定初值与相近尺度的解出发;在 σ=4,40 时, 还加入附录 D 列出的单相参数作为初值, 经 L-BFGS-B 求解, 再用同层数的左右相邻档参数补算一轮, 保留误差最低的一组。“最佳结果”指这些候选中误差最小的数值解, 不表示已证明全局最优。滑条切换时读取该档独立求得的参数, 在 GPU 上实时运行完整滤波链。横截面与误差预先从同一组参数的 float64 参考响应计算并缓存, 无需每帧读回 GPU。Gaussian 在原分辨率离散采样, 截断到 5σ 后归一化。
每张画布的宽高比为 1:2:上半部分显示完整 sinc 图的模糊结果, 下半部分显示单冲激。两部分各自按 512×512 计算, 在每级采样中先将越界坐标镜像折回所属区域, 再读取像素;分界处不会互相混入。此交互图的 Gaussian 与 Kawase 均采用这一镜像边界, 因而 sinc 图边缘与前文采用 clamp 的静态对比存在边界约定上的差异。
上半部分始终以 1× 显示 sinc 图。“冲激增强灰度”开关同时控制三图的下半部分。开启时以目标 Gaussian 峰值作为共同曝光基准, 放大弱响应以查看形状;关闭时按单位冲激的原始幅度显示, 不做曝光或峰值归一化。开关不改变 sinc 图、冲激横截面与冲激误差。
5. 平移输入, 检查相位误差
保持 σ=40 的单相优化参数不变, 将冻结参数后的处理链记为 FB, 把 sinc 测试图记为 I, 向右平移一个像素的操作记为 T1。如果滤波链平移不变, 那么先平移输入再模糊, 应当等于先模糊再平移输出:
FB(T1I)=T1FB(I).
因此需要比较这两个已经对应到相同位置的输出, 并观察它们的差值:
Eshift=FB(T1I)−T1FB(I).
评测应避开有限图像的边界影响, 横截面也使用一致的空间坐标。实际平移对照图尚待补充。
输入相对于固定降采样网格的位置, 就是这里的相位。同一个局部信号移动后, 落入采样网格的权重会改变, 后续重建再将这些样本扩散回原分辨率。
Dual Kawase 同样反复经过固定网格的降采样与重建。因此它虽然保持线性, 通常并不满足逐像素的平移不变性;一个相位的冲激响应不能直接当作所有位置共用的卷积核。单个 pass 的采样模板对称, 也不保证每个输入位置得到的完整响应都关于输入点对称。
这揭示了单冲激损失的遗漏: 即使把受监督位置的响应拟合得非常接近 Gaussian, 其他相位的响应仍没有被直接约束。只在同一个位置继续压低损失, 无法检查这些位置上的误差。
单冲激目标的局限在于监督不完整。 即使假设 Lsingle 已经降到零, 也只确定了一个位置的响应;把冲激移到其他相位, 仍可能产生形状误差。接下来需要枚举全部相位、将它们共同纳入优化, 再检验在相同采样预算下能否进一步改善。
多相位优化 Kawase
1. 多相位冲激响应
多相监督的框架
DPF 论文第 4.2 节把这类固定网格的多分辨率滤波链建模为线性周期移变系统(LPSV): 在边界影响之外, 平移一个像素可能改变响应形状, 但平移完整的采样周期后, 响应模式重复。
论文据此将单冲激监督扩展为多相冲激监督。离线阶段, 在一个周期内的不同位置分别放置单位冲激, 运行同一条滤波链;目标核也分别平移到对应的输入位置。将所有响应与目标的平方误差相加, 通过可微滤波运算优化稀疏采样的位置和权重。运行时直接使用求得的核处理图像, 多组冲激只在离线求解时使用。
完整 DPF 还包含 Spatial-to-Depth、亮度与色度的不对称采样, 以及可变核的层级选择。本文接下来只把其中的多相监督方法应用到前面定义的共享 Kd,4,Kd,2,Ku 与混合参数族, 用于检验补全监督相位的作用;采样数量、层数与参数约束都沿用 B。
σ=4: 枚举全部输入相位
为了完整展示各个相位, 这里改用 σ=4、首次四倍、再一次二倍下采样的链路, 并针对这个目标重新做单相拟合, 得到该尺度下的 B。后面的多相优化也固定在 σ=4, 两种方案使用相同层数与参数范围。先检查这个尺度下的单相拟合结果:
σ=4 · 输入相位 (0,0) · 响应图共用 2× 显示增益,无裁切;A—A 标出中心行,下方叠加该截面的原始值曲线,灰色虚线为 Gaussian。

Android Kawase V2
二维 RMSE 3.262e-3

B · 单冲激平方误差拟合
二维 RMSE 3.803e-5

先不改变 B 的核, 只改变冲激在图像中的位置。对于首次四倍下采样、再经过 N 级二倍下采样及逐级重建的链, 每轴的相位周期可以取为
P=4⋅2N,ϕ(n)=(nxmodP,nymodP).
N 不计首次四倍下采样。σ=4 时 N=1, 需要检查 8×8=64 个输入相位;σ=40 时 N=3, 需要检查 32×32=1024 个。A、B、C 在相同尺度下使用相同的链路和相位集合。
选择远离边界、两个坐标均为 P 倍数的基准位置 n0, 将单位冲激 δϕ 放在 n0+ϕ。以各自输入点为原点, 定义响应
Rϕ[r]=F(δϕ)[n0+ϕ+r],ϕ∈{0,…,P−1}2.
单相拟合监督的中心位置对应相位 (0,0)。下面默认展示 B 在 σ=4 下的全部 64 个响应, 也可以切换 Gaussian 和 A, 以卡片的相位坐标为准。同一方案的所有图共用显示增益与坐标范围, 切换方案时按标注设置增益与纵轴;曲线零点始终是输入位置。A 在小半径下含有原图直通产生的尖峰, 因此使用较低的显示增益。
Gaussian 的各相位响应一致;A、B 的响应随相位改变。响应质量、质心与宽度统计放在附录 C。
这组响应共同决定了滤波链对任意输入的行为。在远离边界处, 线性叠加给出
(FI)[m]=n∑I[n]Rϕ(n)[m−n].
只有输入对齐后的 Rϕ 全部相同, 才能用一个通用卷积核替代整条链。B 只优化了其中一个相位, 因此下一步应当把整组响应一起纳入损失。
用多相损失重新评价单相拟合
按论文式 (5)、(6), 将目标 Gaussian 平移到每个冲激的位置。对于 B/C 使用的完整参数组 (Kd,4,Kd,2,Ku,α,β), 定义
Lpoly(Kd,4,Kd,2,Ku,α,β)=ϕ∑F(Kd,4,Kd,2,Ku,α,β)(δϕ)−SϕGσ22=ϕ∑∥Rϕ−Gσ∥22.
Sϕ 将中心目标核平移到 n0+ϕ;右边则统一改用相对输入点的坐标。目标与输入一起移动, 各相位的形状差异保留在残差中。
用全部相位重新评测, 定义
RMSEall=P2M21ϕ∑∥Rϕ−Gσ∥22,
其中 M 是单幅响应的边长, 本节 σ=4 的实验使用 M=128。最差相位 RMSE 取各相位 RMSE 的最大值;全相位 RMSE 是先汇总平方误差再开方, 不是各相位 RMSE 的算术平均。
单相 RMSE 只评价被直接监督的位置, 全相位 RMSE 汇总全部 64 个输入相位;两者不能互相替代, 具体数值见下方误差表。
2. 单 σ 多相位优化
保持相同的优化变量
将多相优化方案记为 C。C 沿用 B 的三个圆周核、所有混合系数、非负单位和权重、半径范围和跨层共享方式, 也使用相同的四组初值与 L-BFGS-B 求解器。两者只改变监督集合: B 使用 (0,0), C 使用全部相位。
最小化多相损失
最小化这个损失, 得到多相优化方案 C:
(Kd,4,Kd,2,Ku,α,β)C≈Kd,4,Kd,2,Ku,α,βargminLpoly(Kd,4,Kd,2,Ku,α,β).
计算权重与采样偏移的梯度
bilinear 插值对采样位置分段可微, 加权和对权重可微, 因此单相、多相两种最小二乘目标都能通过完整链计算梯度。第一部分使用的也是这一求解方式;本节增加的是参与损失的输入相位。
更新参数并对照优化结果
下面固定 σ=4, 比较 Gaussian、单相优化 B 和多相优化 C 的单点与 sinc 输出。B、C 各自包含一套 Kd,4、一套 Kd,2 和跨层共享的 Ku, 以及各层混合系数, 运行时使用同一条链处理整幅图像;各尺度的完整参数表见附录 D。
σ=4 · 输入相位 (0,0) · 响应图共用 20× 显示增益,无裁切;A—A 标出中心行,下方叠加该截面的原始值曲线,灰色虚线为 Gaussian。

B · 单冲激平方误差拟合
二维 RMSE 3.803e-5


σ=4 · B/C:4× 起始下采样,1 级 2× down/up · 输出均无显示增益

B · 单冲激平方误差拟合
图像 RMSE 3.486e-2


Gaussian · AE ×1
max 0 · 无裁切

B · AE ×1
max 3.066e-1 · 无裁切

C · AE ×1
max 2.209e-1 · 无裁切

| 方案(σ=4) | 相位 (0,0) RMSE | 全相位 RMSE | 最差相位 RMSE | sinc 图像 RMSE |
|---|
| B: 单相优化 | 3.803e-05 | 5.795e-04 | 8.595e-04 | 3.486e-02 |
| C: 多相优化 | 1.956e-04 | 2.357e-04 | 3.117e-04 | 1.531e-02 |
在这个尺度下, 全相位 RMSE 降低约 59.34%, sinc 图像 RMSE 降低约 56.07%。这些数值分别评价整组冲激响应和这一张测试图。
C 在 (0,0) 上的误差高于 B, 但整组相位的总平方误差更低。这说明 B 找到的单点拟合结果仍有改进空间: 相同的参数族和采样预算, 可以求得更接近全相位 Gaussian 响应的另一组核与混合参数。不过, C 也受有限采样模板约束, 并不保证所有相位都变得相同。
3. 多 σ 多相位优化
对各个 σ 逐点求解
不同目标尺度需要分别确定层数与核参数。下表保留两个已经独立求解的尺度;它们只能说明这两个目标下的结果, 尚不足以建立连续 σ 的参数映射。
| 目标 σ | 二倍下采样层数 N(首个 4× 之外) | 每轴相位周期 | 二维相位数 |
|---|
| 4 | 1 | 8 | 64 |
| 40 | 3 | 32 | 1024 |
拟合随 σ 变化的参数
使用拟合参数重新运行完整链路
多相位优化降采样模糊
1. 固定 Mip 的降采样模糊链路
这部分将多相监督应用到共享 Mip 金字塔模糊方案: 先用固定 Box 核生成共享 Mip 金字塔, 再在最终分辨率的输出像素上, 用小核采样所选 Mip 层。模糊覆盖范围来自 Mip 层级与末端采样核的共同作用。
该方案在最终分辨率直接采样 Mip;其运行流程与 Kawase 的逐级上采样链不同。以下先明确优化约束和求解步骤, 优化结果尚待补充。
2. 优化变量与运行约束
- 固定共享 Mip 核。 所有 σ 使用同一套固定降采样结果, 每个 σ 只求最终采样的权重和偏移。
- 固定采样预算。 明确最终 pass 的采样次数, 原算法与优化后算法使用相同预算;共享 Mip 的构建成本单独记录。
- 连续模糊半径。 参数拟合后应检查相邻 σ 的输出, 以及 Mip 层级切换处的变化。
- 沿用原算法的 Mip 层级选择规则。 层级选择不作为本轮连续参数优化的变量。
3. 多 σ 多相位优化
对各个 σ 逐点求解
固定共享 Mip 与该 σ 对应的层级, 枚举输入相位, 对末端采样参数建立多相平方误差目标。
拟合末端采样参数
使用拟合参数重新运行完整链路
4. 原算法与多相优化结果对照
附录: 补充推导、对比与复现资料
A. Android 基线的实现修订
本文的 A、B、C 与交互演示均使用同一个 Android 派生实现。它保留 V2 的四倍起始缩放、逐层二倍缩放、层间混合与原图混合, 修订以下两项。这里记录的是本文采用的版本, 不代表 AOSP 已经合入这些改动。
方向常量的两个符号
固定的 AOSP 修订将上采样方向描述为正七边形, 但 STEP_4.x 与 STEP_6.x 的符号和对应顶点不符:
| 常量 | 原值 | 本文值 |
|---|
| STEP_4.x | +0.900968868 | −0.900968868 |
| STEP_6.x | −0.623489802 | +0.623489802 |
A 保留这些常量的小数精度;B/C 和交互演示通过正七边形的三角函数生成方向。七边形的采样点重心为零, 但它不同时关于 x、y 两轴对称, 也不保证离散响应的峰值位于重心。
下采样与上采样的基准坐标补偿
本文以输入相位 (0,0) 为对齐基准。采用整数像素索引时, 原实现的首个四倍下采样等价于对不重叠的 4×4 输入块求平均: (256,256) 处的冲激落入索引 256∼259 的块, 对应低分辨率像素 (64,64)。原四倍重建把它的中心映回 (257.5,257.5), 因此模糊分支每轴多出 1.5 个原图像素的位移。
补偿必须放在每次上采样的取样坐标里、与同层图像或原图混合之前。对当前核参数, 先用固定的相位 (0,0) 冲激生成下采样金字塔。记第 i 层响应相对于该层基准位置的质心为 μi, 单位为该层 texel。二倍重建在未补偿时将子层质心映到 2μi+1+211, 因此需要减去的输出位移是
di=2μi+1+211−μi,oi=di/2.
oi 是加到该次采样坐标上的输入 texel 偏移。它让重建分支与保存的第 i 层具有相同的基准质心, 随后才进行层间混合。最后四倍重建使用 of=μ0+831, 使模糊分支回到原图基准位置, 再进行原图混合。
这些 offset 由核参数和固定参考冲激确定, 不是额外的可优化变量;同一组参数对整张图、所有相位使用同一组 offset, 不依据正在处理的图片重新定位。优化时也传播 offset 对核参数的导数。参考响应为零时没有质心, 使用有限的中性回退值并保留零响应及其损失。
对 A 的原始模板, μ0=0;二倍下采样的权重恰好使 di=0, 最后四倍重建的输出补偿为每轴 1.5 像素。此时原取样位置与本文取样位置分别为
cnative(n)=4n+1/2−21,carticle(n)=cnative(n)+41.5=4n.
但这个简化不能直接沿用于任意优化参数。例如 Kd,2 与 Ku 都退化为中心采样时, 子层响应位于索引 32, 未补偿的二倍重建中心位于父层 64.5, 而父层保存的响应位于 64。此时需要在该次二倍上采样增加每轴 0.25 输入 texel, 即向左、向上各补偿半个父层像素。只补偿最终四倍重建, 仍会让两个内部中心错开的分支先混在一起。
上述操作保留下采样和上采样的采样模板, 只调整整组采样点的共同坐标偏移;不增加预滤波或额外的图像平移 pass。每组核参数确定后, 参考探针和 offset 可以预先计算, 实际图像只执行原有采样与混合链。
例如 blurRadius=6, 未补偿时, 相位 (0,0) 模糊分支每轴偏 1.5 像素, 混合原图后偏 0.9 像素;补偿后两者均回到输入重心的数值误差范围。这是指定相位的坐标补偿, 不是逐相位对齐。 同一块里的其他输入位置仍共享首层样本: 冲激沿对角线移动到相位 (1,1),(2,2),(3,3) 后, 完整输出每轴偏移为 −0.6,−1.2,−1.8 像素。这些真实的相位差异原样进入正文的多相损失。
原版逐 pass 核对保存在 android-coordinate-audit.json。A 的本文版核对使用 verify_aosp_kawase_v2_skia --registered: 原始模板的内部 offset 为零, 在独立 Skia 执行中将最终模糊 shader 的矩阵平移设为 (−1.5,−1.5) 原图像素, 再与 float64 实现对照。CPU F32 验证覆盖 σ=4,8 的全部 64 个相位、σ=16,40 的各八个分散相位、sinc 图和奇数尺寸边界, 记录见 android-registered-skia-validation.json。
对于可变核, test_android_kawase_core.py 另外覆盖 N=1,2,3 的纯中心核与一般核, 逐层比较混合前后质心, 并检查最终基准对齐、其他相位差异、直接渲染与频域求值, 以及包含 offset 导数的完整梯度。交互演示有对应的 TypeScript 检查。
B. Gaussian5x5 单阶段冲激实验
居中冲激
下面用一条单阶段链演示冲激评测: Gaussian5x5 预滤波, 按偶数网格二倍抽取, 在低分辨率上执行 7×7、σ=1.5 Gaussian, 再用三角核重建。它用于单独观察抽取网格对冲激响应的影响, 正文的 Kawase 拟合使用另一条完整链路。这里仍将处理链记为 P, 其居中冲激响应为 K=P(δ)。



向右平移一个像素的冲激
保持处理链和核参数不变, 只把输入冲激向右移动一个像素。若系统平移不变, 新输出应当恰好等于原响应向右平移:
P(δ(x−1))=K(x−1),K=P(δ).
继续使用上面的 Gaussian5x5 单阶段演示链, 只改变输入位置, 得到:
输入
离散冲激
δ(x−1)(中心区域放大)



与上面的居中冲激响应相比, 输出不只是位置改变, 形状也发生了变化, 即
P(δ(x−1))=K(x−1).
原因在于抽取网格保持固定: 冲激在偶数位置和奇数位置时, 预滤波后的权重落在不同的采样位置上, 进入低分辨率图像的数值随之改变。后续重建又把这些样本扩散回高分辨率。输入相对于固定网格的位置, 就是这里的相位。
C. 各相位的响应统计
Gaussian 的各相位响应一致;Kawase 链的响应仍可能随相位改变。A、B、C 均使用 P=4⋅2N 的周期, 在 σ=4 时有 64 个相位, 在 σ=40 时有 1024 个。指标完整枚举所有相位。
响应质量是权重之和, 质心偏移以输入点为零点, 单轴 σ 根据相对于自身质心的二阶矩计算。即使质量和质心一致, 也不代表宽度、峰值或轮廓一致。上采样核是七边形, 不应把响应额外做双轴镜像平均;用于半径校准的平均响应宽度也不同于单相宽度范围。
σ=4 · 各方案遍历自身完整周期。单相 σ 按自身质心计算;零响应没有质心和 σ,不计入这两项范围。| 方案 | 相位数 | 零响应数 | 响应质量范围 | 非零响应单轴 σ 范围 | 最大单轴质心偏移 / px |
|---|
| Gaussian | 64 | 0 | 1.000000 – 1.000000 | 4.0000 – 4.0000 | 0.0000 |
| Android Kawase V2 | 64 | 0 | 1.000000 – 1.000000 | 3.7924 – 4.1115 | 1.8000 |
| B · 单冲激平方误差拟合 | 64 | 0 | 0.011936 – 1.516197 | 3.9149 – 4.0019 | 7.9551 |
σ=40 · 各方案遍历自身完整周期。单相 σ 按自身质心计算;零响应没有质心和 σ,不计入这两项范围。| 方案 | 相位数 | 零响应数 | 响应质量范围 | 非零响应单轴 σ 范围 | 最大单轴质心偏移 / px |
|---|
| Gaussian | 1024 | 0 | 1.000000 – 1.000000 | 39.9997 – 39.9997 | 0.0000 |
| Android Kawase V2 | 1024 | 0 | 1.000000 – 1.000000 | 39.6610 – 40.0073 | 3.0000 |
| B · 单冲激平方误差拟合 | 1024 | 0 | 0.987726 – 1.018213 | 38.9098 – 40.7909 | 3.8414 |
D. 完整参数、补充对比与误差分析
两个目标尺度的核参数与拟合指标
A 使用前述 Kawase 基线参数, B、C 分别用单相、多相目标求解。下表汇总 σ=4 与 σ=40 的参数与冲激误差;各尺度都使用自己的参数, B、C 的采样预算和参数范围相同。
σ=4 · N=1| 方案 | 核 | θ / rad | w_c | a / 输入 texel |
|---|
| B · 单冲激平方误差拟合 | K_d,4 | 0.535265 | 0.369428 | 1.752996 |
| B · 单冲激平方误差拟合 | K_d,2 | 2.013296 | 0.999963 | 0.398384 |
| B · 单冲激平方误差拟合 | K_u | 0.496114 | 0.026407 | 0.250000 |
| C · 多相优化 | K_d,4 | 0.785398 | 0.000009 | 1.404174 |
| C · 多相优化 | K_d,2 | 0.785398 | 0.199184 | 1.335039 |
| C · 多相优化 | K_u | 0.161356 | 1.000000 | 0.250000 |
| 方案 | α_0 | β |
|---|
| B · 单冲激平方误差拟合 | 0.988770 | 1.000000 |
| C · 多相优化 | 0.914917 | 0.996897 |
σ=40 · N=3| 方案 | 核 | θ / rad | w_c | a / 输入 texel |
|---|
| B · 单冲激平方误差拟合 | K_d,4 | 0.785398 | 0.002948 | 1.410899 |
| B · 单冲激平方误差拟合 | K_d,2 | 0.769632 | 0.297705 | 1.503566 |
| B · 单冲激平方误差拟合 | K_u | -0.113638 | 0.389194 | 1.573893 |
| C · 多相优化 | K_d,4 | 0.785398 | 0.000000 | 1.414104 |
| C · 多相优化 | K_d,2 | 0.783856 | 0.019230 | 1.140882 |
| C · 多相优化 | K_u | 0.004392 | 0.373370 | 1.546569 |
| 方案 | α_0 | α_1 | α_2 | β |
|---|
| B · 单冲激平方误差拟合 | 0.999995 | 0.999846 | 1.000000 | 1.000000 |
| C · 多相优化 | 1.000000 | 1.000000 | 1.000000 | 1.000000 |
σ=4 · 每个响应 128×128 · A 汇总 64 个相位,B/C 汇总 64 个相位;各自先取平均平方误差再开方。| 方案 | (0,0) RMSE | 全相位 RMSE | 最差相位 RMSE |
|---|
| Gaussian | 0 | 0 | 0 |
| Android Kawase V2 | 3.262e-3 | 3.159e-3 | 3.262e-3 |
| B · 单冲激平方误差拟合 | 3.803e-5 | 5.795e-4 | 8.595e-4 |
| C · 多相优化 | 1.956e-4 | 2.357e-4 | 3.117e-4 |
σ=40 · 每个响应 512×512 · A 汇总 1024 个相位,B/C 汇总 1024 个相位;各自先取平均平方误差再开方。| 方案 | (0,0) RMSE | 全相位 RMSE | 最差相位 RMSE |
|---|
| Gaussian | 0 | 0 | 0 |
| Android Kawase V2 | 1.760e-6 | 1.864e-6 | 2.049e-6 |
| B · 单冲激平方误差拟合 | 2.063e-7 | 8.268e-7 | 1.399e-6 |
| C · 多相优化 | 3.026e-7 | 5.494e-7 | 1.027e-6 |
σ=4:B 的相位 (0,0) RMSE 为 3.803e-5,C 为 1.956e-4;全相位 RMSE 从 B 的 5.795e-4 变为 C 的 2.357e-4,降低 59.34%。
σ=40:B 的相位 (0,0) RMSE 为 2.063e-7,C 为 3.026e-7;全相位 RMSE 从 B 的 8.268e-7 变为 C 的 5.494e-7,降低 33.55%。
补充 sinc 图像对比
先补充 σ=4 时 Gaussian、Kawase 基线 A 与单相优化 B 的 sinc 对比, 再展示 σ=40 时 Gaussian、B、C 的结果。图像计算和 AE 显示规则见附录 E。
σ=4 · A:Android blurRadius=6;B:4× 起始下采样,1 级 2× down/up · 输出均无显示增益

Android Kawase V2
图像 RMSE 5.722e-2

B · 单冲激平方误差拟合
图像 RMSE 3.486e-2

Gaussian · AE ×1
max 0 · 无裁切

A · AE ×1
max 4.984e-1 · 无裁切

B · AE ×1
max 3.066e-1 · 无裁切

σ=40 · B/C:4× 起始下采样,3 级 2× down/up · 输出均无显示增益

B · 单冲激平方误差拟合
图像 RMSE 4.631e-3


Gaussian · AE ×20
max 0 · 无裁切

B · AE ×20
max 3.029e-2 · 无裁切

C · AE ×20
max 3.055e-2 · 无裁切

σ=4:B 的 sinc 图像 RMSE 为 3.486e-2,C 为 1.531e-2,降低 56.07%。这个百分比只比较 B/C,采样预算、参数族与边界规则相同。
σ=40:B 的 sinc 图像 RMSE 为 4.631e-3,C 为 4.596e-3,降低 0.75%。这个百分比只比较 B/C,采样预算、参数族与边界规则相同。
上表分别报告全相位冲激误差与 sinc 图像误差。全相位监督改善的是完整核支撑上的响应目标, 有限尺寸图像还包含逐级 clamp 的边界行为与具体输入结构, 两种指标不能互相替代。
平均核形状误差与相位差异
为了区分平均形状的近似误差与相位差异, 取输入对齐后的平均响应
Rˉ=P21ϕ∑Rϕ.
平方误差满足精确分解:
总误差P21ϕ∑∥Rϕ−Gσ∥22=平均核形状误差∥Rˉ−Gσ∥22+相位差异P21ϕ∑∥Rϕ−Rˉ∥22.
交叉项为零, 因为 ∑ϕ(Rϕ−Rˉ)=0。即使平均响应已经很接近高斯, 只要各相位仍有差异, 总误差就不会消失。表中最后两列将这两项分别除以响应像素数再开方, 所以它们的平方和等于全相位 RMSE 的平方。
σ=4 · sinc 为 512×512;“内部”去掉四周 32 px;最后两列平方和等于全相位 RMSE 的平方。| 方案 | 图像 RMSE | 最大 AE | 内部 RMSE | 平均核形状 RMSE | 相位离散 RMS |
|---|
| Gaussian | 0 | 0 | 0 | 4.838e-19 | 0 |
| Android Kawase V2 | 5.722e-2 | 4.984e-1 | 5.966e-2 | 3.145e-3 | 2.986e-4 |
| B · 单冲激平方误差拟合 | 3.486e-2 | 3.066e-1 | 3.633e-2 | 3.870e-4 | 4.314e-4 |
| C · 多相优化 | 1.531e-2 | 2.209e-1 | 1.604e-2 | 2.000e-4 | 1.247e-4 |
σ=40 · sinc 为 512×512;“内部”去掉四周 32 px;最后两列平方和等于全相位 RMSE 的平方。| 方案 | 图像 RMSE | 最大 AE | 内部 RMSE | 平均核形状 RMSE | 相位离散 RMS |
|---|
| Gaussian | 0 | 0 | 0 | 1.925e-19 | 0 |
| Android Kawase V2 | 4.809e-3 | 2.889e-2 | 2.187e-3 | 1.817e-6 | 4.121e-7 |
| B · 单冲激平方误差拟合 | 4.631e-3 | 3.029e-2 | 1.826e-3 | 4.441e-7 | 6.974e-7 |
| C · 多相优化 | 4.596e-3 | 3.055e-2 | 1.713e-3 | 2.874e-7 | 4.682e-7 |
“内部 RMSE”是去除原图四周 32 像素后的区域指标。对于 σ=40 的大支撑核, 这个区域仍可能受到边界影响, 不能将它视为完全排除了边界的实验。
B 的单冲激目标约束指定位置的响应, 从 B 到 C 则补全了被遗漏的相位监督。A、B、C 使用相同的链路;A 仅匹配整数半径, B/C 则优化核与混合参数。多相损失并不分别保证质心、最差相位或每张图像的误差都减小。
冲激指标与实际图像误差的关系
对于像素独立、零均值、等方差的输入噪声, 输出误差能量的期望正比于响应误差的平方和;真实图像存在空间相关性, 不同位置的响应误差可能相互抵消或叠加。因此评测降采样模糊时, 应同时检查完整的多相冲激响应和实际图像结果: 前者衡量系统在不同输入位置上的近似能力, 后者检验具体图像与边界条件下的成像效果。
E. 数值配置与复现
Android 半径与目标 σ 的匹配
A 使用附录 A 定义的基线, 模板权重、层数调度、采样距离与混合系数由整数 blurRadius 决定。不能把这个半径直接当作 Gaussian 的标准差, 也不能用某一个相位的宽度代表整条链。
对每个候选半径 r, 将自身完整周期内的 P(r)2 个响应按各自输入点对齐后取平均, 得到质量为一的 Rˉr。记它的质心为 μr, 取两个方向中心方差的平均值作为匹配尺度:
σA2(r)=21x∑∥x−μr∥22Rˉr[x],rA=r∈Z≥0argmin∣σA(r)−σ∣.
这一步只匹配扩散宽度, 没有用 Gaussian 响应的形状误差拟合权重或偏移。数值实现传播各次采样和插值的矩, 并通过显式枚举全部相位验证;首次下采样、逐级重建、层间混合、最终四倍放大和小半径混合均计入。用中心矩测量宽度不等于移动输出, 图像与损失仍以输入点为原点。
目标 σ=4,8,16,40 分别选择整数半径 6,17,32,90, 对应平均响应标准差约为 3.9817,8.0894,16.0737,39.8502。小半径的整数步进较粗, 宽度匹配本身也存在残差, 详见上表。
为复现 Android 的内部半径调度, 数值移植直接沿用源码计算: ρ=0.57735r、连续层深 d=min(3,ρ/10)、N=⌈d⌉、αi=min(1,d−i)。源码中的 step 记为 s, 其值由这些量唯一确定;半径匹配只搜索 r。在 shader 坐标中,
s=∑i=0N−1(2iαi)2max(0,(ρ/4)2−∑i=0N−1(2i−1αi2)2).
当 N=0 时取 s=0;在尺寸恰好二倍的上采样 pass 中, s 个 shader 像素对应 s/2 个输入 texel。
静态图表与数值指标使用 float64 线性亮度计算;σ 滑条的交互图像使用 float32 shader。实现与 Skia 的独立核对范围见附录 A。它们不是 Android 设备截图, 也不是性能测量。
冲激响应与求解配置
这里的 Gσ 与输入冲激同中心。损失累加完整二维响应的每个像素, 横截面只是展示方式。拟合时保留原始响应值, 不做峰值或质量归一化, 评测时不再单独移动输出质心。高斯目标按每轴 5σ 截断后归一化。后文固定参数的 B/C 对比在 σ=4 使用 N=1、在 σ=40 使用 N=3, 分别使用 128×128 与 512×512 响应画布。最终图表的画布覆盖完整核支撑;搜索过程中若候选核超出该范围, 会自动扩大求值画布, 避免循环卷积混叠。冲激渲染使用更大的零背景以隔离边界。
虽然残差采用最小二乘目标, 整条多级链对采样距离和权重的依赖仍是非线性的。固定参数的 B/C 对比使用带解析梯度与参数边界的 L-BFGS-B, 从四组初值分别求解, 每组至多迭代 180 次, 再取损失最小的一组。求解器仅用固定的目标能量缩放损失, 不改变最优点。本文的“优化结果”指给定参数范围与这些初值下找到的最佳结果, 并不声称已经证明全局最优。
σ 滑条的 80 档单相拟合每组初值至多迭代 250 次, 同时使用相近尺度及附录 D 中同尺度的单相参数作为补充初值;该参数表独立保存, 后文 B/C 的全相位统计仍对应附录 D 列出的固定参数。滑条统一在 512×512 上渲染与计算 RMSE, 求解时则按核支撑自适应选择画布。两者均覆盖完整响应, 平方误差与目标能量的比值不受零背景大小影响。
大尺度链有 1024 个相位。为了避免求解时同时保存 1024 张大响应图, 数值实现用级联滤波器的相关运算, 精确计算全相位平方误差及其梯度;这与逐一累加所有相位的目标等价。最终核还会由独立的逐像素采样和混合链核对, 评测时显式枚举全部相位。
图像与误差显示约定
各组图按标题列出参与对比的方法。静态图像在 float64 线性亮度域中计算。A/B/C 的金字塔内部均使用 clamp, 最终重建使用 mirror;Gaussian 使用 clamp。带 AE 的对比图中, 每列上方为实际输出, 下方为相对 Gaussian 的绝对误差 AE=∣Imethod−IG∣。
静态输出均以 1× 显示。AE 在同一尺度内使用图中标注的固定倍率, 白色表示零误差, 没有显示裁切;两个尺度的倍率不同, 因此不能仅凭颜色深浅跨尺度比较误差。Gaussian 与自身比较, AE 为全白。σ 滑条的原始模式在白底上按 1−h 显示响应 h;增强模式按 exp(−2.5h/Gσ(0,0)) 显示。显示值限制在 [0,1], 原始曲线与指标不经过这一映射。
复现命令与验证范围
开篇的四组 Gaussian / Android V2 图像对比可用 python3 -m scripts.generate_android_sinc_comparison 单独生成;半径、图像误差和原图哈希记录在 content/blog/differentiable-polyphase-filtering/android-sinc-comparison-data.json。
σ 滑条的参数可用 python3 -m scripts.fit_single_phase_sweep 重新生成, 依赖 NumPy、SciPy、Numba;--resume 从已保存的档位继续, --workers 1 使用单进程。首轮完成后再运行 python3 -m scripts.fit_single_phase_sweep --polish, 将同层数的左右相邻档参数作为补充初值求解。single-phase-sweep-data.json 保存每档参数、坐标补偿、整数半径、各初值与最终损失。再运行 bun scripts/generate_single_phase_cache.ts, 将 shader 参数、float64 横截面和误差打包为单个压缩缓存文件, 不保存各档图像。python3 -m unittest scripts.test_single_phase_sweep 核对完整空间渲染、频域损失与梯度;bun test content/blog/differentiable-polyphase-filtering/single-phase-response.test.ts 核对 80 档参考响应、零档直通, 以及缓存与源参数、中心行取样和误差的一致性。single-phase-image.test.ts 另行核对软件镜像延拓、Gaussian 与直接二维卷积的一致性, 以及镜像边界下原有冲激响应与常量输入的保持。
复现。 运行 python3 -m scripts.fit_polyphase_dual_kawase 会重新求解 B/C, 并生成配图与 content/blog/differentiable-polyphase-filtering/four-way-blur-data.json;加 --reuse-fits 可直接使用已保存的参数重新生成结果。数据记录原图哈希、采样约定、最终位置和权重、全部相位指标, 以及四个初值的损失。可优化的完整链位于 scripts/android_kawase_core.py, Android V2 移植与半径校准位于 scripts/aosp_kawase_v2.py。验证命令为 python3 -m unittest scripts.test_android_kawase_core scripts.test_polyphase_dual_kawase scripts.test_aosp_kawase_v2 scripts.test_aosp_kawase, 覆盖逐 pass 采样、解析梯度、全相位损失、独立渲染器和图像指标的一致性。
可另安装 skia-python==144.0.post2, 运行 python3 -m scripts.verify_aosp_kawase_v2_skia --registered --sigmas 4 8 16 40, 核对本文基线;去掉 --registered 则核对保留在 scripts/aosp_kawase_v2_reference.py 中、仅改两个符号的历史版本。两者的验证记录及位置差异说明见附录 A。
F. 旧版 Android Kawase 参考
AOSP 还包含旧的 KawaseBlurFilter.cpp。它在首次四倍下采样时就使用随半径变化的偏移, 随后在同一低分辨率上执行中心加四个对角、各占 1/5 的模糊 pass, 最多四次。这个实现与本文 A 所用的 V2 有不同的采样覆盖和金字塔结构。
旧版按同样的平均响应宽度原则匹配 σ=40 时选取 blurRadius=92。此时首个 pass 的原图偏移为 11.5, 采样中心为 4k+1.5, 每轴只读取模四余数为一或二的输入像素, 导致 16 个相位中有 12 个冲激完全漏采样。原版 V2 首次覆盖完整 4×4 块, 避免了这种完全遗漏;正文采用附录 A 定义的坐标约定。旧版数值移植与验证保留在 scripts/aosp_kawase.py、scripts/test_aosp_kawase.py, 不计入正文 A 的数据。