图像处理里有个挺有意思的现象:很多人一提到图像增强,脑子里第一反应就是全局直方图均衡化,拉一下对比度,看着效果还行就收工了。但真正把图放大看细节,尤其是医学影像、工业检测、夜景照片这类场景,全局处理往往把该亮的地方压死、该暗的地方拉爆,局部纹理全糊成一团。局部直方图统计这条路子,就是专门解决这个问题的——它不看整张图的脸色,而是盯着每个像素周围那一小片区域做文章,用均值和方差这两个最朴素的统计量来决定这个像素到底该被拉亮还是压暗、该增强多少。这篇内容我打算把局部直方图统计增强的完整逻辑拆开讲清楚:均值管什么、方差管什么、窗口怎么选、参数怎么调、代码怎么落地、实测中哪些坑最容易踩。适合已经会用OpenCV做基础处理、想往精细化增强方向走一截的读者,也适合刚接触图像增强、想搞明白"局部"两个字到底值钱在哪的新手。
1. 为什么全局直方图那套在局部场景里会翻车
1.1 全局均衡化的隐含假设与它的失效边界
全局直方图均衡化的底层逻辑其实很干脆:统计整张图的灰度分布,把密集的灰度段拉开、稀疏的灰度段压缩,让输出直方图尽量平坦。这个操作成立的前提是——整张图的光照条件大致均匀,或者说图像内容的灰度分布可以被一个统一的变换函数合理覆盖。问题就在这,现实中的图像很少满足这个前提。一张逆光人像,天空区域灰度集中在高位、人脸区域集中在低位,全局均衡化一拉,天空过曝成白板,人脸虽然亮了一点但噪点也跟着放大。再比如工业表面检测里的金属件,高光反射区和阴影区并存,全局处理之后缺陷的微弱对比度反而被淹没。
我自己的经验是,全局均衡化在"内容单一、光照均匀"的图上确实又快又好,但只要画面里存在明显的光照梯度或者多材质区域,它的效果就会变得不可控。这不是算法本身有毛病,而是它用一个全局变换去逼近一个本质上是空间变化的增强需求,信息量不够。局部直方图统计的思路正好反过来:既然光照是空间变化的,那就让增强参数也随空间变化,每个像素根据自己的邻域统计特性单独决定变换方式。
1.2 局部统计量能捕捉到全局统计丢失的空间信息
把图像想象成一片地形,全局直方图只告诉你整片区域的海拔分布,但不会告诉你哪座山头在哪。局部窗口统计则相当于拿着一个固定大小的取景框在地形上滑动,每到一个位置就记录框内的平均海拔和起伏程度。均值反映的是这个局部区域的整体亮度水平,方差反映的是这个区域的对比度强弱——方差大说明窗口内灰度差异明显、纹理丰富,方差小说明这片区域比较平坦、接近纯色。
这两个量组合起来,就能对每个像素做出相当精细的判断:如果局部均值偏低但方差正常,说明这个像素处在暗区但周围有细节,应该适度提亮;如果局部均值正常但方差很小,说明这片区域本来就平坦,增强力度要收着点,否则把噪声当细节放大;如果局部方差很大,说明纹理密集,可以适当加大增强系数让细节更突出。这种"因地制宜"的判断能力,是全局方法给不了的。下面这张对照表能比较直观地看出两类方法的差异:
| 对比维度 | 全局直方图均衡化 | 局部直方图统计增强 |
|---|---|---|
| 统计范围 | 整幅图像 | 每个像素的邻域窗口 |
| 参数数量 | 一个全局变换函数 | 每像素一组均值/方差 |
| 光照适应 | 无法适应空间变化 | 天然适应局部光照 |
| 计算复杂度 | 低,一次遍历 | 较高,窗口滑动统计 |
| 噪声敏感度 | 中等,暗区易放大噪声 | 可控,方差约束可抑制 |
| 典型适用场景 | 内容均匀的图 | 光照不均、多材质图 |
1.3 均值与方差各自扮演的角色不能混着理解
很多人刚接触这个方法时容易把均值和方差的作用搞混,觉得两个量都是"越大越亮"之类的线性关系。实际上它们的职责分工非常明确。均值决定的是亮度基准的偏移方向——局部均值低于全局均值,说明这个像素处在相对暗的区域,增强时应该给它正向增益;反之则应该压制。方差决定的是增益的强度系数——局部方差大意味着这里有真实的结构信息值得放大,方差小则意味着放大风险高,需要衰减增益。
换句话说,均值管"往哪个方向调",方差管"调多狠"。这两个判断是正交的,缺了任何一个都会出问题。只用均值不用方差,平坦区域和纹理区域会被同等对待,噪声跟着细节一起被放大;只用方差不用均值,方向感丢失,暗区可能被进一步压暗。我在早期实现时就犯过只取均值的错误,结果平坦的天空区域被整体提亮后噪点非常明显,后来加上方差约束才压下去。
2. 局部均值与方差的窗口计算:从公式到可落地的实现
2.1 滑动窗口统计的数学定义与计算量估算
设图像为 I(x, y),窗口大小为 (2k+1) × (2k+1),以像素 (x, y) 为中心的局部均值定义为窗口内所有像素灰度的算术平均,局部方差定义为窗口内灰度与局部均值之差的平方的平均。公式本身不复杂,但直接按定义实现的计算量很吓人:假设图像尺寸 M×N,窗口边长 W,每个像素都要做 W² 次加法和若干次乘法,总复杂度是 O(M·N·W²)。一张 1024×1024 的图配 15×15 的窗口,光加法就超过两亿次,实时场景根本扛不住。
所以实际落地时几乎没人用暴力滑窗,标准做法是借助积分图(也叫求和面积表)把窗口求和降到 O(1)。积分图的核心思想是预先算一张与原图同尺寸的表,表里每个位置存的是原图从左上角到该位置的矩形区域灰度总和,这样任意矩形区域的求和都可以用四个角的值做加减得到,与窗口大小无关。均值就是窗口和除以窗口面积,一步除法搞定。
2.2 用积分图把均值计算压到常数时间
积分图的构建只需要一次遍历,递推关系是当前值等于上方值加左方值减左上值再加原图当前像素。构建完之后,窗口内求和就是右下角减左下角减右上角加左上角,四个查表加三次加减。这个技巧在局部统计里是标配,不用的实现基本没法在实际项目里跑。下面给出均值积分图的构建与查询代码,用 Python 加 NumPy 实现,注意边界处理我用的是边缘复制填充,避免窗口越界时统计失真:
import numpy as np def integral_image(img): # img: 单通道 float32, 形状 (H, W) ii = np.zeros((img.shape[0] + 1, img.shape[1] + 1), dtype=np.float64) ii[1:, 1:] = img.cumsum(axis=0).cumsum(axis=1) return ii def window_sum(ii, y, x, k): # 以 (y, x) 为中心、半径 k 的窗口求和,边界自动裁剪 H, W = ii.shape[0] - 1, ii.shape[1] - 1 y0, y1 = max(0, y - k), min(H, y + k + 1) x0, x1 = max(0, x - k), min(W, x + k + 1) return ii[y1, x1] - ii[y0, x1] - ii[y1, x0] + ii[y0, x0]这里有个细节值得说:积分图用 float64 存储是有意为之。图像尺寸稍大时,累加和很容易超出 float32 的精度范围,导致大图上的窗口求和出现肉眼可见的偏差,进而让方差计算出负数——开根号直接报错。我踩过这个坑,一张 4000×3000 的图用 float32 积分图,方差出现 -0.003 这种值,排查了半天才发现是精度问题。
2.3 方差计算的数值稳定性处理
方差有两种算法:一种是先求均值再遍历窗口算平方差(两遍扫描),另一种是用 E[X²] - E[X]² 的展开式(一遍扫描)。后者在积分图框架下更自然,因为平方图的积分图可以预先构建,窗口内平方和也是 O(1) 查询。但展开式有个经典问题:当均值远大于标准差时,两个大数相减会产生严重的有效数字丢失,甚至出现负方差。
处理办法有几个层次。最直接的是把平方和与和都用 float64 算,大部分情况下够用;再稳一点的做法是对展开式结果做截断,负值一律置零;更讲究的做法是先减去一个全局偏移量再算方差,减小数值量级。我在实际项目里通常采用"float64 积分图 + 负值截断"的组合,实测在 8 位灰度图上没再出过问题。下面是方差积分图的完整实现:
def local_mean_var(img, k): img = img.astype(np.float64) ii = integral_image(img) ii2 = integral_image(img * img) H, W = img.shape mean = np.zeros((H, W), dtype=np.float64) var = np.zeros((H, W), dtype=np.float64) for y in range(H): for x in range(W): y0, y1 = max(0, y - k), min(H, y + k + 1) x0, x1 = max(0, x - k), min(W, x + k + 1) area = (y1 - y0) * (x1 - x0) s = ii[y1, x1] - ii[y0, x1] - ii[y1, x0] + ii[y0, x0] s2 = ii2[y1, x1] - ii2[y0, x1] - ii2[y1, x0] + ii2[y0, x0] m = s / area mean[y, x] = m v = s2 / area - m * m var[y, x] = max(v, 0.0) return mean, var上面这段是教学版,逐像素 Python 循环在大图上会很慢。生产环境我会用向量化的方式把四个角的索引预先算好,或者直接用 OpenCV 的boxFilter分别对原图和平方图做均值滤波,一步到位拿到 E[X] 和 E[X²],再组合出方差。boxFilter底层是优化过的,速度比手写循环快一到两个数量级,这是实际项目里更务实的选择。
3. 增强公式的设计:均值方差怎么组合成增益
3.1 从"局部均值归一化"到"方差自适应增益"的推导思路
拿到局部均值和方差之后,怎么把它们变成对像素的修正量,这一步是整个方法的核心设计空间。最朴素的想法是局部均值归一化:把每个像素除以它的局部均值,让所有区域的亮度都往中间靠。这个做法能压掉光照不均,但会把纹理也一起抹平,因为除法是全局性的缩放,不区分内容。
更合理的思路是构造一个增益函数,让增益同时受均值和方差调制。我常用的形式是这样的:先算全局均值作为参考基准,局部均值与全局均值的比值决定基础增益方向,局部标准差与全局标准差的比值决定增益的调制强度。用公式表达就是增益 g(x,y) = 1 + α · (μ_local - μ_global) / μ_global · f(σ_local),其中 α 是全局强度系数,f 是关于局部标准差的调制函数,通常取 σ_local / (σ_local + ε) 这种饱和形式,让方差大的区域增益接近满额、方差小的区域增益趋近于零。
这个设计的好处是参数物理意义清晰:α 控制整体增强力度,ε 控制对平坦区域的抑制程度。ε 取大一点,平坦区域被压得更狠,噪声抑制更好但细节增强也弱;ε 取小一点,细节保留多但噪声风险高。实际调参时我一般从 α=0.5、ε=10 起步(8 位灰度图),然后根据图像内容微调。
3.2 一个可直接套用的增强公式与参数含义
把上面的思路整理成一个可直接落地的公式:
g(x,y) = 1 + alpha * ((mu_local - mu_global) / (mu_global + eps_mu)) * (sigma_local / (sigma_local + eps_sigma)) out(x,y) = clip(I(x,y) * g(x,y), 0, 255)这里我加了 eps_mu 防止全局均值接近零时除零,虽然 8 位图里全局均值很少接近零,但做归一化浮点图时这个保护是必要的。增益 g 被限制在一个合理区间内,比如 [0.5, 2.0],防止极端情况下把像素拉飞。这个限幅不是可选项,是必须项——我见过不加限幅的实现,遇到局部均值极小、方差极大的边缘像素时,增益能冲到十几倍,输出直接变成纯白噪点块。
参数的实际影响可以用一张表说清楚:
| 参数 | 作用 | 调大后的效果 | 调小后的效果 | 建议起始值 |
|---|---|---|---|---|
| alpha | 整体增强强度 | 对比度提升明显,噪声风险上升 | 增强温和,可能不够明显 | 0.5 |
| eps_sigma | 平坦区域抑制阈值 | 平坦区更平滑,细节也变弱 | 细节保留多,噪声易放大 | 10 |
| 窗口半径 k | 局部统计的空间尺度 | 统计更平滑,局部适应性下降 | 局部适应强,易出现块状感 | 7 |
| 增益上下限 | 防止极端增益 | 允许更强增强,风险高 | 更保守,可能欠增强 | [0.5, 2.0] |
3.3 增益限幅与边界像素的特殊处理
边界像素是局部统计方法里容易被忽略的角落。窗口滑到图像边缘时,窗口有一部分落在图外,如果直接补零,边缘像素的局部均值会被拉低、方差会被拉大,导致边缘出现一圈异常亮的增强带。我试过补零和边缘复制两种方式,补零在边缘产生的伪影非常明显,边缘复制则基本无感。所以窗口统计时一定要做边界裁剪或者边缘复制填充,这一点在代码里体现为窗口坐标的 max/min 裁剪。
另一个容易出问题的是纯黑或纯白区域。纯黑区域局部均值和方差都接近零,增益公式里的除法会变得不稳定。我的处理方式是在增益计算前加一个判断:局部方差低于某个极小阈值时,直接令增益为 1,跳过增强。这个短路逻辑既避免了数值问题,也符合直觉——本来就平坦的区域没什么可增强的。
4. 窗口尺寸与参数调优:实测出来的经验值
4.1 窗口大小对增强效果的影响规律
窗口半径 k 是这套方法里最需要凭经验拿捏的参数。k 太小,局部统计只覆盖几个像素,统计量噪声大,增强结果会出现明显的块状感和椒盐状伪影;k 太大,局部统计退化成近似全局统计,方法就失去了局部适应的意义。中间存在一个甜点区,但这个甜点区跟图像分辨率和内容尺度强相关。
我的经验规律是:窗口边长大约取图像短边的 1/20 到 1/10 之间比较稳妥。一张 1000×800 的图,短边 800,窗口边长 40 到 80,对应半径 k 在 20 到 40 之间。但这个规律只适用于内容尺度中等的自然图像。如果是显微图像里细胞结构很小,窗口要相应缩小;如果是大场景风景照,窗口可以放大。更靠谱的做法是先在小图上试几个 k 值,看增强结果的块状感和细节保留的平衡点在哪。
下面这组对比是我在一张 800×600 的低照度室内图上实测的,供参考:
| 窗口半径 k | 窗口边长 | 增强观感 | 主要问题 |
|---|---|---|---|
| 3 | 7 | 局部适应极强 | 块状感严重,噪声明显 |
| 7 | 15 | 细节突出,适应性好 | 轻微块状感,可接受 |
| 15 | 31 | 过渡自然 | 暗部细节增强偏弱 |
| 30 | 61 | 整体均衡 | 局部适应性下降,接近全局 |
| 60 | 121 | 光照校正为主 | 细节增强基本失效 |
4.2 不同内容类型下的参数组合策略
参数不能一套打天下,得看图像内容类型。我大致把常见场景分成几类,每类的参数取向不太一样。低照度自然图像,重点是提亮暗部同时压噪声,α 取中等偏大(0.6 到 0.8),ε_sigma 取大一点(15 到 20)压平坦区噪声,窗口取中等(k=10 到 15)。医学或显微图像,细节对比度是命根子,α 可以取到 0.8 到 1.0,ε_sigma 取小(5 到 8)保细节,窗口要跟结构尺度匹配,通常偏小。工业表面检测,缺陷往往是小尺度低对比度目标,α 取 0.7 左右,ε_sigma 取中等,窗口取小(k=5 到 10)保证对小缺陷的敏感度。
这里有个反直觉的点:不是所有图都适合加大 α。我处理过一批过曝的室外图,暗部其实信息量很少,加大 α 只是把噪声放大,观感反而更差。这种图正确的做法是先判断暗部是否真的有可恢复的信息(看暗部区域的局部方差是否显著大于零),没有的话增强力度要收着,甚至应该做的是压制高光而不是提亮暗部。
4.3 参数搜索的实用流程:从粗调到微调
实际项目里我不会盲目网格搜索,那样太慢也没必要。我的流程是三步走。第一步,固定 ε_sigma 和窗口,只调 α,从 0.3 到 1.0 每隔 0.1 试一遍,看整体增强力度是否合适,选一个观感最平衡的值。第二步,固定 α,调窗口半径,从 5 到 30 试几个值,重点看块状感和细节保留的平衡。第三步,微调 ε_sigma,在选定窗口下从 5 到 25 试,主要观察平坦区域(天空、墙面)的噪声表现。三步下来一般十几组参数就能收敛,比全网格搜索快得多。
调参时我习惯把原图和增强结果并排显示,同时放大到 200% 看局部细节。只看缩略图很容易被整体亮度变化骗过去,放大之后噪声和伪影才藏不住。另外建议把局部方差图也可视化出来看一眼,方差图能直观告诉你算法认为哪些区域有细节、哪些区域平坦,参数调得对不对,方差图上一目了然。
5. 完整实现与工程化落地
5.1 基于 OpenCV 的高效实现骨架
生产环境我基本不用手写积分图循环,直接用 OpenCV 的boxFilter组合出均值和方差,代码短、速度快、边界处理也省心。核心思路是对原图做均值滤波得到局部均值,对原图平方做均值滤波得到 E[X²],两者相减得到方差。boxFilter的normalize=True时输出就是均值,边界默认是反射填充,比补零合理。下面是完整骨架:
import cv2 import numpy as np def local_enhance(img, k=7, alpha=0.5, eps_sigma=10.0, gain_lo=0.5, gain_hi=2.0): img_f = img.astype(np.float32) win = (2 * k + 1, 2 * k + 1) mu_local = cv2.boxFilter(img_f, -1, win, normalize=True, borderType=cv2.BORDER_REFLECT) mu_sq = cv2.boxFilter(img_f * img_f, -1, win, normalize=True, borderType=cv2.BORDER_REFLECT) var_local = np.maximum(mu_sq - mu_local * mu_local, 0.0) sigma_local = np.sqrt(var_local) mu_global = float(img_f.mean()) base = (mu_local - mu_global) / (mu_global + 1e-6) modu = sigma_local / (sigma_local + eps_sigma) gain = 1.0 + alpha * base * modu gain = np.clip(gain, gain_lo, gain_hi) out = np.clip(img_f * gain, 0, 255).astype(np.uint8) return out这段代码在 1080p 灰度图上跑,单帧耗时在 10 毫秒量级,实时视频流完全够用。彩色图的话对每个通道独立处理再合并,或者转 YCrCb 只处理 Y 通道再转回,后者更快且色偏风险小,我一般选后者。
5.2 彩色图像处理的通道策略与色偏规避
彩色图直接对 RGB 三通道各自做局部增强,很容易出现色偏,因为三个通道的局部统计量不一致,增益不同步,原本中性的灰色区域可能被增强成偏色。规避办法有两个:一是转 YCrCb 或 HSV,只对亮度通道做增强,色度通道原样保留,这样亮度提升但色调不变;二是对三通道用同一套增益(用亮度通道算出的增益应用到三个通道),效果类似但计算稍多。
我实测下来 YCrCb 方案最省事,OpenCV 里cv2.cvtColor一转,处理完再转回,色偏基本没有。唯一要注意的是 YCrCb 的 Y 通道范围是 0 到 255,跟灰度图一致,参数不用换算。HSV 的 V 通道也是类似道理,但 HSV 转换的数值精度损失略大,我一般优先 YCrCb。
5.3 性能优化:从逐像素到向量化的提速路径
如果不用 OpenCV 而自己实现,性能优化的路径很明确:第一步把逐像素 Python 循环换成 NumPy 向量化,用预先算好的四个角索引数组做批量查表,这一步通常能提速几十倍;第二步如果还嫌慢,考虑用 Numba 的@njit装饰器把核心循环编译成机器码,提速能到百倍量级;第三步才是上 C++ 或者 CUDA,但大多数图像增强场景到第二步就够了。
向量化积分图查询的关键是把每个像素的窗口四角坐标预先算成四个二维索引数组,然后用 NumPy 的花式索引一次性取出所有窗口和。这个技巧写起来稍微绕,但跑起来非常快。我做过对比,同样一张 2000×1500 的图,逐像素循环要 8 秒左右,向量化之后 0.15 秒,差距两个数量级。如果项目里对实时性有要求,这一步优化是必须做的。
6. 实测踩坑记录:那些文档里不会写的问题
6.1 方差出现负值导致的诡异输出
前面提过方差负值的问题,这里展开说完整排查链路。现象是增强结果里出现随机分布的纯黑或纯白像素块,位置不固定,重跑一次可能换地方。第一反应是增益限幅没生效,检查代码发现限幅在的。第二步打印方差图,发现部分位置方差是负数,开根号得到 NaN,NaN 参与后续计算污染了整条链路。第三步定位负方差来源,确认是 float32 积分图在大图上的精度丢失。修复方案是把积分图和平方积分图都升到 float64,并在方差计算后加np.maximum(var, 0)兜底。修复后问题消失。
这个坑的教训是:数值稳定性在图像处理里不是理论问题,是实打实会冒出来的工程问题。凡是涉及"平方和减和的平方"这种展开式方差计算,一律用高精度类型加负值截断,别省这一步。
6.2 窗口过大导致的"光晕"伪影
另一个典型问题是增强结果在强边缘附近出现一圈亮边或暗边,看起来像光晕。根因是窗口跨越了亮度差异很大的两个区域,局部均值被拉向中间,导致边缘两侧的增益方向判断出错。窗口越大,光晕越明显。解决办法有两个:一是缩小窗口,让统计范围尽量落在同一亮度区域内;二是改用双边滤波或者引导滤波来算局部均值,这类保边滤波能在统计时给同区域像素更高权重,跨边缘的污染小很多。
我一般先用缩小窗口的办法,如果内容尺度要求窗口必须大,再上引导滤波版本的局部均值。引导滤波的计算量比 boxFilter 大,但比双边滤波小,效果和速度的平衡比较好。
6.3 平坦区域的噪声放大与抑制手段
平坦区域噪声放大是局部增强的老大难。方差调制函数虽然能抑制一部分,但 ε_sigma 调不好还是会漏。我的经验是 ε_sigma 宁大勿小,平坦区稍微平滑一点比噪声满天飞强。如果噪声实在压不住,可以在增强之后接一个轻度的非局部均值去噪或者双边滤波,但要注意别把刚增强出来的细节又抹回去。更讲究的做法是在增益计算时引入一个基于局部方差的软阈值,方差低于阈值的区域增益直接压到 1 以下,主动平滑而不是被动等噪声冒出来。
6.4 参数在不同图像间迁移失效的应对
最后一个坑是参数迁移。在一张图上调好的参数,换一张图效果可能完全不对,因为全局均值和全局标准差变了,增益公式里的归一化基准跟着变。应对办法是把参数分成"绝对参数"和"相对参数"两类:α、ε_sigma、窗口这些是绝对参数,跟图像内容无关,可以跨图复用;而增益的归一化基准应该用当前图的全局统计量动态计算,不要写死。我早期把全局均值写死成 128,结果在整体偏暗的图上增强过度、偏亮的图上增强不足,改成动态计算之后就稳了。
7. 和其他局部增强方法的横向对比
7.1 与 CLAHE 的定位差异
CLAHE(限制对比度的自适应直方图均衡化)是局部增强里名气最大的方法,它把图像分块,每块独立做直方图均衡化,再用插值消除块间不连续。局部直方图统计跟它的定位不太一样:CLAHE 本质是分块直方图变换,强项是提升整体局部对比度,但对每个像素的增强力度缺乏精细控制;局部均值方差方法则是逐像素的增益调制,控制粒度更细,参数物理意义更明确,适合需要精细调节增强力度的场景。两者不是替代关系,我有时候会先用局部统计做基础亮度校正,再叠一层轻量 CLAHE 提局部对比,效果比单用一种更均衡。
7.2 与 Retinex 类方法的思路对照
Retinex 系列方法的核心假设是图像等于光照分量乘反射分量,增强的本质是估计并去除光照影响。局部均值方差方法没有显式的光照模型,它是用统计量直接构造增益,思路上更"工程"一些。Retinex 在色彩恒常性上理论更漂亮,但实现里高斯尺度参数不好调,容易出现色彩失真;局部统计方法参数少、行为可预测,调试成本低。如果项目对色彩保真要求高,Retinex 值得试;如果追求参数可控和实现简单,局部统计更务实。
7.3 方法选型的决策依据
选型我一般看三个维度:实时性要求、参数调试成本、内容复杂度。实时性高、内容中等复杂的场景,局部统计加 boxFilter 是最稳的选择;内容复杂度高、允许离线处理的场景,可以上 Retinex 或者更重的学习方法;如果只是想要一个开箱即用的局部对比度提升,CLAHE 最省事。局部均值方差方法的独特价值在于它的参数有明确物理含义,调参时你知道自己在调什么,这在需要反复迭代的项目里非常值钱。
8. 一些延伸玩法与个人体会
局部均值方差这套统计量拿到手之后,能玩的花样其实不止增强。比如可以用局部方差图做纹理分割的预处理,方差高的区域大概率是纹理区,方差低的区域是平坦区,这个粗分割在很多任务里能当先验用。再比如可以把局部均值和方差作为特征喂给后续的分类或检测模型,比原始像素多了空间统计信息,小样本场景下有时能带来意外提升。
我个人在实际操作中的体会是,这个方法最大的价值不在于公式多精巧,而在于它把"局部适应性"这件事用最少的统计量表达出来了。均值和方差两个数,一个管方向一个管强度,配合窗口尺寸这个空间尺度参数,三个旋钮就能覆盖大部分光照不均场景的增强需求。真正花时间的从来不是写代码,而是理解你的图像内容在什么尺度上有细节、在什么尺度上该被平滑,这个判断只能靠多看多试。我建议刚上手的人先拿十几张不同类型的图跑一遍,把方差图都存下来对比着看,看多了自然就有感觉了。参数没有标准答案,但图像会告诉你答案。