news 2026/10/19 1:26:07

如何使用 OHIF Viewer 工具栏?测量、窗宽窗位与一键导出完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何使用 OHIF Viewer 工具栏?测量、窗宽窗位与一键导出完整指南

如何使用 OHIF Viewer 工具栏?测量、窗宽窗位与一键导出完整指南

【免费下载链接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages项目地址: https://gitcode.com/GitHub_Trending/vi/Viewers

拿到一叠 CT 切片,想做的第一件事往往不是放大,而是量个尺寸——病灶到底是 2 厘米还是 5 厘米。OHIF Viewer 的工具栏(toolbar)就是为这类高频小动作准备的:量尺寸、调窗宽窗位、换视口布局、截图留档,全都摆在屏幕顶部一步可达。下面先带你把每个动作走一遍最短路径,再拆开代码看看每个按钮究竟是怎么被定义、又何时才会点亮的。

先跑通:3 分钟装好并打开 OHIF

仓库 clone 下来执行几条命令即可(要求 Node 18+):

git clone https://gitcode.com/GitHub_Trending/vi/Viewers cd Viewers pnpm install pnpm start

服务起来后打开浏览器,连上一个 DICOMweb 影像源,进入 Basic 模式。顶栏即工具栏:左侧是测量工具组,中间依次是缩放、平移、窗宽窗位、截图、布局按钮,右侧是 More Tools 菜单入口。

📐 三步量出病灶大小

操作本身非常直接:

  1. 点击工具栏里的Length图标(默认激活的测量工具);
  2. 在图像上点下两个端点,两点间的 mm 数值立刻标出;
  3. 想换量具?点工具旁的小箭头(caret)展开下拉列表,在默认排布的九件测量工具中任选一件:
工具干什么用结果单位
Length两点线性距离mm
Bidirectional最长径 LD × 最长垂直径 LPDmm
Annotation带自由文本的定性标记—
Ellipse椭圆面积 + 平均 CT 值mm² / HU
Rectangle矩形面积 + 平均 CT 值mm² / HU
Circle圆形面积mm²
Freehand ROI自由手绘轮廓取面积mm²
Spline ROI样条绘制轮廓取面积mm²
Livewire沿组织边缘吸附勾画mm²

另有Calibration按钮专门修正 DICOM 的 Pixel Spacing(相邻像素间的物理距离)。元数据里这个值缺失或错了,所有长度类测量都会跟着偏——在已知尺寸的参照物上画一条线、输入真实长度,后续测量就都以它为基准了。

往实现里看一层:这九件量具点击时走的都是同一个setToolActiveToolbar命令,它会把"激活该工具"的事件同时广播给default、mpr、SRToolGroup、volume3d四个工具组(定义见 toolbarButtonsCustomization.ts)。所以无论当前是 2D 堆栈、MPR 重建还是 SR 报告视口,选完工具立刻生效,无需逐类视口配置。

拖一拖窗宽窗位,或直接用预设对齐

图像偏暗、发白、层次糊成一团时,用 Window/Level 工具:

  1. 点Window/Level按钮进入自由调整模式;
  2. 在视口上按住拖拽——横向拖动改窗宽、纵向改窗位,对比度实时变化;
  3. 不想手调的话,点 caret 展开预设列表,肺窗、纵隔窗这类常见成像场景的标准化 W/L 设置点一下即套。

代码里这条线其实不止一条:主栏的WindowLevel是按钮形态,视口左下角挂着windowLevelMenu,底部中间的 AdvancedRenderingControls 区里还有内嵌式windowLevelMenuEmbedded和带手动滑杆的voiManualControlMenu。位置与形态不同,改的都是同一组渲染参数。

平移、缩放、3D 旋转:图像导航三件套

  • Zoom:选中后在图上按住拖拽即缩放,当前放大倍数实时显示在视口角上;
  • Pan:拖拽平移图像位置,看偏了的病灶不用翻片;
  • 3D Rotate:在容积视口上把三维重建体随手旋转到位。

三者与测量工具走的是同一条命令通道setToolActiveToolbar,只是激活的工具名不同——这也是 OHIF 工具栏"按钮皆数据"的直观体现。

一键换布局:1x1 到 3x4 网格任选

点Layout按钮,画面切换为网格选择器,点选想要的行数列数即可,1x1、2x2、3x3 都能覆盖。定义端只有两行参数:Layout按钮声明为ohif.layoutSelector类型,rows: 3, columns: 4划定了可选网格的上限。

📸 一键导出当前视口:文件名、尺寸、格式可配

留档时点工具栏右侧的相机图标,弹出下载配置弹窗,三个参数都能定:

参数说明
filename下载后的文件名
width / height输出图像的尺寸
filetypepng、jpg 等常用格式

确认后,当前视口就以高清图片落到本地。按钮背后绑的是showDownloadViewportModal命令,职责只是打开弹窗;它的可用状态求值同时排除了video与wholeSlide两类视口——视频帧和全切片 WSI 不做静态截图,所以这两种视图下按钮保持置灰。

进阶:More Tools 里藏着的工具箱

