OHIF Viewer 技术 FAQ 实战指南:元数据要求、大体积渲染内存优化与测量/排序自定义 OHIF Viewer 技术 FAQ 实战指南元数据要求、大体积渲染内存优化与测量/排序自定义【免费下载链接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages项目地址: https://gitcode.com/GitHub_Trending/vi/ViewersOHIF Viewer 是一个零足迹zero-footprint的 DICOM 浏览器其工作列表查询、多平面重建MPR、体渲染、测量与标注等工作流在实际部署中经常会遇到缩略图不显示大体积数据内存占用过高测量无法动态注入系列排序不符合预期等实现类问题。本文基于仓库中的 Technical FAQ 文档逐条梳理这些高频问题的成因、配置与代码级解决方案并对照 OHIF 仓库源码给出可验证的实现依据帮助你在自己的部署与扩展开发中快速定位和解决问题。相关阅读如需在视口四角viewport corners添加自定义图标可参考同目录下的 add-viewport-icon.md。1. Viewer 打开但没有缩略图supportsWildcard与服务器通配符支持1.1 问题现象与根因当 DICOMWeb 应用打开后工作列表worklist一片空白、没有缩略图时原因可能有很多。Technical FAQ 重点指出了一种最常见的场景配置文件中开启了supportsWildcard: true但你的 DICOMweb 服务器并不支持通配符wildcard匹配查询。以工作列表标签页的过滤为例OHIF 会构造如下形式的查询请求图片见 filtering-worklist.pnghttps://server/dicomweb/studies?PatientName*Head*limit101offset0fuzzymatchingfalseincludefield00081030%2C00080060可以看到PatientName*Head*使用了*通配符包裹查询值。如果服务器能正确处理这种请求一切正常但如果服务器不支持这种过滤语法查询就会失败进而导致缩略图无法加载。1.2 源码层面通配符是如何产生的通配符拼接逻辑位于 DICOMWeb 数据源实现中qido.js 中的mapParams函数会根据配置决定是否为患者姓名、患者 ID、检查号、检查描述等字段添加*通配符const useWildcard params?.disableWildcard ! undefined ? !params.disableWildcard : options.supportsWildcard; const withWildcard value { return useWildcard value ? *${value}* : value; }; const parameters { PatientName: withWildcard(params.patientName), 00100020: withWildcard(params.patientId), AccessionNumber: withWildcard(params.accessionNumber), StudyDescription: withWildcard(params.studyDescription), // ... };index.ts 中定义了DicomWebConfig类型的supportsWildcard字段注释明确说明其含义为服务器是否支持通配符匹配。1.3 解决方案根据你的服务器能力二选一即可方案 A关闭 OHIF 端的通配符拼接。在配置文件如 default.js的数据源configuration中设置supportsWildcard: false。注意该选项的默认值就是false见 configurationFiles.md 中的说明只有当你确认服务器支持时才应显式开启。方案 B修改服务器代码以支持*通配符。FAQ 给出了一个伪代码示例把*转换为 SQL 的LIKE通配符%Pseudocode: For each filter in filters: if filter.value contains *: Convert * to SQL LIKE wildcard (%) Add metadataField LIKE ? to query else: Add metadataField ? to query此外若你的服务器连fuzzymatching也不支持还应注意配套的supportsFuzzyMatching配置项默认不开启模糊匹配两者常常需要一起评估。2. OHIF Viewer 正常工作所需的 DICOM 元数据清单如果你的数据源返回的元数据缺失关键字段OHIF 的显示集displaySet组织、图像渲染、MPR、分割与结构化报告等工作流都可能失败。以下清单完整来自 Technical FAQ并标注了每一项的用途建议作为对接数据源时的核对表。2.1 必备Mandatory所有模态All Modalities标签用途StudyInstanceUID、SeriesInstanceUID、SOPInstanceUID检查Study、序列Series与实例SOP Instance的唯一标识符是 OHIF 组织数据的基本单位PhotometricInterpretation描述图像的色彩空间如 MONOCHROME2、RGBRows、Columns图像的行列尺寸PixelRepresentation指示像素数据应如何被解释有符号/无符号Modality模态类型如 CT、MR 等PixelSpacing像素间距参与测量与空间换算BitsAllocated每个像素采样分配的位数SOPClassUID指定对象的 DICOM 服务类对大多数常规图像数据集缺失时可能仍能渲染但通常都应该具备渲染Rendering要正确渲染图像还需要以下标签否则应使用窗宽窗位工具手动调整RescaleIntercept、RescaleSlope用于可视化时对像素值进行重新缩放CT 值换算等。WindowCenter、WindowWidth显示用的窗位与窗宽参数。部分数据集Some DatasetsInstanceNumber用于实例排序缺失时实例可能乱序。MPR多平面重建渲染与工具ImagePositionPatient、ImageOrientationPatient图像在患者坐标系中的位置与方向是 MPR 正确重建的前提。SEG分割FrameOfReferenceUID用于处理分割图层。序列sequencesReferencedSeriesSequence、SharedFunctionalGroupsSequence、PerFrameFunctionalGroupsSequence。RTSTRUCT放疗结构集FrameOfReferenceUID用于处理分割图层。序列ROIContourSequence、StructureSetROISequence、ReferencedFrameOfReferenceSequence。US超声NumberOfFrames多帧图像的帧数。SequenceOfUltrasoundRegions用于测量。FrameTime帧间隔时间若存在。SR结构化报告编码报告内容与模板所需的各种序列ConceptNameCodeSequence、ContentSequence、ContentTemplateSequence、CurrentRequestedProcedureEvidenceSequence、CodingSchemeIdentificationSequence。PT 伴 SUV 校正正电子发射断层扫描标准化摄取值与放射性药物、单位、校正和时间相关的序列与标签RadiopharmaceuticalInformationSequence、SeriesDate、SeriesTime、CorrectedImage、Units、DecayCorrection、AcquisitionDate、AcquisitionTime、PatientWeight。PDFEncapsulatedDocument包含 PDF 文档本体。VideoNumberOfFrames视频帧数。2.2 可选Optional还有大量可选的标签可以增强查看体验但对基本功能不是必需的例如患者信息Patient Information、检查信息Study Information、序列信息Series Information、实例信息Instance Information以及帧信息Frame Information。这些标签缺失不会阻断查看但会减少界面上可展示的元数据丰富度。3. MPR 与体渲染处理大数据量useNorm16Texture与preferSizeOverAccuracy当患者影像数据量超过客户端机器内存时OHIF 提供了两个配置项来降低内存占用它们都是**应用级配置App Config**中的布尔开关。在 AppTypes.ts 中可以看到这两个字段与experimentalStudyBrowserSort、useCPURendering等一同定义experimentalStudyBrowserSort?: boolean; preferSizeOverAccuracy?: boolean; useNorm16Texture?: boolean;3.1useNorm16Texture使用 16 位纹理WebGL 官方只支持 8 位和 32 位数据类型。对大多数医学图像来说8 位不够用32 位又太浪费但 MPR 和体渲染此前必须使用 32 位数据类型导致内存消耗不理想。通过 WebGL 2.0 的EXT_texture_norm16扩展WebGL 可以支持 16 位数据类型这对大多数图像而言是理想的选择可在 WebGL 报告类工具中检查你的环境是否启用了该扩展界面示例见 webgl-report-norm16.png。在配置文件中开启该标志后MPR 与体渲染会强制使用 16 位数据类型内存占用约可减少一半。FAQ 以一个大型 PT/CT 检查为例见 large-pt-ct.jpeg未开启标志时应用显示约399 MB内存占用见 memory-profiling-regular.png本地开启标志后内存降至约249 MB见 webgl-int16.png。仓库中提供了一个专门开启该选项的示例配置 default_16bit.js其核心就是一行useNorm16Texture: true,注意使用 16 位纹理若被支持不会对渲染产生任何影响pixelData会原样呈现。对于无法用 16 位数据类型表示的数据集该标志会被忽略回退到 32 位数据类型。虽然 WebGL 已提供 16 位数据类型支持但在某些环境例如基于 Intel 的 macOS中仍存在已知问题可能引发渲染异常部署前需要在目标浏览器环境中充分验证。3.2preferSizeOverAccuracy优先体积而非精度这是另一个可在配置文件中设置的标志用于强制 MPR 和体渲染使用half_float16 位浮点数据类型。选择它而非useNorm16Texture的主要原因是它在硬件和浏览器上有更广泛的支持代价是精度低于 16 位整数纹理可能引入一些渲染伪影。half_float的精度范围如下数字越大舍入误差越大Integers between 0 and 2048 can be exactly represented (and also between −2048 and 0) Integers between 2048 and 4096 round to a multiple of 2 (even number) Integers between 4096 and 8192 round to a multiple of 4 Integers between 8192 and 16384 round to a multiple of 8 Integers between 16384 and 32768 round to a multiple of 16 Integers between 32768 and 65519 round to a multiple of 32可以看到超过 2048 的区间就会出现精度损失。开启preferSizeOverAccuracy后同一检查的内存快照见 preferSizeOverAccuracy.png。3.3 如何选择配置项内存收益精度兼容性useNorm16Texture约减少一半高16 位整数无损呈现需要EXT_texture_norm16部分环境如 Intel Mac有已知问题preferSizeOverAccuracy明显降低低half_float2048 有舍入误差硬件与浏览器支持更广两者都可作为 configurationFiles.md 所述的应用配置直接写在window.config顶层。配置方式与常规配置文件完全一致例如APP_CONFIGconfig/default_16bit.js指定 16 位配置或按npm run build前的环境变量方式切换。4. 如何动态加载测量动态注入标注在某些工作流中你需要在进入检查mode时根据外部数据例如服务器返回的测量结果以编程方式动态添加测量而不是依赖用户在界面上手动绘制。Technical FAQ 给出的推荐做法是组合使用 OHIF 的MeasurementService与 CornerstoneTools 的 Annotation API下面以Rectangle矩形测量为例完整展开。4.1 背景OHIF 的 mapped 测量与 Cornerstone 原始标注当你在 OHIF 中创建一个测量后终端里获取measurementService会看到一条测量记录但它是 OHIF 内部的mapped已映射cornerstone 测量包含geReport、source等 OHIF 内部细节这些并不需要关心。如果需要拿到原始标注数据可以调用 CornerstoneTools 的 API按uid直接获取cornerstoneTools.annotation.state.getAnnotation(ea45a45c-0731-47d4-9438-d2a53ffea4ff);注意对于Rectangle、EllipticalRoi这类工具annotation 的data中会保存一个pointsInShape属性用于存放形状内的点动态加载时同样可以移除该属性。4.2 在 mode 生命周期钩子中动态添加标注OHIF 中有很多可以添加标注的地方但官方始终推荐拥有自己的扩展与 mode以便对你的自定义 API 保持完全控制。此处以在longitudinalmode 中添加逻辑为例你也可以创建自己的扩展和 mode在onModeEnter或其他生命周期钩子中加入标注完整的生命周期钩子说明见 lifecycle.md。实际应用中你需要为每个检查加载对应的测量为了示例简洁下面先硬编码一个存放测量 JSON 的 URL该 URL 应替换为你自己的数据服务地址import * as cs3dTools from cornerstonejs/tools; onModeEnter: function ({ servicesManager, extensionManager, commandsManager }: withAppTypes) { // rest of logic const annotationResponse await fetch( your-server/rectangle-roi.json ); const annotationData await annotationResponse.json(); cs3dTools.annotation.state.addAnnotation(annotationData); },4.3 自动映射到 OHIF MeasurementService关键点在于OHIF 为 CornerstoneTools 预先配置了测量映射器位于 measurementServiceMappingsFactory.ts。当你调用cs3dTools.annotation.state.addAnnotation(annotationData)添加标注后OHIF 会自动将其映射到 OHIF 的 measurement service从而刷新后即可在图像上看到该测量。该工厂函数为各类工具Length、Bidirectional、RectangleROI、EllipticalROI、Angle、CobbAngle、ArrowAnnotate、CircleROI、SplineROI、LivewireContour、Probe、SegmentBidirectional、UltrasoundDirectional等建立了从 cornerstone 事件到MeasurementService格式的双向转换逻辑仓库中 RectangleROI.ts 即为矩形测量的具体映射实现。4.4 右侧面板不显示测量切换到非追踪测量面板刷新查看器后测量会出现在图像上但如果右侧面板仍是空的原因在于右侧面板默认使用的是追踪测量面板tracking measurement panel。此时可以把布局配置中的rightPanels: [dicomSeg.panel, tracked.measurements],改为使用默认扩展的非追踪测量面板rightPanels: [dicomSeg.panel, ohif/extension-default.panelModule.measure],修改后右侧面板即可展示该动态加载的测量。5. 按指定值对序列排序实验性 StudyBrowserSort5.1 开启实验性组件当前 OHIF 正在重新设计 study panel 与 study browser。在此期间可以通过在配置文件应用级配置中开启experimentalStudyBrowserSort: true来启用实验性的StudyBrowserSort组件{ experimentalStudyBrowserSort: true, }该配置字段同样定义在 AppTypes.ts 中experimentalStudyBrowserSort?: boolean。开启后study panel 中会出现一个排序下拉框用于按指定值对序列排序。该组件之所以标注为实验性是因为 study panel 仍在重新设计中、未来界面可能变化但排序功能本身会保留。组件内置了 3 个默认排序函数Series Number序列号、Series Image Count序列图像数、Series Date序列日期。在仓库的默认定制模块 studyBrowserCustomization.ts 中可以看到studyBrowser.sortFunctions的默认实现例如studyBrowser.sortFunctions: [ { label: i18n.t(StudyBrowser:Series Number), sortFunction: (a, b) { return a?.SeriesNumber - b?.SeriesNumber; }, }, { label: i18n.t(StudyBrowser:Series Date), sortFunction: (a, b) { const dateA new Date(formatDate(a?.SeriesDate)); const dateB new Date(formatDate(b?.SeriesDate)); return dateB.getTime() - dateA.getTime(); }, }, ],5.2 通过 customizationModule 添加自定义排序函数你可以通过 customization 模块添加自定义排序函数键名为studyBrowser.sortFunctions位于default键之下。既可以使用默认扩展中现成的 getCustomizationModule.tsx也可以在自己的扩展中创建。方式一定义在 extension 的 customizationModule 中export default function getCustomizationModule({ servicesManager, extensionManager }) { return [ { name: default, value: [ { id: studyBrowser.sortFunctions, values: [ { label: Series Number, sortFunction: (a, b) { return a?.SeriesNumber - b?.SeriesNumber; }, }, // Add more sort functions as needed ], }, ], }, ]; }方式二通过customizationService.addModeCustomizations在运行时添加customizationService.addModeCustomizations([ { id: studyBrowser.sortFunctions, values: [{ label: Series Images, sortFunction: (a, b) { return a?.numImageFrames - b?.numImageFrames; }, }], }, ]);注意studyBrowser.sortFunctions下的values是一个数组其中每个元素是一个包含label和sortFunction的对象多个排序函数可以共存。5.3 工作原理StudyBrowserSort组件会检索这些排序函数并在displaySetService 层面对全部 displaySets 进行排序。由于它作用于服务层排序结果会反映到应用的所有部分——包括 study panel 中的缩略图。你可以在组件下拉框中定义多个函数并选择使用哪一个。6. 修改 Cine 自动挂载行为autoCineModalitiesOHIF 在进入某些模态时默认会自动挂载 Cine 播放即自动循环播放多帧序列。你可以通过autoCineModalities这个 mode customization 修改该行为其值为应自动挂载 Cine 的模态数组。默认行为查看器默认对OT和US两种模态开启 Cine。这一默认值在 cornerstone 扩展的 miscCustomization.ts 中定义export default { cinePlayer: CinePlayer, autoCineModalities: [OT, US], // ... };自定义示例通过customizationService.addModeCustomizations覆盖customizationService.addModeCustomizations([ { id: autoCineModalities, modalities: [OT, US], }, ]);将modalities数组改成你需要自动挂载 Cine 的模态列表即可例如只想对超声开启可改为modalities: [US]或者按需求加入其他多帧模态。7. 延伸阅读本文内容源自 platform/docs/docs/faq/technical.md相关实现细节可继续深入以下仓库文件配置项全量说明configurationFiles.md含supportsWildcard、useNorm16Texture、experimentalStudyBrowserSort、maxNumRequests等参数与默认值配置类型定义AppTypes.tsDICOMWeb 数据源通配符实现qido.js、index.ts16 位纹理示例配置default_16bit.js测量映射工厂measurementServiceMappingsFactory.ts排序函数默认定制studyBrowserCustomization.tsCine 默认模态miscCustomization.ts生命周期钩子用于动态加载测量的onModeEnter等lifecycle.md【免费下载链接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages项目地址: https://gitcode.com/GitHub_Trending/vi/Viewers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考