☰
高斯核Caputo-Fabrizio分数阶导数:闭式推导与Matlab实现
2026/10/14 5:54:47 网站建设 项目流程

做图像边缘检测那段时间,我最头疼的不是梯度算子怎么写,而是噪声和边缘响应总是打架。Sobel在干净图像上确实利落,可图像一旦带噪,输出全是高频毛刺,阈值怎么调都难受。后来我转向分数阶导数这条技术路线,从经典Caputo定义一路试到Caputo-Fabrizio(CF)分数阶导数,发现思路对了,但按定义做变上限数值积分效率实在不理想。直到把核函数从指数衰减换成高斯函数,整个问题忽然好看了很多——基于高斯函数的Caputo-Fabrizio分数阶导数,可以推导出漂亮的闭式表达式,Matlab里几行代码就能实现,还能直接用在信号滤波和图像边缘检测上。这篇文章就把这套思路、公式和代码完整记录下来,适合正在做信号处理、图像增强,或者想用分数阶算子但被理论推导劝退的朋友。

1. 分数阶导数的工程落地瓶颈,以及为什么选高斯核

1.1 先理解Caputo-Fabrizio导数和老版本的区别

经典分数阶导数的定义里,Riemann-Liouville和Caputo两套体系虽然在数学上等价,但Caputo形式对初值问题的处理更友好。不过它们的核函数都是幂律型,也就是带有((t-\tau)^{-\alpha})这类奇异核,积分在(\tau\to t)时会发散,数值计算必须做特殊处理,边界层的收敛速度也慢。

Caputo-Fabrizio定义在2015年前后被提出后,最大的变化是把奇异核换成了非奇异的指数衰减核。它的连续形式可以写作:

