
简介面向图像处理与计算机视觉研究者的 MATLAB 图像增强算法合集覆盖图像去雾、对比度增强、引导滤波、限制对比度自适应直方图均衡、直方图均衡等经典方法适合用于学习算法原理、效果对比与二次开发。压缩包共 69 个文件以 m 源程序为主搭配 jpg 与 bmp 测试图、gif/png 结果演示、py 辅助脚本及 txt 说明文档整体 3.89MB目录结构清晰易查找。已有 544 人浏览学习内容组织按算法模块划分适合中高级 MATLAB 用户按需查阅也可作为课程实验或毕业设计的参考。资源内含暗原色去雾、CLAHE 与 HE 对比、引导滤波增强、Retinex 亮度复原等分模块工程并附带多张真实场景测试图像可直观评估不同算法的处理效果便于快速定位所需增强方案并展开实验。1. MATLAB 图像增强算法把去雾、对比度和直方图均衡串成一条流水线很多人拿到一张灰蒙蒙的图片第一反应是往灰度图上套直方图均衡结果天空区域出现一圈圈光晕暗部噪声被彻底放大。这其实不是 MATLAB 的 histeq 函数不好用而是因为直接对整图做全局映射会把原本清晰的边缘和模糊的雾融为一体动态范围拉得越狠伪影越明显。标题列出的那组算法真正的组合套路是暗通道先验负责估计雾的厚度引导滤波负责保边细化透射率CLAHE 负责在局部块内拉对比度而直方图均衡往往只用来做最底层的对比度拉伸。这套流程里每个算法都有明确分工能在 MATLAB 里用二三十行命令串起来。适合图像处理大作业、算法预研以及想做 MATLAB 与 Python 算法对照的工程师。2. 直方图均衡与 CLAHE全局映射到局部对比度的两个层级2.1 直方图均衡的全局映射逻辑与边界在 MATLAB 中histeq(I, n) 把灰度图像的直方图重新映射为近似均匀分布n 是输出灰度级数默认 64。当图像低照度或过曝时像素集中在低端或高端累积分布函数CDF在密集区斜率大灰度级会被拉开视觉上动态范围就变宽了。代价是 CDF 平坦区域的灰度级被压缩原本层次丰富的中间调丢失细节。真正的问题出现在图像中某一大块区域占比过高时比如天空、白色墙壁。CDF 在亮区快速上升均衡后天空区域整体发白而暗部原本被压缩的噪声被拉伸成可见颗粒。这是“直方图均衡可以提升对比度”这句话的反面它只保证直方图平坦不保证感知质量。I imread(foggy.png); I_gray im2gray(I); % 将 RGB 转为灰度保留亮度信息 I_eq histeq(I_gray, 64); % 64 级输出保留主要动态范围 imshowpair(I_gray, I_eq, montage);im2gray 在 R2020b 之后可用旧版用 rgb2gray。n 参数不宜超过 256超过之后没有实际意义只会增加计算量。如果对彩色图直接做 histeq需要分别处理三个通道但这会破坏通道间的比例关系产生明显色偏不推荐。2.2 CLAHE 的局部机制tile 分块与 clipLimit 的平衡adapthisteq 是 MATLAB 内置的 CLAHE 实现。它的思路是把图像划分成矩形块默认 8 行 8 列每个块内先做直方图均衡再用双线性插值把相邻块的映射结果平滑拼接消除块与块之间的边界。clipLimit 是每个灰度级直方图高度的上限高于上限的统计量会被截断再重新分配到其他灰度级相当于限制了单次对比度拉伸的增益。这个参数的直观理解是clipLimit 越小对比度增益越温和图像越接近原始观感clipLimit 越大局部对比度越强但噪声和块状效应越明显。实际使用中0.005 到 0.05 是一个有效区间。tile 大小同样关键分块越细局部自适应性越强但计算量和噪声同步上升。参数adapthisteq 中的名称典型范围作用tile 行数/列数NumTiles[8 8] 到 [16 16]定义局部统计窗口块越小局部对比度越强对比度限制ClipLimit0.005 ~ 0.05限制直方图峰值数值越大增强越强目标分布Distributionuniform / rayleigh / exponential决定变换目标形状rayleigh 适合低照度增强对一张 512x512 的灰度图[8 8] 分块意味着每块 64x64 像素足够计算局部直方图。如果图像尺寸更大建议按比例增加 tile 数量否则局部统计窗口覆盖范围过大CLAHE 退化成全局均衡。2.3 彩色图增强的正确姿势LAB 空间亮度通道处理对彩色图像做 CLAHE 时直接对 RGB 三分量分别处理会产生色斑因为三个通道的映射关系不一致。常见做法是先转换到 LAB 色彩空间只对 L 通道做增强AB 颜色通道保持不动。LAB 空间本身把亮度和颜色分离这样增强亮度不会影响色调比例。I imread(foggy.png); I_lab rgb2lab(I); % 转换到 LAB 空间 L I_lab(:,:,1); % 提取亮度通道 L rescale(L); % 确保 L 范围在 [0,1] L_enhanced adapthisteq(L, ... NumTiles, [8 8], ... ClipLimit, 0.01, ... Distribution, uniform); I_lab(:,:,1) L_enhanced; J lab2rgb(I_lab); % 转回 RGB imshowpair(I, J, montage);rgb2lab 和 lab2rgb 需要 Image Processing Toolbox。关键点是 rescale因为 rgb2lab 返回的 L 通道虽然是 double 类型但范围不是标准 [0,1]而是 0 到 100。如果直接送入 adapthisteq部分版本会因超出范围报错或产生错误映射。处理完之后如果发现颜色偏黄多半是 ClipLimit 过大导致局部亮度拉伸幅度不一致。3. 图像去雾算法实战暗通道先验与透射率估计3.1 雾天成像退化模型的三个未知量去雾算法的基础是雾天成像退化模型I(x) J(x) t(x) A(1 - t(x))。I(x) 是观测到的雾图J(x) 是清晰无雾的图像A 是全局大气光t(x) 是透射率表示物体反射光穿透雾到达相机的比例。去雾的目标是从单张 I(x) 中解出 J(x)、A、t(x)这是一个欠定问题必须引入先验假设。暗通道先验基于一个统计规律在绝大多数户外无雾图像的任意局部区域内至少有一个颜色通道的强度非常低接近 0。雾天图像的暗通道不满足这个规律因为大气光散射会让所有通道的亮度抬升。利用这个差异可以估计 t(x) 的大小。对比度增强解决不了这个问题因为它假设 t(x) 是常数等同于把雾当作均匀亮度偏移来补偿。真实场景中 t(x) 随距离变化雾越厚的地方透射率越低远处物体亮度被大气光抬得更高。强行拉对比度只会让远处区域过曝近处区域被压暗。3.2 计算暗通道的最小值滤波与形态学腐蚀暗通道的计算分两步先对每个像素取 RGB 三通道的最小值再对整张图做最小值滤波。最小值滤波在 MATLAB 里用 imerode 实现结构元素选择矩形即可。窗口大小 win_size 是第一个要调的参数太小则无法覆盖白色物体和天空区域暗通道值偏高透射率估计过小太大则透射率图边缘被磨平去雾后物体边界出现光晕。function [dark] dark_channel(I, win_size) % I 是 double 类型 RGB 图像范围 [0,1] I_min min(I, [], 3); % 沿通道维取最小值 se strel(rectangle, [win_size win_size]); % 定义矩形结构元素 dark imerode(I_min, se); % 灰度腐蚀等价于最小值滤波 endmin(I, [], 3) 返回一个二维矩阵每个像素取 R、G、B 中的最小值。imerode 在这里做的是局部最小值替换和传统卷积不同它没有加权平均所以不会产生平滑过渡而是保留锐利边缘。win_size 在论文中建议 15但实际处理 512x512 图像时11 或 9 往往更好尤其当画面中有细长结构时。3.3 大气光估计与透射率下界得到暗通道之后取暗通道中亮度最高的前 0.1% 像素在这些位置找到原图中对应的 RGB 值取平均值作为大气光 A。这样做的依据是暗通道最高亮的区域通常对应雾最浓的区域那里的像素颜色近似于大气光。透射率的估计公式是 t(x) 1 - omega * dark(x) / A。omega 是一个在 0 到 1 之间的常数用来保留远景的轻微雾气否则去雾后的图像会显得不自然。t(x) 需要设置一个下界 t0通常取 0.1防止透射率接近 0 时恢复公式出现除零也避免天空区域被过度增强产生色块。function J dehaze(I, win_size, omega, t0) I im2double(I); dark dark_channel(I, win_size); % 定义暗通道图、按行/列快速展平 [h, w] size(dark); dark_flat dark(:); I_flat reshape(I, [], 3); % 提取大气光 num floor(h * w * 0.001); % 前 0.1% 像素数量 [~, idx] sort(dark_flat, descend); % 按暗通道值降序排序 A mean(I_flat(idx(1:num), :), 1); % 取对应像素的通道均值 A reshape(A, 1, 1, 3); % 透射率估计与恢复 t 1 - omega * dark ./ mean(A, all); % 逐像素透射率 t max(t, t0); % 限制下界 J (I - A) ./ t A; % 向量化恢复 J max(min(J, 1), 0); end方法里的几个参数需要说明sort 降序排序后取前 num 个索引这里的 0.1% 是暗通道像素占比如果图像分辨率高可以适当降低到 0.05%。omega 建议范围 0.9 到 0.98值越大去雾越彻底但也更容易出现颜色失真。t0 在 0.1 到 0.2 之间天空区域占比大时调高 t0 能抑制色彩过饱和。3.4 暗通道去雾关键参数速查表去雾效果的稳定性主要由三个参数决定实际项目中按场景调整。参数推荐值对结果的影响win_size9 ~ 15过小导致白色物体误判为雾过大削弱边缘细节omega0.9 ~ 0.98控制去雾程度数值越大远处雾被去除越多t00.1 ~ 0.2透射率下限保护天空和白色区域不过曝这段代码直接运行时透射率图 t 常常出现块状边缘因为最小值滤波的矩形窗口把纹理细节吞掉了。下一章用引导滤波把 t 细化到原图边缘上。4. 引导滤波的应用透射率细化与增强后噪声抑制4.1 引导滤波的局部线性模型与边缘保持条件引导滤波假设在一个局部窗口内输出 q 与引导图像 G 满足线性关系 q_i a_k * G_i b_k其中 a_k 和 b_k 在窗口内是常数。目标是最小化 q 与输入 p 的差异同时加入正则化项 epsilon 限制 a_k 不能过大。求解出的 a_k 使引导图像梯度较大的区域保留梯度梯度平坦的区域过渡平滑。与双边滤波相比引导滤波的优势在于边缘保持形式更稳定。双边滤波的权重依赖像素强度差当噪声幅度接近边缘梯度时噪声也会被当作边缘保留。引导滤波则依赖引导图像的结构只要引导图像清晰输出就会把边缘对齐到引导图像的边缘位置。在去雾流程里透射率 t 是逐步估计出来的它本身带有最小值滤波留下的块状伪影。用原图 I 作为引导图像对 t 做引导滤波可以让透射率的边缘锐利度与原图一致同时保持远处区域的平滑。4.2 imguidedfilter 参数选择与数据范围陷阱MATLAB 的 imguidedfilter 函数直接封装了引导滤波算法核心参数有三个NeighborhoodSize 定义窗口半径DegreeOfSmoothing 对应正则化项 epsilonMode 控制数据范围。t_refined imguidedfilter(t, I, ... NeighborhoodSize, 15, ... DegreeOfSmoothing, 0.01, ... Mode, double);这里的陷阱是数据范围一致性。如果 t 和 I 都是 double 且在 [0,1] 区间内DegreeOfSmoothing 取 0.01 就可以。但很多人会用 uint8 的 I 作为引导图input 是 double 的 t此时 imguidedfilter 内部会自动转换容易造成范围不一致。建议在调用前统一用 im2double 转换输入。参数名默认值推荐值说明NeighborhoodSize[5 5][15 15]窗口越大平滑范围越广边缘容错越大DegreeOfSmoothing0.010.01 ~ 0.1越大越平滑过小则噪声残留Modesamedouble确定输入数据范围避免缩放误差4.3 用引导滤波细化大气光透射率并抑制 CLAHE 噪声实际应用中引导滤波可以承担两个任务。第一个是细化去雾流程中的透射率把第 3 章代码里的 t 替换成 t_refined再做恢复时边缘光晕会显著减少。I im2double(imread(foggy.png)); J_dehazed dehaze(I, 15, 0.95, 0.15); % 第一次去雾 t 1 - 0.95 * dark_channel(I, 15); % 复用透射率估计 t_refined imguidedfilter(t, I, ... NeighborhoodSize, 15, ... DegreeOfSmoothing, 0.01, ... Mode, double); J (I - A) ./ max(t_refined, 0.15) A; % 用细化透射率再恢复第二个任务是对 CLAHE 增强后的图像做保边噪声抑制。CLAHE 在提升局部对比度的同时放大了传感器噪声尤其是在暗部区域。直接用高斯模糊会让边缘变软引导滤波的引导图像选择增强前的原因被滤波图像选择增强后结果可以在边缘处保持清晰在平坦区域平滑噪声。L_smooth imguidedfilter(L_enhanced, L, ... NeighborhoodSize, 15, ... DegreeOfSmoothing, 0.05, ... Mode, double);这里 L_enhanced 是经过 CLAHE 的亮度通道L 是原始亮度通道。引导滤波会把增强后的细节拉回原始边缘附近抑制那种“松散的颗粒感”。5. 图像增强的量化验证与参数排错技巧5.1 用信息熵、平均梯度判断增强强度随手动调参前先用两个指标量化增强效果。信息熵衡量灰度分布的分散程度增强后熵值上升说明动态范围被拉开。平均梯度是图像边缘强度的直观反映数值越大说明细节越清晰但过大意味着噪声也被增强。E_before entropy(im2gray(I)); E_after entropy(im2gray(J)); gr imgradient(im2gray(J)); G_after mean(gr(:), omitnan); fprintf(熵: %.3f - %.3f, 梯度: %.2f\n, E_before, E_after, G_after);entropy 函数只接受灰度图所以 J 如果是 RGB要先转灰度。平均梯度用 imgradient 计算梯度幅值omitnan 处理边缘像素。5.2 有参考图时使用 PSNR 与 SSIM 对照如果同一场景有清晰参考图psnr 和 ssim 是更可靠的指标。去雾处理后 PSNR 通常在 20 到 30 之间低于 20 说明色调或亮度整体偏离SSIM 低于 0.8 说明结构边缘有明显失真。psnr_val psnr(J, ref); ssim_val ssim(J, ref);PSNR 对亮度偏移敏感去雾后如果画面偏暗PSNR 会明显下降优先检查大气光 A 是否估计过高。SSIM 则对结构敏感如果出现光晕SSIM 会跌到 0.7 以下这时优先调整引导滤波窗口大小而非 CLAHE clipLimit。5.3 三组经过验证的参数组合按照不同场景给出可直接套用的参数组合表覆盖轻雾、浓雾、低照度三类常见输入。注意这只是出发点实际效果需要根据图像分辨率微调窗口大小。场景win_sizeomegat0clipLimit引导滤波 eps轻度雾90.90.10.010.01浓雾150.950.20.030.05低照度夜景不执行去雾--0.050.02如果同一批图像反复出现光晕优先检查引导滤波的 NeighborhoodSize 是否与图像尺寸匹配而不是提高 clipLimit 或者调低 t0。把去雾、CLAHE、引导滤波封装成三个独立函数逐一替换输入能省下大量排错时间。本文还有配套的精品资源点击获取