搭建DICOM医学影像系统(OHIF+Orthanc+Nginx)
本文描述如下解决方案:
- 搭建dicom影像系统
- 编写dicom服务器的java接口
- 更换orthanc的数据库,方便大量图像的应用
- 把图片包装成dicom文件
后续要进一步了解的问题:
- dicom文件归档
- ohif解读
- orhanc与其他dicom服务的比较
搭建dicom影像系统

(以上是官方的图)
我们就按图索骥,搭建服务
根据指南:Get Started | OHIF
一步步搭建OHIF服务:
有一点要修改:我不修改这个地方,加载图片好像有卡等现象?但也不是很肯定
maximumFileSizeToCacheInBytes: 50 * 1024 * 1024
位置如图:

下载Orthanc,运行服务,测试:

http://localhost:8042/app/explorer.html
右上角有上传文件的按钮,上传相关文件。下面2个服务有时间都需要了解一下:
- DCM4CHEE
- Orthanc
文件的例子? 按这个网址去找:dicom文件例子
nginx配置:
server{ listen 8800; location /dicom/studies { proxy_pass http://127.0.0.1:8042/dicom-web/studies; proxy_set_header HOST $host; proxy_set_header X-Real-IP $remote_addr; rewrite /orthanc(.*) $1 break; add_header 'Access-Control-Allow-Credentials''true'; add_header 'Access-Control-Allow-Headers''DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; add_header 'Access-Control-Allow-Methods''GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Origin''*'; } location /wado { proxy_pass http://localhost:8042/wado; proxy_set_header HOST $host; proxy_set_header X-Real-IP $remote_addr; rewrite /orthanc(.*) $1 break; add_header 'Access-Control-Allow-Credentials''true'; add_header 'Access-Control-Allow-Headers''DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; add_header 'Access-Control-Allow-Methods''GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Origin''*'; } }
启动OHIF服务:dev:orthanc

完毕!

总结:2个关键点:
一个是nginx配置:
一个是设置maximumFileSizeToCacheInBytes
接下来需要解决四个问题:
1 我们从设备上抓取的可能是图片,要把图片包装成dicom文件
2 另外 dicom文件上传Orthanc
OHIF本身提供一个生成器把图片包装成dicom(需要研究)
dicom文件上传Orthanc
3、项目当中集成这套服务体系
4、更换Orthanc的数据库服务器,应对大数据量的挑战
编写dicom服务器的java接口
Orthanc文档中,用curl执行相关命令。
test:
C:\Users\xj>curl http://localhost:8042/patients/c9b0ff25-29a5faeb-269fa5e7-a3e9c99f-794ed755{"ID" : "c9b0ff25-29a5faeb-269fa5e7-a3e9c99f-794ed755","IsStable" : true,"LastUpdate" : "20221214T080756","MainDicomTags" : {"PatientBirthDate" : "19990115","PatientID" : "P00004787","PatientName" : "LiuXinLu","PatientSex" : "F" },"Studies" : ["175a50e8-e7e128c6-baa0df3e-7b38034f-372f3170" ],"Type" : "Patient"}
测试上传dicom:
D:\temp>curl -X POST http://localhost:8042/instances --data-binary @2-32_1_00000C98.IMG{"ID" : "7a2bd226-d679ea16-06f25ba2-e5dbcbcd-a4d6b6e8","ParentPatient" : "c9b0ff25-29a5faeb-269fa5e7-a3e9c99f-794ed755","ParentSeries" : "4bed12be-64764849-5985f66d-d73f9629-4a8beac2","ParentStudy" : "175a50e8-e7e128c6-baa0df3e-7b38034f-372f3170","Path" : "/instances/7a2bd226-d679ea16-06f25ba2-e5dbcbcd-a4d6b6e8","Status" : "Success"}D:\temp>curl -X POST http://localhost:8042/instances --data-binary @2-33_1_00000C9E.IMG{"ID" : "b97a3465-b4ba453d-5b558db1-9f50afe1-43cc38fe","ParentPatient" : "c9b0ff25-29a5faeb-269fa5e7-a3e9c99f-794ed755","ParentSeries" : "4bed12be-64764849-5985f66d-d73f9629-4a8beac2","ParentStudy" : "175a50e8-e7e128c6-baa0df3e-7b38034f-372f3170","Path" : "/instances/b97a3465-b4ba453d-5b558db1-9f50afe1-43cc38fe","Status" : "Success"}
绿色部分即为相应的内容。从响应内容可以看出:
parentPatient(parentSeries)、parentSeries、path(id) 三部分组成,这和DICOM模型是对应的。
用java代码实现:代码上传到了github上:
orthancAPIForJava: java 写的 操作orthanc代码
目前,实现了orthanc文档上restful API功能:
- postDcm
- getPatientInfos
- getStudies
- getSeries
- getInstances
- getPatient
- getStudy
- getSeries
- getInstance
- getSimpleTag
- getTag
- getDicomField
- getAllTag
- downInstance
- downInstancePng
- getInfoFromOrthanc
- getJsonFromOrthanc
- getValueFromOrthanc
- downInstanceFromOrthanc
- delete
根据标签查询的时候,要传标签编码:具体编码见:ps:DICOM的常用Tag分类和说明
Orthanc can send its DICOM instances to remote DICOM modalities (C-Store SCU).这个暂时没有实现,我们不存在影像归档一类的需求,需要的时候再实现它。
使用REST执行查Query/Retrieve 和 Find这一部分也暂时没有实现
使用PostgreSQL数据库
- 安装 PostgreSQL,创建对应的数据库,我这里创建了orthanc_db数据库。
- 修改配置文件
- 重启服务
文档上说:
The Orthanc project provides two official plugins to replace the default storage area (on the filesystem) and the default SQLite index by a PostgreSQL database.
我们安装的是64位orthanc,所有的插件似乎已经自带,不用另外安装配套的插件
当然你必须创建PostgreSQL数据库,我创建的数据库如下图:

我只是更改了相关配置文件:

最后重启服务即可!
按文档的描述,要说明插件位置,我没有说明好像也行:

另外,配置文件 lock属性,用于多个实例共享一个数据库的情况,我们用不着,就不管它了。
需要注意的是:

一段时间不用,可能数据库连接报错!
解决办法是修改postgresql.conf 数据库端相应三个设置。

ps:TCP KEEPALIVE FOR A BETTER POSTGRESQL EXPERIENCE【译】
PostgreSQL如何控制客户端连接超时
Java 如何把图片JPG转成Dicom文件
ps:对数据库表的理解:DICOM医学图像处理:深入剖析Orthanc的SQLite,了解WADO & RESTful API
Welcome to the Orthanc Book! — Orthanc Book documentation