简介:这是一个面向计算机视觉研究者和开发者的显著性检测工具箱SaliencyToolbox 2.3完整压缩包,可用于图像区域显着性分析、视觉注意建模以及智能监控、图像摘要等场景。压缩包共180个文件,以MATLAB脚本(.m)为核心算法实现,配合HTML帮助文档、可视化图片示例、GUI界面(.fig)及说明文本,整体仅1.71MB,轻量易部署。已有186人浏览学习,适合具备一定MATLAB基础的图像处理初学者参考或二次开发。资源不仅包含全局对比度、自下而上等多种经典显著性模型,还提供预处理、特征提取、后处理、可视化与评估环节的配套代码,用户可通过调整参数适配不同需求。从预览可见,内含guiSaliency界面及全套html文档,便于快速理解数据结构与调用方式,降低上手门槛,整体上是学习显著性检测原理的案例教材,也是可直接运行和扩展的实验工具。
1. 从显著性检测到SaliencyToolbox2.3:为什么这个老工具箱仍值得用
给定一张图片,人眼能够在几百毫秒内锁定最显眼的区域,这种底层的视觉注意能力在计算模型里被称为显著性检测。SaliencyToolbox2.3是视觉计算领域流传很广的MATLAB显著性检测工具箱,它基于Itti-Koch模型,把多尺度特征提取、中心-周围差、特征图归一化和跨通道合并封装成了可直接调用的函数。不少做图像检索、广告注意力评估、自动驾驶场景分析的团队仍然把它作为传统Baseline,甚至在深度学习模型里用它的显著性图作为先验输入。原因很直接:它不需要GPU、没有训练数据需求,能从一张图像直接算出可解释的显著图,并且每一层特征都可以拆开看。下面就从zip包检查开始,一直讲到参数调优、批处理和结果量化,所有步骤都是我在MATLAB里实际使用的方案。
2. 安装与配置:把SaliencyToolbox2.3跑起来的第一步
2.1 拿到zip包后先做完整性检查再解压
SaliencyToolbox2.3的发布形式通常是zip压缩包,所以第一步绕不开解压。我见过不少同事跳过完整性检查直接解压,然后被一连串“Cannot open file”或者“invalid zip archive”折腾半天。这些错误往往不是工具箱本身的问题,而是zip包没有下载完整。比如could not find EOCD就是压缩包缺少结尾目录记录,直接解压时解压工具会拒绝执行。在Linux或者macOS上用unzip -t可以快速测试:
# 测试zip完整性,不实际解压 unzip -t SaliencyToolbox2.3.zip # 如果测试输出末尾是 No errors detected,再执行解压 unzip SaliencyToolbox2.3.zip -d SaliencyToolbox2.3-t参数只测试不释放,它会逐个文件校验CRC。如果中途看到bad CRC之类的字样,说明文件损坏,这时候重新下载并确认下载后的大小是否和发布页面一致,比在解压工具里反复重试更有意义。Windows环境没有直接等价的命令行测试命令,7-Zip的“测试”按钮能够完成同样的校验。偶尔解压时会有“failed to copy ...”这类中断,先别急着换工具,优先检查目标目录是否被其他进程占用,比如MATLAB当前正在访问这个目录,或者杀毒软件把MEX文件隔离了。
解压目录我一般放在纯英文且没有空格的路径里,例如D:\Toolboxes\SaliencyToolbox2.3。这个工具箱使用genpath递归扫描子目录,中文或空格路径在部分MATLAB版本里会导致某些子文件夹被静默跳过。另外解压出来的文件夹不要放在zip包所在的同一目录,否则后续addpath时可能会把zip本身也加入搜索路径。
2.2 用addpath配置MATLAB搜索路径并验证依赖
SaliencyToolbox2.3是纯MATLAB加部分MEX的实现,核心依赖是Image Processing Toolbox。建议使用R2016a以上的MATLAB版本,太老的版本在解析类定义时兼容性不好。配置路径的常见做法是使用genpath递归添加所有子文件夹:
% 指定工具箱根目录 rootDir = 'D:\Toolboxes\SaliencyToolbox2.3'; addpath(genpath(rootDir)); % 保存路径,重启MATLAB后仍生效 savepath;这段代码的关键是genpath,它会把rootDir下面所有层次的子目录都扩充进搜索路径。但这也意味着doc、html甚至.git目录也会被加进去,如果后续出现函数名冲突,可以手动rmpath这些无关目录。savepath的作用是把当前路径配置写回pathdef.m,在MATLAB安装目录没有写权限时(常见于C:\Program Files),这行会返回错误,这时可以改为在startup.m里写addpath命令,每次启动自动加载。
验证安装是否成功的方法很简单,跑一张合成测试图:
% 生成一个简单的测试图像:红色块在灰色背景上 img = zeros(256,256,3); img(:,:,1) = 0.5; img(50:150, 50:150, 1) = 1; % 调用显著性计算主函数 s = salmap(img); imagesc(s); axis image; colorbar;这里用红色块作为输入,是为了让显著性图有一个明确的高亮区域,方便判断输出是否符合预期。salmap是工具箱的核心显著性计算函数,输入是图像矩阵,输出是显著度二维矩阵。如果代码弹出热力图窗口,说明路径和依赖都正常。常见的报错有两种:Undefined function 'salmap'代表工具箱没有被正确addpath;Invalid MEX-file则代表工具箱里的编译文件与当前MATLAB版本或操作系统不匹配,这种问题在Windows上最常见。
2.3 依赖项清单与常见安装错误对照
下面这张表是我在多台开发机上跑SaliencyToolbox2.3时用到的检查项,可以直接作为排查参考:
| 依赖或环境 | 检查方法 | 常见报错 | 处理方式 |
|---|---|---|---|
| MATLAB版本 | version | 类定义解析失败 | 使用R2016a以上 |
| Image Processing Toolbox | license('test','image_toolbox') | Undefined function or variable 'imfilter' | 安装对应工具箱 |
| MEX编译环境 | mex -setup | Invalid MEX-file | 重装匹配的编译器,或下载预编译版本 |
| 搜索路径 | which salmap | Undefined function 'salmap' | 重新执行addpath(genpath(...)) |
| zip包完整性 | unzip -t | could not find EOCD | 重新下载zip包 |
其中could not find EOCD对应的是ZIP格式的结尾目录记录缺失,说明压缩包不完整。MEX报错则是很有迷惑性的问题,因为错误信息不会告诉你是哪个函数出了问题,建议在MATLAB里执行which -all salmap来定位实际被调用的文件路径。如果该路径指向一个.mexw64文件,而你的MATLAB是linux版本,肯定是平台不匹配;这时候不要想着改扩展名,直接换用纯M文件实现,或者重新编译对应平台的MEX文件。
3. 核心计算流程:SaliencyToolbox2.3的feature map与显著图生成
3.1 Itti-Koch模型的三个计算阶段
SaliencyToolbox2.3不是一堆零散滤波器的堆积,而是按照Itti-Koch模型组织起来的确定性流程。第一个阶段是特征提取,图像被分解成亮度、颜色和方向三条通道;第二个阶段是金字塔和多尺度中心-周围差,得到不同感受野下的局部对比度;第三个阶段是特征图归一化和线性加权融合,最终输出一张与输入尺寸相同的显著图。
这三个阶段的顺序是固定的,但每阶段的内部参数可以独立调整。颜色通道在RGB空间里实现,方向通道使用Gabor滤波器,亮度通道只用灰度信息。值得注意的一点是,这个模型没有学习过程,所有权重都是人工设定的,因此它很适合当作对照基线。现在很多论文报告显著性检测效果时,仍然把Itti-Koch模型的输出作为第一行Baseline。理解这个流程还有一层实际意义:当你看到显著图结果不理想时,可以倒推出问题出在哪个阶段,而不是盲目调最终融合权重。
3.2 salmap函数与参数结构体的最小可复现示例
salmap是SaliencyToolbox2.3的主入口函数。下面是一个最小可复现示例,完整展示了从读图到显示结果的流程:
% 读取图像并转为double类型,保证后续数值一致 img = imread('peppers.png'); img = im2double(img); % 使用工具箱默认参数 params = saliencyParameters(); s = salmap(img, params); % 将原图与显著图并排显示 figure; subplot(1,2,1); imshow(img); subplot(1,2,2); imagesc(s); colormap jet; axis image; colorbar;代码里im2double把图像从0-255范围映射到0-1,这一步在显著值需要跨图像比较时非常重要。saliencyParameters函数返回一个参数结构体,salmap内部的每一个特征计算阶段都会读取这个结构体。如果你不传入params,工具箱会调用默认值,但显式传入可以在后面直接改字段。peppers.png是MATLAB自带图像,如果当前环境找不到,可以先执行which peppers.png确认,找不到就换成任意自己的图片路径。
3.3 值得调整的4个显著性参数
SaliencyToolbox2.3默认参数适合普通自然图像,但实际工程中的数据往往是UI截图、医疗影像或遥感图像,这时代码直接跑默认参数可能出现整幅图都高亮的情况。我一般会优先调整下面四个参数:
| 参数 | 影响范围 | 常见默认区间 | 调整方向 |
|---|---|---|---|
levels | 特征金字塔层数 | 2-4 | 图像尺寸大取大值 |
channelWeights | 亮度、颜色、方向权重 | 等权 | 按图像域调整 |
normalizationType | 特征图归一化算法 | 迭代归一化 | 低对比度时切换 |
subSampling | 下采样步长 | 2 | 小目标检测时降低 |
以遥感图像为例,建筑物边缘密集而颜色饱和度低,此时方向通道权重高一些会更合适。修改方式直接操作结构体:
params = saliencyParameters(); params.levels = 3; params.channelWeights = [0.3 0.3 0.4]; % 亮度、颜色、方向 s = salmap(img, params);这里channelWeights的三个分量顺序是亮度、颜色、方向,不能弄反。调权重时要记住,显著性最终值是对三通道结果的加权和,并不是说权重加倍结果就加倍,因为归一化过程已经把特征图拉到了相同动态范围。如果你只是想快速看效果,先调levels,因为金字塔层数对结果的影响比权重更直接。
3.4 灰度图与超小尺寸图像的常见误用
灰度图没有颜色通道,但Itti-Koch模型中的颜色通道仍会产生响应,只是特征值多为常数。遇到灰度输入时,我通常把颜色通道权重设为零,只保留亮度和方向,这样避免特征图被无效的噪声主导。超小尺寸图像(比如小于32x32)则会出现另一个问题:金字塔层数过多时最顶层的尺寸变成1x1,中心-周围差没有意义。此时要减少levels,或者先对图像做放大预处理。下面是针对灰度图的一个简单封装:
% 灰度图输入时调整通道权重 if size(img, 3) == 1 params.channelWeights = [0.5 0.0 0.5]; end这种判断在批处理脚本里很有用,因为一批图像里往往混合着彩色图和灰度图,统一规则会损失一部分图像的显著性线索。
4. 批处理与集成:用命令行和脚本驱动SaliencyToolbox2.3
4.1 用MATLAB脚本循环处理整个文件夹
实际项目中,显著性检测很少只跑一张图。SaliencyToolbox2.3本身没有批处理界面,常见做法是写一个MATLAB函数遍历目录。下面这个batch_saliency函数会读取输入目录中的所有jpg文件,生成显著图PNG:
function batch_saliency(inputDir, outputDir) if ~exist(outputDir, 'dir') mkdir(outputDir); end fileList = dir(fullfile(inputDir, '*.jpg')); params = saliencyParameters(); for i = 1:length(fileList) imgPath = fullfile(inputDir, fileList(i).name); img = imread(imgPath); img = im2double(img); s = salmap(img, params); [~, name, ~] = fileparts(fileList(i).name); outPath = fullfile(outputDir, [name, '_salmap.png']); imwrite(mat2gray(s), outPath); end endmat2gray的作用是把显著图矩阵线性映射到0-1,再用imwrite保存成PNG。如果后续要做定量评估,需要保留double精度的原始显著值,建议同时保存.mat。脚本本身没有处理文件扩展名大小写问题,Windows上遇到*.JPG会漏掉,所以实际使用中我会用dir(fullfile(inputDir, '*.*'))配合正则筛选。批处理耗时主要在salmap内部的高斯金字塔和下采样上,图像多时可以用parfor,但要确保并行池的每个worker都能访问工具箱路径。
4.2 用外部配置做参数化批处理
批处理脚本不能把参数写死。我一般会把可调参数放到params.json中,在脚本里用jsondecode读取:
% 读取外部配置并合并到默认参数 opts = jsondecode(fileread('params.json')); params = saliencyParameters(); fields = fieldnames(opts); for i = 1:length(fields) params.(fields{i}) = opts.(fields{i}); end这样在跑网格搜索时,只需要修改JSON文件,不需要改MATLAB代码。fieldnames的循环赋值方式可以避免为每个可选参数写if判断,但要注意jsondecode会把数字解析成double,不会自动转换类型,字符串参数需要自己处理。下面这张表是我通常定义的一个输出文件规范:
| 输出内容 | 格式 | 适用场景 |
|---|---|---|
| 原始显著图 | .mat | 统计分析和指标计算 |
| 归一化显著图 | 8位PNG | 可视化与HTML报告 |
| 缩放到真值尺寸 | 16位PNG | 与标注数据做逐像素对齐 |
| 显著点坐标列表 | CSV | 候选区域生成、UI热区 |
4.3 和Python显著性检测流水线互传数据
当主流程是Python时,不建议让MATLAB每处理一张图都通过system被调用一次,那会让启动开销淹没计算时间。更好的方式是批量把显著图输出成文件,再由Python读取。PNG是常用的交换格式,读取时要特别注意类型转换:
import imageio.v3 as iio import numpy as np s_map = iio.imread("output/face_salmap.png").astype(np.float64) / 255.0 s_map = (s_map - s_map.min()) / (s_map.max() - s_map.min())这里astype(np.float64)是关键。PNG在imageio中默认读成uint8,直接除以255会得到接近0的浮点数,并且如果不在float64下运算,s_map.min()和max()也可能因为整数溢出得到错误结果。转换成double后还要做一次线性归一化,目的是让不同输入图像的显著图分数处于同一量纲,这一步在做AUC或者NSS指标时尤其重要。
4.4 用parfor加速批处理的注意事项
如果图像数量达到上千张,可以把循环改成parfor。但SaliencyToolbox2.3内部包含类对象和MEX函数,并行池的每个线程都会独立加载工具箱代码。常见做法是在parfor之前先调用parpool,并在parpool启动后执行一遍salmank(ones(8), params)让代码进入执行缓存,否则第一个worker首次计算时会显著变慢。另外,使用parfor时不要在循环内调用figure或imshow,这会造成图形句柄跨worker传输错误。
5. 调参与结果验证:让SaliencyToolbox2.3的显著性检测结果变成可信指标
5.1 用固定随机种子消除不确定性
SaliencyToolbox2.3的大部分计算是确定性的,但某些归一化步骤中存在随机采样。对比实验开始前,在脚本顶部执行rng(2024),可以确保两次运行的结果完全一致。这一点在论文复现和A/B测试里是基本要求,否则你无法判断指标差异来自算法还是随机噪声。
5.2 使用NSS指标评估显著性排序
NSS(Normalized Scanpath Saliency)对显著图的排序质量很敏感,计算时需要先对显著图做标准化:
s = double(s); s = (s - mean(s(:))) / std(s(:)); nss = mean(s(sub2ind(size(s), y, x)));y和x是注视点坐标。NSS为正值表示预测显著区域和真实注视点有正向关系,负值则表示相反。这个指标对地图的整体动态范围不敏感,比直接计算相关系数更稳定。
5.3 用AUC-Judd避免类别不平衡陷阱
显著图评估里常用AUC,但采样点中背景像素远多于注视点像素,直接计算AUC会把分数抬高。AUC-Judd从背景中随机抽取与正样本同数量的像素,再计算ROC曲线。如果SaliencyToolbox2.3输出显著图分布过于集中,AUC-Judd和AUC-Borji的差距会变大,这时候通常需要调整归一化参数或降低中心先验的影响。
5.4 显示中间层特征图定位问题来源
最终显著图不理想时,先看中间特征。在MATLAB里通过params.verbose = true打开中间结果输出,逐通道观察亮度、颜色、方向特征图。如果某个通道的特征图全接近零,优先检查输入图像的颜色空间。灰度图像在颜色通道上没有任何有意义的信息,再调颜色通道权重也无济于事;这种情况下应该把该通道权重设为零,避免噪声被放大。
5.5 用面积比自动选择阈值
把显著性图转成候选区域时,固定阈值在不同分辨率图像上表现差异很大。建议先计算面积比:
ratio = sum(s(:) > thresh) / numel(s);然后根据业务需要自动调整thresh,让面积比稳定在某个目标区间,比如1%到3%。这样得到的候选框数量不会因为图像大小起伏而剧烈变化,也更适合接入后续目标检测或注意力预测模块。这个方法在SaliencyToolbox2.3的批处理场景中非常实用,因为它不需要额外训练分类器,只依赖显著图自身分布。
本文还有配套的精品资源,点击获取