news 2026/9/19 11:58:55

OHIF Viewer 数据源(Data Source)完全指南:从 Naturalized DICOM JSON 到自定义数据源实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OHIF Viewer 数据源(Data Source)完全指南:从 Naturalized DICOM JSON 到自定义数据源实现

OHIF Viewer 数据源(Data Source)完全指南:从 Naturalized DICOM JSON 到自定义数据源实现

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

导读

本文围绕 OHIF Viewer 的 Data Source 机制展开,从 OHIF 内部统一使用的 naturalized DICOM JSON 元数据格式讲起,系统梳理内置的dicomwebdicomjsondicomwebproxymerge等常用数据源及其配置方式,并深入讲解如何基于IWebApiDataSource与 Data Source Module 编写自定义数据源,将任何私有后端(甚至非 DICOM 数据)映射到 OHIF 原生格式。读完本文,你将掌握数据源模块的注册方式、DICOMweb 服务的本地搭建与配置参数、以及通过 ExtensionManager 动态添加/更新数据源的实际能力。

OHIF 的数据基石:Naturalized DICOM JSON

OHIF 内部元数据的数据结构遵循naturalized DICOM JSON格式,这是一种由dcmjs项目开创的表示法。其核心思路是:将传统 DICOM 元数据头中的Tag(如(0020,000D))替换为 DICOM Keyword(如StudyInstanceUID,并将 Sequences 以数组形式组织,从而获得易于开发、代码语义清晰的 JSON 结构。

相比原始 DICOM 的十六进制 Tag 与嵌套元素,naturalized 格式带来两点直接收益:

  • 可读性:开发者在代码中直接书写StudyInstanceUIDSeriesInstanceUIDModality等人类可读字段,无需查阅 DICOM 标准字典翻译 Tag;
  • 可扩展性:JSON 天然适合前后端交换与序列化,也为自定义数据源的映射提供了统一目标格式。

在仓库中,这一格式贯穿全链路:dcmjsDicomMetaDictionary.naturalizeDataset/denaturalizeDataset被 DicomWebDataSource/index.ts 直接引用,用于将服务端返回的 DICOM 数据在 naturalized 与 denaturalized 两种形态间转换;而platform/core/src/classes中的 MetadataProvider 与services/DicomMetadataStore则负责承载这些 naturalized 元数据,供 DisplaySet 构建、挂片协议(Hanging Protocol)与视口渲染消费。

OHIF 提供的内置数据源总览

OHIF 已经为最常见的几种数据接入场景提供了开箱即用的数据源实现,官方文档(introduction.md)中明确列出的包括:

数据源名称标识适用场景
DICOMwebdicomweb对接遵循 DICOMweb 标准的 PACS / 影像归档(QIDO-RS / WADO-RS / STOW-RS)
DICOM JSONdicomjson通过一个指向 JSON 文件的 URL 直接启动查看器,JSON 内含研究/序列/实例元数据与 DICOM 文件地址
DICOMweb Proxydicomwebproxy通过一个返回 DICOMweb 配置的 JSON URL,动态构造数据源并代理后续请求
Static DICOMweb基于dicomweb+staticWado服务由static-wado预先生成的静态 DICOMweb 文件,追求极致加载性能
Mergemerge在 series 级别合并多个数据源的结果

其中dicomwebdicomjson由 default 扩展在getDataSourcesModule中注册,源码形态如下(getDataSourcesModule.js):

import { createDicomWebApi } from './DicomWebDataSource/index'; import { createDicomJSONApi } from './DicomJSONDataSource/index'; function getDataSourcesModule() { return [ { name: 'dicomweb', type: 'webApi', createDataSource: createDicomWebApi, }, { name: 'dicomjson', type: 'jsonApi', createDataSource: createDicomJSONApi, }, ]; }

从这段代码可以看到 Data Source Module 的标准注册契约:每个数据源包含name(唯一标识)、typewebApi/local/other等)与createDataSource(工厂函数,接收dataSourceConfig并返回数据源实例)。