[ {}_0^{CF}D_t^\alpha f(t) = \frac{M(\alpha)}{1-\alpha}\int_0^t f'(\tau),\exp!\left(-\frac{\alpha(t-\tau)}{1-\alpha}\right)d\tau ]

其中(0<\alpha<1)是分数阶次,(M(\alpha))是归一化函数。这个定义的好处是核函数不再发散,工程上可以直接做离散卷积,做控制系统和信号滤波都方便。但真要用它处理一段几万点的信号,问题就出来了:核从积分下限一直延伸到当前时刻,变上限积分做严格计算是(O(N^2))的;即便窗长截短,也需要仔细管理历史状态。在图像上处理一个百万像素的矩阵时,这种计算代价就更明显了。

1.2 高斯核为什么能让问题变“好看”

指数核本身当然没问题,但工程上卷积计算最舒服的是对称核、短支撑核、以及频域表达式简单的核。高斯函数恰好三个都占:

第一,时域对称。指数核是单边衰减的,卷积之后会带来相位偏移;高斯核关于零点对称,对图像这类关注空间结构的场景,不会引入方向性畸变。

第二,频域形式极简。高斯函数做傅里叶变换后仍然是高斯函数:(G_\sigma(x))的频谱是(e^{-\sigma^2\omega^2/2})。这意味着“分数阶求导+高斯平滑”这个复合算子在频域里就是一次复指数乘法,原理上非常通透。

第三,闭式推导有依靠。高斯函数和误差函数之间有一整套漂亮的积分关系,任何一个工程上常见的输入信号——多项式、复指数、谐波、指数衰减——和高斯核卷积后都能写成初等函数加误差函数的有限组合,这才是所谓“闭式表达式”的真正底气。

说白了,把CF导数里的指数核换成高斯核,不是单纯换一个低通滤波器,而是把一个原本需要数值积分的问题,变成了可以直接查公式、直接写算子的工程问题。

2. 高斯核Caputo-Fabrizio导数的闭式推导,附可直接套用的公式

2.1 定义整理

基于高斯核的CF分数阶导数,我习惯写为:

[ \mathcal{D}\sigma^\alpha f(t) = \frac{M(\alpha)}{1-\alpha}\int_0^t f'(\tau),G\sigma(t-\tau),d\tau ]

其中:

[ G_\sigma(x) = \frac{1}{\sqrt{2\pi},\sigma} e^{-x^2/(2\sigma^2)} ]

(M(\alpha))在多数工程文献里取1,也有取(\frac{2}{2-\alpha})来调节幅度的版本。两种我都试过,区别主要在(\alpha)接近于1时的增益补偿上,下文应用部分会专门说。

先提醒一点:高斯核是对称双边核,而原版CF定义里指数核是单边因果核。所以这个新定义如果想严格从0积到t,等于是在高斯核上做了一次截断。截断本身会给闭式结果带来误差函数修正项,处理得当其实更好用。实际做工程信号时,我建议默认在频域用全卷积计算,再对边界做羽化处理,这个后面章节会给出完整代码。

2.2 频域闭式表达是最常用的主干公式

对平稳信号或长序列信号,把卷积区间近似为全实数域后,由卷积定理可以直接得到:

[ \widehat{\mathcal{D}_\sigma^\alpha f}(\omega) = \frac{M(\alpha)}{1-\alpha},j\omega, e^{-\sigma^2\omega^2/2},\hat{f}(\omega) ]

这个式子信息量很大,值得拆开看。前半部分(\frac{M(\alpha)}{1-\alpha})是常数增益,做大信号时只需要一次乘除;(j\omega)就是一阶导数的频域算子;(e^{-\sigma^2\omega^2/2})则是高斯核带来的低通因子。整体效果是:求导的同时按频率做加权衰减,(\sigma)越大,高频压制越强。

所以这个算子天然就是一个“频带可调的微分器”。对单频信号(f(t)=\cos(\omega_0 t)),忽略边界瞬态时有:

[ \mathcal{D}_\sigma^\alpha \cos(\omega_0 t) = -\frac{M(\alpha)}{1-\alpha},\omega_0,e^{-\sigma^2\omega_0^2/2},\sin(\omega_0 t) ]

也就是说输出还是同频正弦,幅度乘了一个与频率和(\sigma)都有关的增益系数。这个结论对做滤波器设计非常直观:想要保留哪个频段,直接根据(\omega_0)反推允许的(\sigma)范围即可。

2.3 时域闭式结果族:多项式、指数、三角

频域公式适合写代码,但真正体现“闭式表达式”价值的是时域结果。以最常用的多项式输入(f(t)=t^n)为例,通过换元(u=t-\tau)和分部积分,可以推出如下递推结果:

[ \mathcal{D}\sigma^\alpha t^n = \frac{M(\alpha),n}{1-\alpha}\sum{k=0}^{n-1}(-1)^k\binom{n-1}{k},t^{n-1-k},Q_k(t;\sigma) ]

其中辅助函数族为:

[ Q_0(t)=\frac12,\mathrm{erf}!\left(\frac{t}{\sqrt2,\sigma}\right) ]

[ Q_1(t)=\frac{\sigma}{\sqrt{2\pi}}\left(1-e^{-t^2/(2\sigma^2)}\right) ]

[ Q_k(t)=\sigma^2,Q_{k-2}(t)-\sigma^2,t^{k-1}G_\sigma(t),\quad k\ge 2 ]

这套递推的优点在于:无论(n)多大,最终都只用到高斯函数(G_\sigma(t))和误差函数(\mathrm{erf}),而这两个函数在Matlab里都有内置函数,不需要为每个时间点单独做积分。对指数输入(f(t)=e^{ct}),也可以用高斯积分的完全平方配方得到:

[ \mathcal{D}_\sigma^\alpha e^{ct} = \frac{M(\alpha),c}{1-\alpha} e^{ct+\frac{c^2\sigma^2}{2}}\cdot \frac12\left[ \mathrm{erf}!\left(\frac{t-c\sigma^2}{\sqrt2,\sigma}\right) -\mathrm{erf}!\left(\frac{-c\sigma^2}{\sqrt2,\sigma}\right) \right] ]

我第一次推导这个公式时漏乘了一个(c)因子,导致用(t^2)做验证时数值差了整整一个数量级。后来学到的教训是:所有涉及链式法则的闭式推导,完成后先用最简单输入做极限验证,再谈效率优化。

2.4 闭式表达式对工程实现到底意味着什么

很多人觉得闭式表达式只是数学上的“好看”,实际用处不大,这个观点我不同意。至少有三点工程价值很直接:

其一,不需要为每个输出点重新做变上限积分。使用闭式递推时,输出序列可以向量化计算,一次把整段信号处理完。

其二,误差可控。数值积分要同时考虑步长、截断区间和核函数奇异性,闭式表达式只涉及误差函数与初等函数,底层的数值精度由语言库保证。

其三,可以借助递推关系做实时流式处理。对实时系统来说,维护一个无限长历史积分是很难受的事情,而局部高斯核配合有限阶递推,天然适合滚动窗口更新。

3. Matlab实现:一维信号算子和二维图像算子的完整代码

3.1 一维频域实现:主流程与关键细节

最稳妥的实现方式是频域法,核心就是上面那行频域闭式公式。下面这段代码可以直接复制运行,框架本身不依赖任何第三方工具箱:

function d = cf_gauss_deriv_fft(f, dt, alpha, sigma) % cf_gauss_deriv_fft 基于高斯核的CF分数阶导数算子(频域实现) % f 输入一维实信号,列向量或行向量均可 % dt 采样间隔,单位秒 % alpha 分数阶次,范围 (0,1) % sigma 高斯核标准差,单位与dt一致 % % 示例: % t = (0:999)' * 0.001; % f = sin(2*pi*5*t) + 0.3*sin(2*pi*120*t); % d = cf_gauss_deriv_fft(f, 0.001, 0.7, 0.002); % plot(t, d) if nargin < 3 || isempty(alpha), alpha = 0.7; end if nargin < 4 || isempty(sigma), sigma = dt; end f = f(:); N = numel(f); % 构造角频率网格,注意FFT的频率排列顺序 omega = (0:N-1)'; omega(omega >= N/2) = omega(omega >= N/2) - N; omega = 2 * pi * omega / (N * dt); % 一阶导数频域算子 j*omega deriv_op = 1i * omega; % 高斯核对频响 gauss_kernel = exp(-(sigma .* omega).^2 / 2); % 归一化常数 M(alpha) 默认取1,可替换为 2/(2-alpha) Malpha = 1; scale = Malpha / (1 - alpha); % 频域实施 F = fft(f); d = ifft(F .* deriv_op .* gauss_kernel .* scale, 'symmetric'); d = real(d); end

有两个细节值得展开讲。第一个是频率网格的构造,很多人直接用((0:N-1)-floor(N/2))*2*pi/(N*dt),结果忘了Matlab的fft输出是0频在第一个位置、正负频率混合排列的,导致整条曲线做出来是错的。上面代码里先构造0:N-1,再把大于等于N/2的索引减掉N,这样才能和fft的输出顺序对齐。

第二个是'symmetric'参数。这是Matlab在R2018b之后提供的IFFT对称实数化选项,它要求输入频谱在共轭对称误差范围内,使用它会自动去掉不可避免的浮点虚部。如果是旧版本,直接写real(ifft(...))即可。

3.2 二维图像算子:用小核卷积解决大图问题

图像处理和一维信号不太一样,频域法虽然快,但图像边界往往非周期,直接FFT会带来振铃伪影。对中等尺寸的图像,我更推荐直接在空间域构造高斯核,用conv2做有限支撑卷积,效率完全够用,边界行为也更好控制。

function D = cf_gauss_image(I, alpha, sigma, Malpha) % cf_gauss_image 基于高斯核的CF分数阶导数图像算子(空间域实现) % I 灰度图像,double类型,值域不限 % alpha 分数阶次 (0,1) % sigma 高斯核标准差,单位是像素,常用0.8~3 % Malpha 归一化函数,默认取1 % % 返回D为梯度幅度图,类似边缘强度响应 if nargin < 3 || isempty(sigma), sigma = 1.5; end if nargin < 4 || isempty(Malpha), Malpha = 1; end % 高斯核截断半径:6*sigma原则 L = ceil(6 * sigma); [x, y] = meshgrid(-L:L, -L:L); h = exp(-(x.^2 + y.^2) / (2 * sigma^2)); h = h / sum(h(:)); % 中心差分求一阶偏导 Ix = zeros(size(I)); Iy = zeros(size(I)); Ix(:, 2:end-1) = (I(:, 3:end) - I(:, 1:end-2)) / 2; Iy(2:end-1, :) = (I(3:end, :) - I(1:end-2, :)) / 2; % 高斯核卷积 Dx = conv2(Ix, h, 'same'); Dy = conv2(Iy, h, 'same'); % 幅度合成,并乘CF归一化系数 D = Malpha / (1 - alpha) * sqrt(Dx.^2 + Dy.^2); end

这里h是二维高斯核,归一化确保直流增益为1,这是后面数值稳定性的关键。conv2用到'same'模式,边界区域会因零填充出现衰减,如果你对边界精度要求高,可以先用padarray按'replicate'扩张几个像素,算完再把边界裁掉。下面给出一个用法示例:

% 读取或生成灰度图 I = double(rgb2gray(imread('cameraman.tif'))); % 此处仅示例 D = cf_gauss_image(I, 0.6, 1.2); imagesc(D); colormap(gray); axis image; colorbar;

不过我建议测试时先用合成的阶梯块图像,这样边界效应和算法特性更容易定位。

3.3 频域实现和空间域实现怎么选

我个人的分工是:长序列一维信号优先频域法,因为它天然复用FFT速度;二维大图、需要精细控制边界时优先空间域小核法,因为边界不连续效应更容易处理。两者在内部区域的计算结果一致性非常高,差异主要体现在边界附近,这在第五节会专门给出量化说明。

4. 在图像边缘检测与信号去噪中的应用测试,以及参数怎么选

4.1 一维信号:σ相当于是频带选择器

用一个合成信号来说明σ的作用。设采样率1000Hz,信号包含5Hz、40Hz、80Hz三个正弦分量,幅值都是1,同时叠加标准差为0.2的白噪声。取α=0.7,(M(\alpha)=1),分别用三种σ值计算输出,根据频域闭式公式可以算出各频率分量的理论增益:

输入频率σ=0.001sσ=0.005sσ=0.01sσ=0.02s
5Hz≈104≈103≈100≈86
40Hz≈837≈380≈36≈0.003
80Hz≈1675≈71≈0.006≈0

注意σ=0.001s时,5Hz分量会被放大约104倍,80Hz分量放大约1675倍,这个结果非常贴近普通一阶导数;而σ=0.02s时80Hz分量基本被完全抑制,40Hz也几乎消失,只有5Hz附近还能通过。这说明σ本质上就是一个频带选择旋钮:它控制的是微分器对高频的“恐惧程度”。白噪声是宽带信号,σ越大,噪声被压得越狠,代价是真正的高频细节也会被削平。实际处理脉搏信号、振动信号这类窄带信号时,我一般先做一次功率谱估计,把关心的频段中心频率找出来,再反推σ的取值。

4.2 二维边缘检测:和Sobel比出差别

图像上我做了一个模拟实验:构造一张包含阶梯边缘、高斯亮斑和均匀背景的合成图,再叠加标准差为10(8bit灰度图)的高斯白噪声。分别用Sobel算子和本文的CF高斯算子(α=0.6,σ=1.2像素)检测边缘,视觉效果差异很明显。

Sobel的输出在无噪声区域边缘锐利,但噪声区域会产生大量孤立响应,阈值调低则噪声全进来,调高则弱边缘丢失。CF高斯算子的输出则要“干净”得多,因为高斯核的低通效应把孤立噪点的微分响应压低了。我的体会是:它更像一个“带抗噪属性的梯度”,适合在预处理阶段不想引入太多滤波器串联时的场景。

如果要更精确定位边缘位置,可以把α往1方向调,比如α=0.85,这时算子的微分特性更强,边缘响应更集中;如果主要目标是抑制噪声、提取大尺度结构,α往0.3附近调更好。σ的物理意义就是边缘检测的尺度,σ越大检测到的边缘越“胖”,定位精度下降,但对噪声的鲁棒性提升。

4.3 我做实验总结出的参数选择经验

这里直接分享我踩过之后的选参流程:

先定σ,再定α。图像上σ以像素为单位,通常取0.8到3。σ偏小时算子接近普通一阶梯度,抗噪能力弱;σ偏大时边缘过度平滑。一维信号里σ要用物理时间单位,可以从信号的采样频率和关注的截止频率估算。

α决定算子的“分数阶属性”。α接近0时,整个算子退化成强低通,输出幅度很小;α接近1时接近普通一阶导数。常用的有效区间是0.3到0.8,建议从0.6起步,然后看输出幅度的分布再调整。

关于(M(\alpha))的取值,我用默认为1就足够了。若使用(M(\alpha)=\frac{2}{2-\alpha}),在α=0.7时会引入约1.54倍的均匀增益,这只是等比放大,不改变相对频带特性。除非你要和某个论文的数值做严格对比,否则不必纠结这个常数。

5. 数值稳定性、边界效应与几个我没绕开的坑

5.1 直流增益归一化:看起来小,做错全盘错

二维算子里的高斯核必须归一化,这一点一开始我吃过亏。用未归一化的核,图像平坦区域本应输出接近0,实际却出现明显的分块亮度偏移,就是因为卷积核直流增益不等于1导致的泄漏。归一化方法是h = h / sum(h(:)),一维同理k = k / sum(k)。另外一维频域实现里,omega(1)=0对应的直流分量会被deriv_op置零,输出自然零均值,这是正确的。

5.2 高斯核截断的误差量级

理论上高斯核支撑是无限的,但实际只用有限窗。按6σ截断时,尾部漏掉的总权重约为(2\times \mathrm{erfc}(3/\sqrt{2})\approx 0.27%)。对8bit图像来说,这个误差引起的灰度偏移不到1个灰度级;但对浮点科学计算,如果你需要高精度结果,建议把截断半径提高到ceil(8*sigma),误差会降到极低水平。

5.3 边界效应:频域不等于真相

频域实现默认信号是周期延拓的,对真实非周期信号而言,信号两端的不连续会被高斯核“抹”出过渡响应。处理长序列时,我先对信号做去均值和边缘羽化(用smoothstep窗把首尾各3*sigma渐变到零),处理完再把羽化区裁掉。这个操作简单但极其有效。图像处理里则用'replicate'填充边界比零填充平滑得多。

5.4 α等于1附近的数值爆炸问题

公式里分母是1-alpha,α一旦接近1,增益就极速膨胀。比如α=0.999时增益是1000倍,浮点误差会被同步放大。如果你确实需要模拟接近整数阶的微分行为,建议直接调alpha=1走普通导数路径,不要通过CF算子的极限去逼近。这也是我在实际测试中比出来的结论。

另外提醒一个容易忽略的点:中心差分本身对孤立噪声点敏感。如果图像噪声很严重,可以先把差分核从[-0.5,0,0.5]换成[-0.25,0,0.25]配合一次轻量高斯预平滑,或者直接用Sobel核替代中心差分。这相当于把“求导前预处理的职责”显式放在算子外层,虽然形式简单,但效果立竿见影。

我个人的体会是,高斯核和CF分数阶导数的组合,真正的价值不只是多一个数学工具,而是把分数阶微分从“需要解数值积分的大计算量问题”变成了“一个局部线性算子、一个频域乘积、几行Matlab代码”。从推导闭式表达式到写成算子,整个链路走通之后,你会发现参数调整变得非常直观:一个旋钮控频带,一个旋钮控平滑度。后续如果想往更深走,可以把这套算子做成多尺度版本,在一组σ上并行计算然后融合响应,也可以引入GPU阵列做实时视频处理,方向都很清晰。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询