主栏那几个按钮不够用时,More Tools 就是备料区。从菜单里选中的工具会成为当前激活工具,直到被其他选择替换:

工具效果绑定命令自动置灰的视口
Reset View位置、缩放、窗宽窗位一键还原resetViewport—
Rotate Right顺时针旋转 90°rotateViewportCWvideo
Flip Horizontal水平翻转flipViewportHorizontalvideo、volume3d
Image Slice Sync多视口切片位置联动toggleSynchronizer(imageSlice)video、volume3d
Stack Scroll所有图像视口同步翻页setToolActiveToolbar—
Invert灰度反转invertViewportvideo
Cine逐帧电影式播放toggleCinevolume3d
Magnify点击放大局部细节setToolActiveToolbarvideo
Angle测量可调节角度setToolActiveToolbar—
Cobb Angle测量 Cobb 角setToolActiveToolbar—
Probe拖拽读取像素值setToolActiveToolbar—
Calibration覆盖像素间距setToolActiveToolbarvideo

注意"自动置灰"那一列:置灰不是坏了,而是代码在替你把关。这套机制的核心在 ToolbarService——每个按钮的evaluate字段存的是求值器名字,服务从注册表里按名取出检查函数执行;evaluate写成数组时则串联全部检查,任一报 disabled 即整体禁用。正因如此,同一个按钮定义才能安全地活在 2D 堆栈、MPR、3D 容积、视频、WSI 五种视口之上,而不必为每种视图各写一套逻辑。

换个角度看代码:按钮是数据对象,工具栏是分区清单

读到这儿,可以把工具栏翻个面看——界面上其实没有写死任何一个按钮。

按钮即数据对象。在 toolbarButtonsCustomization.ts 中,每个按钮就是一个条目:id是它的住址,uiType决定长什么样(渲染哪个组件),props.commands决定点击后做什么,props.evaluate决定何时点亮。点击发生时,ToolbarService 的recordInteraction把命令扔进命令总线执行,随后refreshToolbarState对所有按钮重跑一遍可用状态求值——你在屏幕上看到的"自动置灰",就是这一步的产物。

能力包即插槽。该文件最终只对外给出两个能力包(capability pack):cornerstone.toolbarButtons(全部按钮定义)和cornerstone.toolbarSections(分区到按钮 ID 清单的映射,见 L719-L785)。Basic 模式不复制这两份清单,只在 index.tsx 里用{ $reference: 'cornerstone.toolbarButtons' }引用;进入模式时,registerModeToolbar 依次调用toolbarService.register()与updateSection()完成注册和落位。渲染端更轻:Toolbar.tsx 用useToolbarhook 拉取当前分区(默认primary)的数据,给每个按钮注入展开、锁定、点击等交互状态后直接映射成组件。

插槽设计的红利是:想给某个模式加一个按钮,不用动任何界面组件——写一个定制模块,用?customization=加载,$push一个新按钮进列表,那个模式的工具栏立刻变了。

收尾:一句口诀 + 三个定制入口

记法如下:

量尺寸,"点选即激活、拖拽即标值"; 窗宽窗位,"按钮进、拖拽调、预设齐"; 留档导出,"一个弹窗定文件名、尺寸、格式"; 定制扩展,"按钮是数据,工具栏是清单"。

三个定制入口:调按钮排布,改 toolbarSections;改某按钮的命令或可用条件,改同文件toolbarButtons列表里对应条目的props;不想动代码,则用?customization=URL 参数动态追加。更多背景可对照 官方 toolbar 文档 与 ToolbarService 源码。

【免费下载链接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages项目地址: https://gitcode.com/GitHub_Trending/vi/Viewers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 1:24:01

从缺货到替代:国产MCU选型与替换实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/19 1:24:00

新能源汽车类型识别:VOC数据集解析与YOLO训练实战

简介:面向新能源汽车品牌识别与目标检测任务,这份数据集以VOC格式组织标注信息,覆盖特斯拉、北汽新能源、宝马、比亚迪秦/宋/唐、奇瑞、福特、江淮等常见车型,适用于智慧交通、车辆检索、辅助驾驶等视觉场景。压缩包共2000个XML文…

作者头像 李华
网站建设 2026/10/19 1:23:14

嵌入式面试必备:UART、I2C、SPI串行通信协议深度解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/19 1:22:39

airllm:单卡低显存运行70B大模型的分层加载方案

1. 当显存成为瓶颈:airllm 要解决的真实问题跑过大模型推理的人大概都经历过这种绝望:手里只有一张消费级显卡,显存 8GB 或者 12GB,想加载一个 70B 参数的模型,光是权重文件就超过 140GB,连门都摸不到。传统…

作者头像 李华
网站建设 2026/10/19 1:22:01

Vue权限控制实战:路由、菜单与按钮级三层方案

简介:这份资源面向Vue前端开发者与后台管理系统搭建者,聚焦权限控制这一核心场景,讲解如何让不同角色用户仅访问被授权的功能。内容围绕两种限制方式展开:一是路由不可见,借助Vue Router的meta字段存储权限列表&#x…

作者头像 李华
网站建设 2026/10/19 1:21:53

UART、I2C、SPI三大串行协议区别与面试高频考点全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华