编写自定义数据源:基于 IWebApiDataSource

如果你的数据源是自定义的、或持有非标准格式的数据,完全可以自行编写一个数据源,把数据映射到 OHIF 原生格式。数据甚至不需要是 DICOM,只要你能将私有数据映射到正确格式即可。官方文档明确给出自定义数据源的标准写法(data-source.md):

const getDataSourcesModule = () => [ { name: 'exampleDataSource', type: 'webApi', // 'webApi' | 'local' | 'other' createDataSource: dataSourceConfig => { return IWebApiDataSource.create(/* */); }, }, ];

这里的IWebApiDataSource.create来自@ohif/core,是一个工厂函数,用于创建"通过 HTTP 拉取数据"的 Web API 数据源。其接口定义位于 platform/core/src/DataSources/IWebApiDataSource.js,核心入参如下:

function create({ initialize, query, retrieve, store, reject, parseRouteParams, deleteStudyMetadataPromise, getImageIdsForDisplaySet, getImageIdsForInstance, }) { /* */ }

值得注意的设计点是:一个数据源实现可以为"读"和"写"分别定义不同的底层来源,并且该工厂会为缺失的方法注入默认实现(例如默认的store.dicom会抛出 "not implemented" 错误,默认getConfig返回{ dicomUploadEnabled: false })。

必须实现的核心 API 端点

参考dicomweb数据源实现(DicomWebDataSource/index.ts),自定义数据源需要重点实现以下端点:

端点作用说明
initialize数据源初始化mode.tsx中数据源首次创建时调用,用于设置配置。例如dicomweb借此从 URL 中提取StudyInstanceUID并设为活动研究;dicomjson则用浏览器 URL 拉取数据并存入缓存
query.studies.search研究查询左侧研究面板用于拉取同一 MRN 的既往研究(All标签页),Worklist 中用于列出服务端全部研究
query.series.search序列查询在 Worklist 展开某个研究时,拉取该研究的序列信息
retrieve.bulkDataURI大数据块检索用于在视口中渲染 RTSTRUCT(放疗结构集)。它是一个包含enabled属性及数据源特定选项的对象
retrieve.series.metadata序列元数据检索最关键端点,用于拉取序列级元数据,支撑挂片 DisplaySet 的构建与创建
store.dicom数据回存仅当需要回存功能时实现,用于把数据写入后端;不需要可跳过

对应到源码:qido.js实现了mapParamssearch(QIDO 查询)与processResultsretrieveStudyMetadata.js实现了retrieveStudyMetadatadeleteStudyMetadataPromiseretrieveBulkData.ts实现了 bulk data 检索;dcm4cheeReject.js实现 reject(仅 DCM4CHEE 等支持 reject 的服务)。

Static WADO 客户端

当数据源配置中设置了staticWado: true时,OHIF 会假定研究查询返回的是研究的超集(静态列表),并使用 StaticWadoClient 在客户端手动执行搜索:它解释查询参数并应用到已返回的响应上。该特性对某些"可查询但不支持按特定字段查询"的 DICOMweb 后端非常有用,但前提是研究列表规模不能太大,否则客户端侧筛选开销过高。

DicomMetadataStore:数据源与元数据的汇合点

OHIF-v3 将研究元数据集中存放在DicomMetadataStore(位于platform/core/src/services/DicomMetadataStore)中,它是存储与获取 Study / Series / Instance 三级元数据的中央位置。你的自定义数据源可以通过DicomMetadataStore写入或读取元数据,与视图渲染层解耦。该 Store 还提供了addInstancesaddSeriesaddStudy及订阅变更等 API,配合 IWebApiDataSource.js 顶部的注释可以看到,OHIF 有意将DicomMetadataStore设计为数据源注入元数据的统一入口,未来可进一步解除数据源对@ohif/core的硬依赖。

在模块之外添加 / 更新数据源

除在扩展模块中静态注册外,数据源还可以在运行时通过ExtensionManager动态管理。

使用 addDataSource 添加

ExtensionManager.addDataSource允许在模块之外添加数据源。下面的示例(data-source.md)为 Google Cloud Healthcare API 添加一个新的 DICOMweb 数据源并将其设为活动数据源:

extensionManager.addDataSource({ namespace: '@ohif/extension-default.dataSourcesModule.dicomweb', sourceName: 'google', configuration: { friendlyName: 'dcmjs DICOMWeb Server', name: 'GCP', wadoUriRoot: 'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb', qidoRoot: 'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb', wadoRoot: 'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb', qidoSupportsIncludeField: true, imageRendering: 'wadors', thumbnailRendering: 'wadors', enableStudyLazyLoad: true, supportsFuzzyMatching: true, supportsWildcard: false, dicomUploadEnabled: true, omitQuotationForMultipartRequest: true, }, {activate:true} });

使用 updateDataSourceConfiguration 更新

ExtensionManager.updateDataSourceConfiguration则用于更新已有数据源的配置。下面的示例(data-source.md)把名为dicomweb的数据源更新为指向 Google Cloud Healthcare:

extensionManager.updateDataSourceConfiguration( "dicomweb", { name: 'GCP', wadoUriRoot: 'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb', qidoRoot: 'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb', wadoRoot: 'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb', qidoSupportsIncludeField: true, imageRendering: 'wadors', thumbnailRendering: 'wadors', enableStudyLazyLoad: true, supportsFuzzyMatching: true, supportsWildcard: false, dicomUploadEnabled: true, omitQuotationForMultipartRequest: true, }, );

addDataSource中的sourceName与配置对象的name字段共同标识数据源实例,是后续updateDataSourceConfiguration等操作引用的句柄。

Merge 数据源

内置的merge数据源用于合并多个数据源的结果,目前仅支持在 series 级别合并:来自数据源 A 和数据源 B 的序列会被归入同一个研究下;若同一序列在两个数据源中都存在,则先到达者生效,其余冲突序列被忽略。这在"衍生数据存储在不同服务器"的场景中尤为实用——例如从一个数据源检索标注(annotation)序列、从另一个数据源检索图像数据。

配置示例(data-source.md):

window.config = { ... dataSources: [ { sourceName: 'merge', namespace: '@ohif/extension-default.dataSourcesModule.merge', configuration: { name: 'merge', friendlyName: 'Merge dicomweb-1 and dicomweb-2 data at the series level', seriesMerge: { dataSourceNames: ['dicomweb-1', 'dicomweb-2'], defaultDataSourceName: 'dicomweb-1' }, }, }, { sourceName: 'dicomweb-1', ... }, { sourceName: 'dicomweb-2', ... }, ], };

其中defaultDataSourceName定义了"出问题时回退到哪台服务器"。

DICOMweb 数据源:本地服务搭建与配置

在所有数据源中,遵循 [DICOMweb] 规范的数据源最容易配置。官方教程(dicom-web.md)给出的三步法为:① 选择并安装一个影像归档(Image Archive);② 上传数据(例如用 DCMTK 的 storescu 或归档的 Web 界面);③ 保持服务运行。

本地 DICOM 服务器选型

常用的开源 DICOM 影像归档如下:

归档安装方式
DCM4CHEE Archive 5.xDocker
OrthancDocker
DICOMcloud(仅 DICOMweb)源码运行
OsiriX(仅 macOS)桌面客户端
Horos(仅 macOS)桌面客户端

下面重点介绍 Orthanc 与 DCM4CHEE 两种。

运行 Orthanc

前提是已安装 Docker(可先运行docker --version确认;若使用 Docker Toolbox,需要把platform/app/package.json中的PROXY_DOMAIN改为http://192.168.99.100:8042或 docker-machine ip 输出值,这是 Webpack 代理请求所用的地址)。

启动并上传数据:

# 启动 Orthanc(窗口保持打开期间持续运行) yarn run orthanc:up

上传首个研究:在浏览器打开 Orthanc Web 界面http://localhost:8042/ui/app/index.html#/,左侧即上传按钮,可直接拖放 DICOM 文件。该命令运行的docker-compose.yml位于platform/app/.recipes/Nginx-Orthanc

随后配置 Web 应用连接 Orthanc——在仓库根目录新开终端:

# 若尚未开启 yarn workspaces yarn config set workspaces-experimental true # 恢复依赖 yarn install --frozen-lockfile # 使用本地 orthanc 配置启动开发模式 yarn run dev:orthanc

yarn run dev:orthanc实际执行的是platform/apppackage.json中的脚本:

cross-env NODE_ENV=development PROXY_TARGET=/dicom-web PROXY_DOMAIN=http://localhost:8042 APP_CONFIG=config/docker-nginx-orthanc.js webpack-dev-server --config .webpack/webpack.pwa.js -w

其中:

  • PROXY_TARGET=/dicom-webPROXY_DOMAIN=http://localhost:8042告诉开发服务器把请求代理到 Orthanc,从而绕开跨域(CORS)问题
  • APP_CONFIG=config/docker-nginx-orthanc.js指定加载到window.config的配置文件。

DICOMweb 数据源配置详解

默认配置位于platform/app/public/config/default.js,其dataSources结构如下(dicom-web.md):

window.config = { routerBasename: null, extensions: [], modes: [], showStudyList: true, dataSources: [ { namespace: '@ohif/extension-default.dataSourcesModule.dicomweb', sourceName: 'dicomweb', configuration: { friendlyName: 'dcmjs DICOMWeb Server', name: 'DCM4CHEE', wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado', qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs', wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs', qidoSupportsIncludeField: true, supportsReject: true, imageRendering: 'wadors', thumbnailRendering: 'wadors', enableStudyLazyLoad: true, supportsFuzzyMatching: true, supportsWildcard: true, }, }, ], defaultDataSourceName: 'dicomweb', };

这些配置项在源码类型定义中均有对应(DicomWebDataSource/index.ts):

配置项类型/默认说明
qidoRoot/wadoRootstringQIDO-RS 与 WADO-RS 的 Base URL
stowRootstringSTOW-RS 地址,缺省回退到wadoRoot
wadoUristringWADO-URI 地址
qidoSupportsIncludeFieldbooleanQIDO 是否支持includefield请求额外字段
imageRendering/thumbnailRenderingwadors图像/缩略图渲染方式
supportsRejectboolean服务端是否支持 reject 调用(如 DCM4CHEE)
singlepartboolean | string以单部分(single part)响应的 payload 类型,逗号分隔,可选pdfvideobulkdatathumbnailimage
supportsFuzzyMatchingboolean是否支持模糊匹配
supportsWildcardboolean是否支持通配符
supportsNativeDICOMModelboolean是否支持原生 DICOM 模型
enableStudyLazyLoadboolean是否启用研究懒加载
dicomUploadEnabledboolean是否允许上传 DICOM 到该数据源(true时 Worklist 页面显示上传入口)
omitQuotationForMultipartRequestbooleanmultipart 请求是否省略引号
staticWadoboolean是否启用 Static WADO 客户端
bulkDataURI 配置

bulkDataURI决定数据源如何利用 bulkdata 端点检索那些"最初未包含在服务端响应中"的元数据,适合体量大、应单独请求获取的元数据。当 bulkdata URI 是相对路径而非绝对路径时,用relativeResolution指定相对解析基准,可取studiesseries。默认值(未配置时自动补全):

bulkDataURI: { enabled: true, relativeResolution: 'series', },

其余可选属性(DicomWebDataSource/index.ts):

  • transform:接收字符串并返回更新后的字符串,用于替换路径片段;
  • startsWith/prefixWith:先移除标准前缀、再添加可选前缀,主要用于反向代理或 URL 命名变更
  • relativeResolution:针对错误的 bulkdata 路径,将其解析为 studies 级。
各 payload 的单部分(singlepart)差异

对于 DICOM 视频与 PDF:实测发现Orthanc 以 multipart 交付,而 DCM4CHEE 以 single part 交付。因此需要查阅你所用数据源的 DICOM 一致性声明(conformance statement)来确定其 payload 交付方式,再决定singlepart是否包含pdfvideo

启用 DICOM 上传

除了dicomUploadEnabled: true,还需要在配置中加入上传组件定制(dicom-web.md):

customizationService: { dicomUploadComponent: '@ohif/extension-cornerstone.customizationModule.cornerstoneDicomUploadComponent', },

运行 DCM4CHEE

dcm4che 是一套用 Java 实现 DICOM 标准的开源医疗保健企业应用集合;dcm4chee(多一个 e)是其中的 Image Manager / Image Archive 项目,提供存储、检索等能力。其完整安装步骤见官方 Wiki("Run minimum set of archive services on a single host"),不在本文教程范围内。官方文档以视频形式给出了使用本地 DCM4CHEE 运行 OHIF Viewer 的步骤概览。

DICOM JSON 数据源:用 JSON 文件直接启动查看器

你可以通过一个指向 JSON 文件的 URL 直接启动 OHIF Viewer,该 JSON 包含 DICOMweb 服务器地址以及研究/序列/实例 UID 列表与元数据。示例:

https://viewer.ohif.org/viewer/dicomjson?url=https://ohif-dicom-json-example.s3.amazonaws.com/LIDC-IDRI-0001.json

url查询参数指向 JSON 文件的位置(上面示例文件由 OHIF 团队生成并存放于 S3,仅用于演示)。

JSON 文件结构

JSON 启动文件按study 级 → series 级 → instance 级三层组织元数据。以下基于 LIDC-IDRI-0001 案例(dicom-json.md):

{ "studies": [ { "StudyInstanceUID": "1.3.6.1.4.1.14519.5.2.1.6279.6001.298806137288633453246975630178", "StudyDate": "20000101", "StudyTime": "", "PatientName": "", "PatientID": "LIDC-IDRI-0001", "AccessionNumber": "", "PatientAge": "", "PatientSex": "", "series": [ { "SeriesInstanceUID": "1.3.6.1.4.1.14519.5.2.1.6279.6001.179049373636438705059720603192", "SeriesNumber": 3000566, "Modality": "CT", "SliceThickness": 2.5, "instances": [ { "metadata": { "Columns": 512, "Rows": 512, "InstanceNumber": 1, "SOPClassUID": "1.2.840.10008.5.1.4.1.1.2", "PhotometricInterpretation": "MONOCHROME2", "BitsAllocated": 16, "BitsStored": 16, "PixelRepresentation": 1, "SamplesPerPixel": 1, "PixelSpacing": [0.703125, 0.703125], "HighBit": 15, "ImageOrientationPatient": [1, 0, 0, 0, 1, 0], "ImagePositionPatient": [-166, -171.699997, -10], "FrameOfReferenceUID": "1.3.6.1.4.1.14519.5.2.1.6279.6001.229925374658226729607867499499", "ImageType": ["ORIGINAL", "PRIMARY", "AXIAL"], "Modality": "CT", "SOPInstanceUID": "1.3.6.1.4.1.14519.5.2.1.6279.6001.262721256650280657946440242654", "SeriesInstanceUID": "1.3.6.1.4.1.14519.5.2.1.6279.6001.179049373636438705059720603192", "StudyInstanceUID": "1.3.6.1.4.1.14519.5.2.1.6279.6001.298806137288633453246975630178", "WindowCenter": -600, "WindowWidth": 1600, "SeriesDate": "20000101" }, "url": "dicomweb:https://ohif-dicom-json-example.s3.amazonaws.com/LIDC-IDRI-0001/01-01-2000-30178/3000566.000000-03192/1-001.dcm" } ], "NumInstances": 133, "Modalities": "CT" } ] } ] }

关键点:instance 级同时存储metadataurl——前者是 naturalized DICOM JSON 元数据,后者是 DICOM 文件在服务器上的dicomweb:前缀地址。这个 JSON 正是 OHIF naturalized 格式的最佳写照:全部使用 Keyword 命名、Sequences 为数组。

用脚本生成 JSON 文件

仓库提供了从托管端点生成 JSON 文件的脚本(.scripts/dicom-json-generator.js):

node .scripts/dicom-json-generator.js '/path/to/study/folder' 'url/to/dicom/server/folder' 'json/output/file.json'

某些模态需要额外元数据才能正常渲染。关于 OHIF Viewer 正常工作所需的最低元数据清单,见 FAQ 技术说明;生成脚本会自动补齐这些字段,例如为 SR(结构化报告)添加 CodeSequence,以便查看器正确显示测量结果。

本地 Demo

将 JSON 文件与 DICOM 文件目录放入public文件夹后,文件由本地服务器提供,于是 JSON 的 URL 为http://localhost:3000/LIDC-IDRI-0001.json,DICOM 文件为dicomweb:http://localhost:3000/LIDC-IDRI-0001/01-01-2000-30178/3000566.000000-03192/1-001.dcm。随后:

yarn install yarn dev

在浏览器打开http://localhost:3000/viewer/dicomjson?url=http://localhost:3000/LIDC-IDRI-0001.json即可看到查看器。

两个实操注意点:

  • URL 编码url参数本身若含查询参数,必须整体 URL 编码。例如http://localhost:3000/viewer/dicomjson?url=http://localhost:3000/LIDC-IDRI-0001.json?key0=val0&key1=val1应写成...?key0=val0%26key1=val1&编码为%26);
  • 托管 404 兜底:部分托管商不会把 404 自动回退到index.html(例如 Netlify 支持、Azure 不支持),这会导致带具体路径的 URL 访问时出现 404。本地同样如此——http-server不处理该问题,而serve包(npx serve ./dist -c ../public/serve.json)可以解决。

DICOMweb Proxy 数据源:动态构造 DICOMweb

你可以用一个返回 JSON 文件的 URL 启动 OHIF Viewer,该 JSON 内含 DICOMweb 配置。DICOMweb Proxy 会据此构造一个 DICOMweb 数据源,并把后续的元数据与图像请求全部代理给它。用法与 DICOM JSON 类似:

https://viewer.ohif.org/viewer/dicomwebproxy?url=https://ohif-dicom-json-example.s3.amazonaws.com/dicomweb.json

URL 返回的 JSON 需包含servers对象,其中dicomWeb是配置数组(dicom-web-proxy.md):

{ "servers": { "dicomWeb": [ { "name": "DCM4CHEE", "wadoUriRoot": "https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado", "qidoRoot": "https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs", "wadoRoot": "https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs", "qidoSupportsIncludeField": true, "supportsReject": true, "imageRendering": "wadors", "thumbnailRendering": "wadors", "enableStudyLazyLoad": true, "supportsFuzzyMatching": true, "supportsWildcard": true } ] } }

Proxy 只使用dicomWeb配置数组的第一项来构造数据源,因此配置结构需严格遵循上述形态。

Static DICOMweb:为极致性能生成静态文件

对于追求极致加载性能的部署,可以使用static-wado项目把 DICOM 文件预处理并压缩成静态 DICOMweb 文件,将服务时间压缩到"磁盘读取 + HTTP 流写出"的最低限度。它包含两个组件:

  • static-wado-creator:把原始 DICOM 文件转换为符合 DICOMweb 的目录结构;
  • static-wado-webserver:专门服务上述静态文件的最小 Web 服务器。

安装与生成

git clone https://github.com/RadicalImaging/Static-DICOMWeb cd Static-DICOMWeb yarn install

把 DICOM 文件整理到一个目录(如/Users/alireza/dicom/test-static-script/ACRIN-CT),然后转换:

node packages/static-wado-creator/bin/mkdicomweb.js '/Users/alireza/dicom/test-static-script/ACRIN-CT' -o '/Users/alireza/dicom/test-static-script/output'

其中前一个路径替换为你的 DICOM 目录,-o后替换为期望的输出目录。

服务静态文件

node packages/static-wado-webserver/bin/dicomwebserver.mjs -p 3001 -o /Users/alireza/dicom/test-static-script/output

-p 3001指定监听端口,-o指定生成的 DICOMweb 目录。

让 OHIF 使用静态数据

以开发模式启动,使用预置的local_static.js配置:

yarn dev:static

该配置指向qidoRoot: 'http://localhost:3001/dicomweb'wadoRoot: 'http://localhost:3001/dicomweb',与static-wado-webserver默认端口 3001 匹配。若更改了服务器的端口或输出目录,必须同步更新local_static.js中的qidoRoot/wadoRoot,否则 OHIF Viewer 无法访问数据。

数据源配置 UI:让数据源可"可视化配置"

OHIF 为数据源提供了一套通用配置机制,尤其适合拥有多个共享层级路径结构的数据源的组织。典型场景:一个组织在 Google Cloud Healthcare 下有多个 DICOM 存储,各自按 project → location → dataset → dicomStore 组织。通过在一个 OHIF 扩展中实现BaseDataSourceConfigurationAPIBaseDataSourceConfigurationAPIItem两个接口(类型定义见platform/core/src/types/DataSourceConfigurationAPI.ts),数据源即可经由通用 UI 完成配置。

BaseDataSourceConfigurationAPIItem 接口

每个(路径)条目对应一个该接口的实例,至少暴露两个属性:

属性说明
id唯一标识条目的字符串
name人类可读的名称

条目在路径层级中的位置信息不在接口内,但可在任何具体实现类中补充。例如 Google Cloud Healthcare 的实现GoogleCloudDataSourceConfigurationAPIItem(GoogleCloudDataSourceConfigurationAPI.ts)就额外增加了itemType(projects / locations / datasets / dicomStores)与url

BaseDataSourceConfigurationAPI 接口

该接口的实现是整个配置过程的核心,提供若干方法,基于通过setCurrentItem设置的各类BaseDataSourceConfigurationAPIItem逐步构建数据源路径。构造函数应接受配置数据源所需的一切参数,其中必须包含数据源名称字符串;由于ExtensionManager本身拥有配置/更新数据源的 API,它通常也是构造函数参数之一。

方法职责
getItemLabels返回各可配置项的 i18n 标签(查找键)。如 Google 实现返回['Project', 'Location', 'Data set', 'DICOM store']。系统还会基于每个标签派生四类翻译串:No {itemLabel} available(无可用项)、Select {itemLabel}(引导选择)、Error fetching {itemLabel} list(拉取出错,通常伴随错误信息)、Search {itemLabel} list(列表过滤占位符)
initialize初始化云服务 API,并返回可用于开始配置数据源的顶层子项。如 Google 实现会先请求当前登录账号的顶层 projects 列表
setCurrentItem设置传入的当前路径项,并返回其可继续选择的子项。当设置到数据源路径的最后一个可配置项时,返回空列表并把活动数据源配置为所选路径。如 Google 实现中,设置 dataset 时查询并返回其下全部 DICOM store;设置 dicomStore 时则更新关联的 OHIF 数据源指向该存储
getConfiguredItems获取当前已配置的条目列表,其长度必须等于getItemLabels的结果长度,且按索引与标签一一对应

通过 Customization Module 创建

通用 UI(DataSourceConfigurationComponent)借助 OHIF UI 定制服务实例化BaseDataSourceConfigurationAPI。UI 可配置的数据源需要在 OHIF 配置文件的configuration中提供configurationAPI字段,其值即提供工厂方法的定制模块 id:

dataSources: [ { namespace: '@ohif/extension-default.dataSourcesModule.dicomweb', sourceName: 'google-dicomweb', configuration: { name: 'GCP', wadoUriRoot: 'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/...', ... configurationAPI: 'ohif.dataSourceConfigurationAPI.google', ... }, }, ]

'ohif.dataSourceConfigurationAPI.google'定制模块由 default 扩展的getCustomizationModule提供。注意其工厂方法名必须为factory,且只接收一个参数——数据源名称,构造函数则按需传入具体配置 API 类所需的一切:

export default function getCustomizationModule({ servicesManager, extensionManager, }) { return [ { name: 'default', value: [ { // 用于创建 Google Cloud Healthcare BaseDataSourceConfigurationAPI 实例的工厂 id: 'ohif.dataSourceConfigurationAPI.google', factory: (dataSourceName: string) => new GoogleCloudDataSourceConfigurationAPI( dataSourceName, servicesManager, extensionManager ), }, ], }, ]; }

总结:如何选择你的数据源

综合本文内容,可以按以下思路选型:

  • 标准 DICOMweb 后端(PACS、云影像平台)→ 使用dicomweb,在 配置指南 中维护dataSources数组;
  • 只有静态 JSON 元数据 + 散落 DICOM 文件→ 使用dicomjson,URL 直启查看器;
  • 动态获取 DICOMweb 配置→ 使用dicomwebproxy
  • 衍生数据分布在多台服务器→ 使用merge在 series 级合并;
  • 追求加载性能→ 使用static-wado预生成静态文件并配staticWado
  • 私有后端 / 非 DICOM 数据→ 基于IWebApiDataSource.create实现自定义数据源,实现initializequeryretrievestore等端点,并通过DicomMetadataStore汇入元数据;需要可视化配置时再实现BaseDataSourceConfigurationAPI接入通用配置 UI。

无论选择哪种方式,所有数据最终都会被映射为 naturalized DICOM JSON 并汇入DicomMetadataStore——这正是 OHIF 数据源机制"一处统一、处处复用"的设计精髓。

【免费下载链接】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/9/19 11:57:56

51单片机交流调压系统:过零检测+PID闭环稳压设计

简介:本资源是一份面向机电一体化、电力电子及自动化专业本科生的毕业设计文档,聚焦单片机控制的单相交流可调稳压电源系统开发,解决传统晶闸管相控电源功率因数低、波形畸变严重、动态响应慢等工程痛点。文档完整覆盖设计全流程:…

作者头像 李华
网站建设 2026/9/19 11:57:26

8051单片机AES-128裸机实现:ECB模式与GF(2⁸)优化

简介:本资源是一份面向C语言初学者与密码学入门学习者的AES对称加密算法实现详解文档,聚焦于AES-128标准的完整C语言工程级实现原理与代码剖析。文档深入讲解密钥扩展、10轮加密流程、GF(2⁸)有限域运算、S-Box/逆S-Box生成逻辑(含仿射变换与…

作者头像 李华
网站建设 2026/9/19 11:56:47

go-toml v2 深度实战:Grafana Tempo 中 TOML 解析库的完整使用指南

go-toml v2 深度实战:Grafana Tempo 中 TOML 解析库的完整使用指南 【免费下载链接】tempo Grafana Tempo is a high volume, minimal dependency distributed tracing backend. 项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo go-toml v2 是 …

作者头像 李华