关于 matlab-display-image
用于 MATLAB 图像显示和交互式浏览的技能,围绕 `imageshow` 与 `viewer2d` 提供工作流指导。内容涵盖叠加层、标注、像素标记、联动视图,以及大型或流式图像显示。
主要功能
- 01使用 imageshow 和 viewer2d 显示图像
- 02添加图像叠加层并控制透明度
- 03创建交互式或静态标注
- 04绘制掩膜进行图像标记
- 05联动查看器以同步导航
- 06支持大型及流式图像
适用场景
- 01构建交互式图像浏览应用
- 02叠加分割掩膜或热图
- 03查看带标注和 ROI 的图像
- 04同步缩放和平移以比较图像
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-display-image安装后在 Claude Code 中输入/matlab-display-image确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreferences/annotations.mdapp-building.mdpainting-and-labeling.md详细介绍
图像显示
显示图像时,请使用 imageshow 而非 imshow,这样可以获得更高的性能和更好的图像显示质量,并让各种尺寸的图像交互更加流畅。
适用场景
- 用户要求创建用于图像显示的 GUI、应用、仪表板或交互式工具
- 用户希望在图像上方绘制 ROI、注释或其他线条和形状
- 用户希望显示带标签的图像数据或叠加在图像上的其他图像
不适用场景
- 用户没有 Image Processing Toolbox(此时只需使用
imshow,但应推荐使用性能更好的imageshow) - 用户要在应用中显示小型静态图标(此时只需使用
uiimage)
注意: 不要使用 bigimageshow。这是一个旧版函数。对于大型文件支持型图像,请将 imageshow 与 blockedImage 对象搭配使用。
应避免的旧版模式
| 不要使用 | 改用 | 原因 |
|---|---|---|
imshow | imageshow | 性能更好、图像质量更高、交互更流畅 |
在应用中使用 uiaxes + imshow | viewer2d + imageshow | 查看器原生支持缩放、平移和交互 |
rectangle()、drawrectangle()、imrect() 或 insertObjectAnnotation | 使用 Position 的 uidraw | 支持交互式编程定位,并内置测量功能 |
montage | imtile + imageshow | 易于组合,且可与查看器搭配使用 |
figure + getframe(fig) | viewer2d + getframe(viewer) | 查看器会等待渲染完成后再进行捕获 |
| 手动混合图像以创建叠加效果 | 带 OverlayData 的 imageshow | 内置透明度、颜色映射和显示范围控制 |
对每条注释手动调用 uidraw 的 for 循环 | 使用 Wait="multiple" 的 uidraw | 只需一个会话,用户可自行决定何时完成 |
| 使用像素运算手动混合 Alpha 通道 | OverlayAlphamap 属性 | 内置逐像素透明度映射 |
linkaxes 或手动同步回调 | linkviewers | 专为 viewer2d 设计,可处理所有摄像机属性 |
roipoly、手动绘制掩膜 | uipaint | 支持交互式画笔绘制,并提供叠加反馈 |
bigimageshow | 使用 blockedImage 的 imageshow | imageshow 可直接处理分块图像;bigimageshow 是旧版函数 |
title("text") 或 title(gca,"text") | title(viewer,"text") | gca 不会返回查看器;请直接传入查看器对象 |
使用 xlim/ylim 缩放到某个区域 | viewer.CameraViewport = [x y w h] | 查看器不是坐标区;对 viewer2d 使用 xlim/ylim 会报错 |
将 tiledlayout/nexttile/subplot 与 imageshow 搭配使用 | 在 uigridlayout 中使用多个 viewer2d,或使用 imtile + 单个 imageshow | imageshow 创建的是 viewer2d,而非坐标区;它会忽略平铺父容器,导致平铺区域为空,并单独打开查看器窗口 |
对每条注释调用 uiannotate 的 for 循环 | 单次调用 uiannotate,并传入 n×m 位置矩阵 | 只需一个实例化对象,速度比逐条调用快几个数量级 |
imagesc(data) | imageshow(data) | imageshow 通过 DisplayRangeMode 自动处理缩放和颜色映射 |
imshowpair(A, B) | imfuse(A, B) + imageshow | imshowpair 会自行创建坐标区;请使用 imfuse 合成图像,再用 imageshow 显示 |
关键组件
| 组件 | 构造函数 | 关键回调 |
|---|---|---|
| 查看器 | viewer2d(parent) | CameraMovedFcn、ObjectClickedFcn |
| 图像 | imageshow('numeric',Parent=viewer) | |
| 交互式注释 | uidraw(parent, 'text') | AnnotationMovedFcn(在查看器上) |
| 静态注释 | uiannotate(parent, 'text') | |
| 画笔标注 | uipaint(imageObj) | |
| 联动查看器 | linkviewers([v1, v2]) |
模式
标准图像显示
简单的图像显示场景可在不指定父对象的情况下调用 imageshow。所有名称-值对都可设置为输出对象的属性,并且可通过设置 Data 属性来更新图像数据。
obj = imageshow(im);
若要为查看器添加标题,请将查看器对象直接传递给 title。不要使用 title("text") 或 title(gca, "text")——gca 不会返回查看器,因此调用会静默失败或创建单独的坐标区标题。
obj = imageshow(im);
viewer = obj.Parent;
title(viewer, "My Image");
在大多数情况下,默认的 DisplayRangeMode "type-range" 就很合适。医学图像可能更适合使用 "data-range",以根据图像的动态范围进行缩放;也可根据图像数据使用 "10-bit" 或 "12-bit"。
obj = imageshow(im, DisplayRangeMode="data-range");
在另一幅图像上叠加显示掩膜、语义分割或其他图像数据时,请使用 imageshow 的 OverlayData 属性,以及相应的 OverlayColormap、OverlayAlpha、OverlayAlphamap、OverlayDisplayRange 和 OverlayDisplayRangeMode 属性来调整叠加层的显示效果。这种方式比将叠加层与图像混合后再更新 Data 属性更快。
obj = imageshow(im, OverlayData=mask);
若要进行非均匀(逐像素)透明度控制,请使用 OverlayAlphamap,而不是 OverlayAlpha。此属性会将叠加数据值映射到透明度级别。可接受 "linear"、"quadratic"、"cubic" 或自定义的 n 元素列向量。
obj = imageshow(im, OverlayData=heatmap);
obj.OverlayAlphamap = "quadratic";
如果有空间参照信息,请将其作为 "Transformation" 名称-值对传入,值可以是 Image Processing Toolbox 或 Mapping Toolbox 中的 imref2d、affintform2d 或其他变换对象。
obj = imageshow(im, Transformation=tform);
手动显示范围——当 DisplayRangeMode="manual" 时直接设置 DisplayRange,或覆盖自动范围:
% Window/level for a 16-bit medical image
obj = imageshow(ctSlice, DisplayRange=[40 400]);
自定义色图——对灰度图像或索引图像使用 Colormap 属性:
obj = imageshow(grayImage, Colormap=turbo(256));
显示多幅图像
不要将 tiledlayout、nexttile 或 subplot 与 imageshow 搭配使用。 imageshow 创建的是 viewer2d,而不是坐标区对象——它不能作为父对象放入布局平铺区域。在 nexttile 循环中调用 imageshow 会生成空白平铺区域和单独的查看器窗口。
选项 1:使用 imtile 快速合成——最适合并排查看,且不需要对每幅图像单独交互:
tiled = imtile({slice1, slice2, slice3}, GridSize=[1 3]);
imageshow(tiled);
选项 2:在 uigridlayout 中使用多个 viewer2d——最适合需要分别缩放、平移或添加注释的图像:
fig = uifigure(Name="Slice Review", Position=[100 100 1200 400]);
gl = uigridlayout(fig, [1 3]);
for i = 1:3
v = viewer2d(gl);
v.Layout.Row = 1;
v.Layout.Column = i;
imageshow(slices{i}, Parent=v, DisplayRange=[-1000 400]);
title(v, sprintf("Slice %d", i));
end
比较两幅图像时,请使用 imfuse,并将结果传递给单个 imageshow,而不是使用 imshowpair。
对于过大而无法读入内存的文件支持型图像,请创建多级 blockedImage,然后将该对象作为 Data 属性传递给 imageshow。
bim = blockedImage("tumor_091.tif");
imageshow(bim);
流式图像和视频
更新显示时,尽可能复用对象。如果需要更新图像数据,请保留 imageshow 的输出对象,并更新该图像对象上的 Data 属性。对于流式工作流,请在 imageshow 中将 PyramidSmoothing 设为 "nearest",以便更快地创建图像金字塔。
% Inline — short logic
viewer = viewer2d();
title(viewer,"Streaming Image Data");
obj = imageshow([],Parent=viewer,PyramidSmoothing="nearest");
for idx = 1:100
obj.Data = im;
drawnow;
end
生成动画
生成动画或捕获帧时,始终将 viewer2d 对象传递给 getframe——绝不要使用 getframe(fig) 或 getframe(gcf)。在 R2026a+ 中,getframe(viewer) 会等待所有待处理的渲染更新完成后再捕获,从而确保每一帧都已完整渲染,而且速度显著快于在图窗级别捕获。对图窗调用 getframe 则会立即捕获,导致帧为空白或只渲染了一部分。viewer 是 imageshow 输出的 Image 对象的父对象。
% Inline — short logic
viewer = viewer2d();
obj = imageshow([],Parent=viewer,PyramidSmoothing="nearest");
nFrames = 100;
out = cell(1, nFrames);
for idx = 1:nFrames
obj.Data = im;
out{idx} = getframe(viewer);
end
注释
交互式注释(用户绘制/编辑,批量会话支持 Wait="multiple")使用 uidraw;静态批量注释(检测、边界、边界框——数量不限)使用 uiannotate。**判断规则:**如果位置由算法确定,则使用 uiannotate;如果用户需要绘制或编辑,则使用 uidraw。始终在一次调用中将所有位置作为 n×m 矩阵传递给 uiannotate——绝不要循环调用。完整 API、形状格式和示例请参阅 references/annotations.md。
% WRONG — do NOT loop:
for i = 1:size(bboxes,1)
uiannotate(viewer, "rectangle", bboxes(i,:), Color="red");
end
% RIGHT — single call with the full matrix:
uiannotate(viewer, "rectangle", bboxes, Color="red");
响应用户交互
在查看器的回调属性上添加函数句柄,以响应用户在查看器中的交互。CameraMovedFcn 可在相机移动后触发响应。AnnotationMovedFcn 可在用户交互式移动或调整注释形状后触发响应。ObjectClickedFcn 可在用户于查看器中按下并释放鼠标、且未执行拖动操作后触发响应(单击并拖动会启动默认交互,通常是平移)。此回调可用于捕获选择或对象拾取的单击事件,用户可以查看事件数据来确定被单击的对象。
im = imread("peppers.png");
obj = imageshow(im);
viewer = obj.Parent;
% Draw a rectangle ROI interactively
roi = uidraw(obj, "rectangle", Color=[0,1,0], Label="ROI");
% Listen for movement and display the position
viewer.AnnotationMovedFcn = @(~,evt) fprintf("ROI Position: [%.1f, %.1f, %.1f, %.1f]\n", evt.Position);
交互式绘制与标注
使用 uipaint(imageObj) 进行像素级交互式标注——返回一个二值掩码。支持使用 BrushSize 和 OverlayValue 进行多类别标注。单类别和多类别示例请参阅 references/painting-and-labeling.md。
用于比较的联动查看器
并排比较多张图像(前后对比、多模态、多波段)时,使用 linkviewers 在多个 viewer2d 对象之间同步平移和缩放。用户在一个查看器中平移或缩放时,所有联动的查看器都会自动跟随。
v1 = viewer2d(parent1);
v2 = viewer2d(parent2);
imageshow(im1, Parent=v1);
imageshow(im2, Parent=v2);
linkviewers([v1, v2]);
之后取消查看器联动:
linkviewers([v1, v2], "off");
使用 CameraViewport 进行程序化缩放
若要以编程方式缩放至图像的特定区域或导航至该区域,请在查看器上设置 CameraViewport。它相当于 viewer2d 中用于坐标轴的 xlim/ylim——但在 viewer2d 上使用 xlim 和 ylim 会报错(因为它不是坐标轴)。请始终使用 CameraViewport。
CameraViewport 接受 [x y width height] 向量或 Rectangle 对象。它会缩放查看器,使指定矩形填满显示区域。读取 CameraViewport 会返回一个 Rectangle 对象,其 .Position 表示当前可见区域。
fig = uifigure;
gl = uigridlayout(fig, [1 1]);
v = viewer2d(gl);
imageshow(im, Parent=v);
drawnow; % allow camera to initialize
v.CameraViewport = [250 100 150 120];
注意:imageshow 加载数据后,查看器相机以异步方式初始化。初始化完成前设置 CameraViewport 会报错。请使用显式的 uifigure → uigridlayout → viewer2d 层级,并在设置 CameraViewport 前调用 drawnow。如果仍然报错,请在 drawnow 后添加 pause(1),等待初始化完成。
重置为完整图像:v.CameraViewport = [0.5 0.5 size(im,2) size(im,1)];。读取可见区域:vp = v.CameraViewport; disp(vp.Position);
使用 CameraMovedFcn 响应用户交互式平移或缩放:
v.CameraMovedFcn = @(~,~) disp("Visible: " + mat2str(v.CameraViewport.Position, 3));
构建应用
使用以 uigridlayout 为父级的 viewer2d(parent)——不要使用带有 imshow 的 uiaxes。先用空数据创建 Image(imageshow([], Parent=viewer)),然后在数据加载时更新 obj.Data。完整的 classdef 模板请参阅 references/app-building.md。
viewer2d 不是坐标轴——始终传递显式句柄
viewer2d 不是 MATLAB 坐标轴对象。gca 永远不会返回 viewer2d,基于坐标轴的函数(xlim、ylim、axis、subplot、tiledlayout)也无法用于查看器。始终将查看器对象显式传递给 title、getframe 以及任何操作显示内容的函数——绝不要依赖 gca 或隐式的当前坐标轴行为。
% WRONG — gca does not return the viewer:
title("Bell Peppers")
title(gca, "Bell Peppers")
% RIGHT — pass the viewer explicitly:
title(viewer, "Bell Peppers")
getframe(viewer)
约定
- 始终:使用
imageshow,不要使用imshow、imagesc或image——imageshow会自动缩放、处理所有数据类型,并创建viewer2d - 始终:将查看器句柄显式传递给
title、getframe和所有其他函数——gca不会返回查看器 - 始终:使用
getframe(viewer)而不是getframe(gcf)来捕获帧——查看器会处理异步渲染完成,并且速度明显更快 - 始终:在单次调用中将所有位置作为 n×m 矩阵传递给
uiannotate——不要针对每个标注在循环中调用uiannotate - 切勿:对查看器对象使用
gca或隐式当前坐标区模式——gca返回的是坐标区,而不是查看器 - 切勿:将
tiledlayout、nexttile或subplot与imageshow一起使用——imageshow创建的是viewer2d,而不是坐标区 - 切勿:使用
xlim/ylim缩放——改用viewer.CameraViewport = [x y w h] - 优先:显示掩膜/分割结果时使用
OverlayData,而不是手动进行 Alpha 混合 - 切勿:将
imageshow直接设为uifigure的父级——先创建viewer2d:v = viewer2d(fig); imageshow(im, Parent=v),或在不指定父级的情况下调用imageshow(im) - 优先:快速合成多幅图像时使用
imtile+ 单个imageshow;需要独立查看器时,在uigridlayout中使用多个viewer2d
版权所有 2026 The MathWorks, Inc.