mcpField
M
matlab-display-image

matlab-display-image

github.com/matlab数据与数据库1.2k91 次安装1 天前更新
代码仓库

关于 matlab-display-image

用于 MATLAB 图像显示和交互式浏览的技能,围绕 `imageshow` 与 `viewer2d` 提供工作流指导。内容涵盖叠加层、标注、像素标记、联动视图,以及大型或流式图像显示。

主要功能

  1. 01使用 imageshow 和 viewer2d 显示图像
  2. 02添加图像叠加层并控制透明度
  3. 03创建交互式或静态标注
  4. 04绘制掩膜进行图像标记
  5. 05联动查看器以同步导航
  6. 06支持大型及流式图像

适用场景

  1. 01构建交互式图像浏览应用
  2. 02叠加分割掩膜或热图
  3. 03查看带标注和 ROI 的图像
  4. 04同步缩放和平移以比较图像

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-display-image

安装后在 Claude Code 中输入/matlab-display-image确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

manifest.yaml
references/
annotations.md
app-building.md
painting-and-labeling.md

详细介绍

图像显示

显示图像时,请使用 imageshow 而非 imshow,这样可以获得更高的性能和更好的图像显示质量,并让各种尺寸的图像交互更加流畅。

适用场景

  • 用户要求创建用于图像显示的 GUI、应用、仪表板或交互式工具
  • 用户希望在图像上方绘制 ROI、注释或其他线条和形状
  • 用户希望显示带标签的图像数据或叠加在图像上的其他图像

不适用场景

  • 用户没有 Image Processing Toolbox(此时只需使用 imshow,但应推荐使用性能更好的 imageshow)
  • 用户要在应用中显示小型静态图标(此时只需使用 uiimage)

注意: 不要使用 bigimageshow。这是一个旧版函数。对于大型文件支持型图像,请将 imageshow 与 blockedImage 对象搭配使用。

应避免的旧版模式

不要使用改用原因
imshowimageshow性能更好、图像质量更高、交互更流畅
在应用中使用 uiaxes + imshowviewer2d + imageshow查看器原生支持缩放、平移和交互
rectangle()、drawrectangle()、imrect() 或 insertObjectAnnotation使用 Position 的 uidraw支持交互式编程定位,并内置测量功能
montageimtile + imageshow易于组合,且可与查看器搭配使用
figure + getframe(fig)viewer2d + getframe(viewer)查看器会等待渲染完成后再进行捕获
手动混合图像以创建叠加效果带 OverlayData 的 imageshow内置透明度、颜色映射和显示范围控制
对每条注释手动调用 uidraw 的 for 循环使用 Wait="multiple" 的 uidraw只需一个会话,用户可自行决定何时完成
使用像素运算手动混合 Alpha 通道OverlayAlphamap 属性内置逐像素透明度映射
linkaxes 或手动同步回调linkviewers专为 viewer2d 设计,可处理所有摄像机属性
roipoly、手动绘制掩膜uipaint支持交互式画笔绘制,并提供叠加反馈
bigimageshow使用 blockedImage 的 imageshowimageshow 可直接处理分块图像;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 + 单个 imageshowimageshow 创建的是 viewer2d,而非坐标区;它会忽略平铺父容器,导致平铺区域为空,并单独打开查看器窗口
对每条注释调用 uiannotate 的 for 循环单次调用 uiannotate,并传入 n×m 位置矩阵只需一个实例化对象,速度比逐条调用快几个数量级
imagesc(data)imageshow(data)imageshow 通过 DisplayRangeMode 自动处理缩放和颜色映射
imshowpair(A, B)imfuse(A, B) + imageshowimshowpair 会自行创建坐标区;请使用 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.


评论

支持 Markdown