热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用ApacheHadoop和ApacheSolr处理和索引医学图像

原文链接:ProcessingandIndexingMedicalImagesWithApacheHadoopandApacheSolr作者:Justi

原文链接:Processing and Indexing Medical Images With Apache Hadoop and Apache Solr
作者:Justin Kestelyn
译者:郭芮(guorui@csdn.net)

你还在为大规模图像管理感到头疼吗?读下去,看看这个团队是如何使用开源产品来更有效地索引和存储高分辨率医学图像的。

时下,医学影像迅速地成为了一种评估病人状况,以及确定是否存在医疗条件的最好非侵入性方法。多数情况下,用来协助诊断的影像是构建现代医学体系的第一步,而成像技术的进步也使我们能够收集到更详细的、分辨率更高的2D、3D、4D以及显微图像,从而帮助更快诊断和治疗某些复杂的情况。

在现实生活中,人脑的高分辨率显微扫描大小可以达到恐怖的66TB。在一些3D模式的例子中(例如计算机断层扫描),每幅图像大约4MB(2048×2048像素)。就目前的情况来看,美国所有资源库中有大约750PB的医学影像,并且预计在2016年底能达到1EB的储存量。基于这样的事实,很显然可以预感到医疗成像必将成为一个大数据问题。

目前,图像存档和通信系统(PACS)已经成为了医学影像存储和文件检索的行业标准,提供了专用的数据格式和对象。而在这篇文章中,我们分享了一个替代性的解决方案用来存储和检索医学影像文件,它利用一个Apache Hadoop集群(CDH)提供高性能和具有成本效益的分布式图像处理,其优点包括: 

  • 让医学影像数据接近其他已经在使用的数据源,例如基因组学、电子病历、药品、穿戴设备数据等等,减少数据存储和迁移成本  
  • 通过使用开源软件和行业标准服务器降低解决方案成本 
  • 允许在同一个集群内结合其他形势的数据做医学影像分析  

本文将努力重现英特尔的工作,并将此作为可以在CDH集群上利用Apache Hadoop和Apache Solr索引DICOM(Digital Imaging and Communications in Medicine)图像,并实现存储、管理和检索功能的佐证。

解决方案概述

下面就来关注一个简单但重要的示例:存储和检索DICOM图像的能力,并且这个用例不依赖于其他现有的影像库。医院和成像设施将DICOM图像的副本发送到本地与HIPPA兼容的云或托管服务器集群并存储。在需要时,医生或护理者应该能够从连接到远程集群的本地机器上查看、搜索和检索病人的DICOM图像,如图1所示。

图片描述

图1

详细说明

DICOM图像包含两个部分:文本标题和二进制图像。要确保图像是像图2和图3所示的那样可存储和可被搜索,需使用下面几个步骤。

图片描述

图2

图片描述

图3

要注意,图2是从软件开发人员的角度来分析,而图3则是终端用户和解决方案交互的角度。作为软件开发人员我们必须亲身经历这个过程,来为最终用户更好地验证功能。

1、从DICOM图像中提取元数据。
2、HDFS中存储原始的DICOM图像。
3、利用元数据生成一个索引文件(也将被存储在HDFS里面)。
4、搜索使用Hue接口来检索图像。
5、下载图片到本地系统并使用DICOM查看器打开视图。

与高性能服务器节点的成本相比,行业标准服务器在性能和存储上更具灵活性。我们的服务器节点采用双CPU结构的英特尔至强E5家族处理器,4TB×12(48TB)存储和192GB内存。在必要时处理和存储的需求可以通过横向扩展来满足——即增加集群中的节点数。

系统设置和配置

以下是我们测试6节点CDH集群和1个边缘节点的关键指标。

图片描述

图片描述

软件需求

为了测试这个解决方案,我们启用Cloudera管理器中的CDH5.4服务:

  • HDFS

    • 存储需要被索引的DICOM XML文件
    • 输出索引结果并存储
  • Apache Solr (Solrcloud模式)

    • 通过SCHEMA.XML索引给定的DICOM XML文件
  • Apache ZooKeeper

    • 在SolrCloud模式下使用ZooKeeper实现分布式索引
  • Hue(启用搜索特性)

    • 在图形界面查看Solr的索引结果,也可以搜索基于索引字段的DICOM图像
  • Cloudera搜索

    • 通过MapReduceIndexerTool做索引的离线批处理

数据集

我们的测试数据包含了从Visible Human Project下载的DICOM CT图像。

工作流

图4描述了工作流路径。

图片描述

图4

第1步:将所有的DICOM图像都存储在本地文件夹,然后使用DCM工具包(DCMTK)与dcm2xml功能从图像中提取DICOM元数据,并将其以XML格式存储。(参见附录1中的例子。)

Example: dcm2xml <input-file-path> <output-file-path>
./dcm2xml source.dcm source.xml

在上面的例子中&#xff0c;要想运行dcm2xml功能&#xff0c;必须事先在本地机器上下载好DCMTK&#xff0c;然后在.bashrc中设置如下路径。

Example: export DCMDICTPATH&#61;"/home/root/Dicom_indexing/dicom-script/dcmtk-3.6.0/s

第2步&#xff1a;将已转换的DICOM图像导入到HDFS的at/user/hadoop/input-dir和create/user/hadoop/output-dir中并存储索引结果。

第3步&#xff1a;做ETL处理。这一步建议使用Morphlines配置文件&#xff0c;然后按照要求解析和提取所需内容并同时为Solr建立可索引文件。

第4步&#xff08;参见下列过程&#xff09;&#xff1a;利用Solr中的schema.xml配置&#xff0c;从给定的XML文件字段中建立索引&#xff0c;同时还可以将MapReduceIndexerTool用于离线批处理索引。&#xff08;见附件2&#xff09;。

  • 首先&#xff0c;请确认Solr服务&#xff08;以SolrCloud模式&#xff09;在集群上成功启动并运行&#xff08;访问http://&#xff1c;your –solr-server-name&#xff1e;:8983/solr&#xff09;。

  • 然后使用solrctl生成配置文件&#xff0c;包括要索引的schema.xml字段&#xff08;使用 - ZK选项将提供ZooKeeper的主机名&#xff0c;还可以在Cloudera Manager’s ZooKeeper中发现这个信息&#xff09;。但是要注意IP地址的最后一项需要ZooKeeper端口&#xff0c;而且ZooKeeper主机IP会代替主机IP。

solrctl instancedir --zk hostip1,hostip2,hostip3:2181/solr --generate $HOME/solr_config
cd $HOME/solr_config/conf

  • 接下来需要在本地计算机中下载schema.xml文件并进行编辑&#xff0c;包括要索引的所有字段名&#xff0c;且字段名称要与XML索引文件的名称属性相匹配。这个例子中&#xff0c;DICOM XML文件仅需要索引成百上千个字段中的10-15个字段&#xff0c;同时还要记得将修改的schema.xml文件在/ conf文件夹中更新&#xff08;见附录1查看生成的DICOM XML文件&#xff0c;见附录2查看定制的schema.xml文件&#xff09;。

  • 清理所有的收藏栏和现有的ZooKeeper实例目录&#xff1a;

solrctl --zk hostip1,hostip2,hostip3:2181/solr collection --delete demo-collection >& /dev/null
solrctl --zk hostip1,hostip2,hostip3:2181/solr instancedir --delete demo-collection >& /dev/null

  • 上传Solr配置到SolrCloud。

solrctl --zk hostip1,hostip2,hostip3:2181/solr instancedir --create &#xff1c;strong&#xff1e;demo-collection&#xff1c;/strong&#xff1e;$HOME/solr_configs

  • 创建一个命名为demo-collection的Solr集合&#xff0c;-s2则表示该集合有两个碎片。

solrctl --zk hostip1,hostip2,hostip3:2181/solr collection --create demo-collection -s 2 -r 1 -m 2

  • 创建一个空白目录&#xff0c;并将MapReduceBatchIndexer结果写到里面。

hadoop fs -rm -f -skipTrash -r output-dir
hadoop fs -mkdir -p output-dir

  • ETL再次处理&#xff0c;建议使用Morphlines配置文件&#xff08;见附录3&#xff09;。

  • 利用MapReduceIndexerTool索引数据并现场演示&#xff0c;而且${DICOM_WORKINGDIR}所在的位置还可以找到log4j.properties和morphlines.conf。

${HDFS_DICOM_OUTDIR} - Location of output dir folder on hdfs (ex: /user/hadoop/output-dir)
${HDFS_DICOM_INDIR} – Location of input dir folder on hdfs (ex: /user/hadoop/input-dir/)

  • Solr会在上面所创建的输出目录中存储索引结果。

第5步&#xff1a;利用Hue查看索引结果&#xff1b;DICOM影像URL可用于本地下载以供观看。

测试

测试索引结果首先需要登录Hue界面&#xff08;假设已获得并启用了Hue的搜索功能。&#xff09;

1、点击搜索和导航>索引>演示系列>搜索。下面是索引结果的默认视图。

图片描述

2、键入一位病人的姓名或身份证号&#xff0c;也可以是其他任何已编入索引的字段数据。在这个例子中&#xff0c;下面截图显示的是一位病人的名字和其他标识。

图片描述

3、当你展开一个单一结果时&#xff0c;可以看到如下图所示的元数据字段。

图片描述

4、上面图片中的DICOM URL点击无效&#xff0c;所以要使用Hue中的图形控件创建一个良好的仪表板并添加一个可点击的URL。

图片描述

5、点击DICOM的URL &#xff0c;可以选择将.dcm文件下载到本地计算机。在该版本中我们将它下载到本地计算机中&#xff0c;并用名为MicroDicom Viewer的开源工具查看。

图片描述

6、使用MicroDicom Viewer查看图像。

图片描述

未来工作

我们计划继续开发这个参考架构&#xff0c;在此基础上利用插件提供更精简的方法&#xff0c;并力争做到允许用户直接下载浏览器内的DICOM文件。我们也将致力于更好的可视化能力研究&#xff0c;来支持多个图像同时下载。

文章贡献者&#xff1a;
KARTHIK Vadla&#xff0c;供职于Intel&#xff0c;Big Data Solutions Pathfinding Group部门软件工程师。
Abhi Basu&#xff0c;供职于Intel&#xff0c;Data Solutions Pathfinding Group部门软件架构师。
Monica Martinez-Canales&#xff0c;供职于Intel&#xff0c;Data Solutions Pathfinding Group部门首席工程师。

附录1


<file-format>
<meta-header xfer&#61;"1.2.840.10008.1.2.1" name&#61;"Little Endian Explicit">
<element tag&#61;"0002,0000" vr&#61;"UL" vm&#61;"1" len&#61;"4" name&#61;"FileMetaInformationGroupLength">216element>
<element tag&#61;"0002,0001" vr&#61;"OB" vm&#61;"1" len&#61;"2" name&#61;"FileMetaInformationVersion" binary&#61;"hidden">element>
<element tag&#61;"0002,0002" vr&#61;"UI" vm&#61;"1" len&#61;"28" name&#61;"MediaStorageSOPClassUID">1.2.840.10008.5.1.4.1.1.6.1element>
<element tag&#61;"0002,0003" vr&#61;"UI" vm&#61;"1" len&#61;"58" name&#61;"MediaStorageSOPInstanceUID">1.2.826.0.1.3680043.2.307.111.48712655111.78571.301.34207element>
<element tag&#61;"0002,0010" vr&#61;"UI" vm&#61;"1" len&#61;"22" name&#61;"TransferSyntaxUID">1.2.840.10008.1.2.4.70element>
<element tag&#61;"0002,0012" vr&#61;"UI" vm&#61;"1" len&#61;"38" name&#61;"ImplementationClassUID">1.2.826.0.1.3680043.1.2.100.5.6.2.160element>
<element tag&#61;"0002,0013" vr&#61;"SH" vm&#61;"1" len&#61;"16" name&#61;"ImplementationVersionName">DicomObjects.NETelement>
meta-header>
<data-set xfer&#61;"1.2.840.10008.1.2.4.70" name&#61;"JPEG Lossless, Non-hierarchical, 1st Order Prediction">
<element tag&#61;"0008,0008" vr&#61;"CS" vm&#61;"2" len&#61;"16" name&#61;"ImageType">ORIGINAL\PRIMARYelement>
<element tag&#61;"0008,0012" vr&#61;"DA" vm&#61;"1" len&#61;"8" name&#61;"InstanceCreationDate">20091111element>
<element tag&#61;"0008,0013" vr&#61;"TM" vm&#61;"1" len&#61;"10" name&#61;"InstanceCreationTime">164835.000element>
<element tag&#61;"0008,0014" vr&#61;"UI" vm&#61;"1" len&#61;"30" name&#61;"InstanceCreatorUID">1.2.826.0.1.3680043.2.307.111element>
<element tag&#61;"0008,0016" vr&#61;"UI" vm&#61;"1" len&#61;"28" name&#61;"SOPClassUID">1.2.840.10008.5.1.4.1.1.6.1element>
<element tag&#61;"0008,0018" vr&#61;"UI" vm&#61;"1" len&#61;"58" name&#61;"SOPInstanceUID">1.2.826.0.1.3680043.2.307.111.48712655111.78571.301.34207element>
<element tag&#61;"0008,0020" vr&#61;"DA" vm&#61;"1" len&#61;"8" name&#61;"StudyDate">20010215element>
<element tag&#61;"0008,0023" vr&#61;"DA" vm&#61;"1" len&#61;"8" name&#61;"ContentDate">20010215element>
<element tag&#61;"0008,0030" vr&#61;"TM" vm&#61;"0" len&#61;"0" name&#61;"StudyTime">element>
<element tag&#61;"0008,0033" vr&#61;"TM" vm&#61;"1" len&#61;"10" name&#61;"ContentTime">093006.000element>
<element tag&#61;"0008,0050" vr&#61;"SH" vm&#61;"0" len&#61;"0" name&#61;"AccessionNumber">element>
<element tag&#61;"0008,0060" vr&#61;"CS" vm&#61;"1" len&#61;"2" name&#61;"Modality">USelement>
<element tag&#61;"0008,0070" vr&#61;"LO" vm&#61;"0" len&#61;"0" name&#61;"Manufacturer">element>
<element tag&#61;"0008,0090" vr&#61;"PN" vm&#61;"0" len&#61;"0" name&#61;"ReferringPhysicianName">element>
<element tag&#61;"0008,1030" vr&#61;"LO" vm&#61;"1" len&#61;"12" name&#61;"StudyDescription">CLR Standardelement>
<element tag&#61;"0008,2111" vr&#61;"ST" vm&#61;"1" len&#61;"66" name&#61;"DerivationDescription">From DSR by TomoVision&#39;s DICOMatic 2.0 rev-2e (conversion module)element>
<element tag&#61;"0008,2124" vr&#61;"IS" vm&#61;"0" len&#61;"0" name&#61;"NumberOfStages">element>
<element tag&#61;"0008,212a" vr&#61;"IS" vm&#61;"0" len&#61;"0" name&#61;"NumberOfViewsInStage">element>
<element tag&#61;"0010,0010" vr&#61;"PN" vm&#61;"1" len&#61;"12" name&#61;"PatientName">BURRUS^NOLAelement>
<element tag&#61;"0010,0020" vr&#61;"LO" vm&#61;"1" len&#61;"6" name&#61;"PatientID">655111element>
<element tag&#61;"0010,0030" vr&#61;"DA" vm&#61;"0" len&#61;"0" name&#61;"PatientBirthDate">element>
<element tag&#61;"0010,0040" vr&#61;"CS" vm&#61;"0" len&#61;"0" name&#61;"PatientSex">element>
<element tag&#61;"0018,0010" vr&#61;"LO" vm&#61;"0" len&#61;"0" name&#61;"ContrastBolusAgent">element>
<element tag&#61;"0018,1030" vr&#61;"LO" vm&#61;"1" len&#61;"12" name&#61;"ProtocolName">CLR Standardelement>
<element tag&#61;"0018,5100" vr&#61;"CS" vm&#61;"0" len&#61;"0" name&#61;"PatientPosition">element>
<sequence tag&#61;"0018,6011" vr&#61;"SQ" card&#61;"4" len&#61;"784" name&#61;"SequenceOfUltrasoundRegions">
………………………………………
item>
sequence>
data-set>
file-format>

附录2

"SOPInstanceUID" type&#61;"string" indexed&#61;"true" stored&#61;"true" required&#61;"true" multiValued&#61;"false" />
"PatientID" type&#61;"string" indexed&#61;"true" stored&#61;"true" multiValued&#61;"false" />
"StudyDescription" type&#61;"string" indexed&#61;"true" stored&#61;"true"/>
"PatientName" type&#61;"string" indexed&#61;"true" stored&#61;"true" />
"DicomUrl" type&#61;"string" stored&#61;"true"/>
"ImageType" type&#61;"string" indexed&#61;"true" stored&#61;"true"/>
"InstanceCreationDate" type&#61;"string" indexed&#61;"true" stored&#61;"true"/>
"InstanceCreationTime" type&#61;"string" indexed&#61;"true" stored&#61;"true"/>
"StudyDate" type&#61;"string" indexed&#61;"true" stored&#61;"true"/>
"ContentDate" type&#61;"string" indexed&#61;"true" stored&#61;"true"/>
"DerivationDescription" type&#61;"string" indexed&#61;"true" stored&#61;"true"/>
"ProtocolName" type&#61;"string" indexed&#61;"true" stored&#61;"true"/>
Mention the unique key along with this
SOPInstanceUID
(Remove any previously existing unique key tag and replace with this tag.)

附录3

SOLR_LOCATOR : {#This is the name of the collection which we created with solrctl utility in our earlier stepscollection : demo-collection
#Zookeeper host names, you will find this information in Cloudera Manager at ZooKeeper service
zkHost : "hostip1:2181, hostip2:2181, hostip3:2181/solr" }
And include this specific XQuery inside the commands tag of morphlines
xquery {fragments : [{fragmentPath : "/"queryString : """for $data in /file-format/data-setreturn{$data/element[&#64;name&#61;&#39;SOPInstanceUID&#39;]}{$data/element[&#64;name&#61;&#39;ImageType&#39;]}{$data/element[&#64;name&#61;&#39;InstanceCreationDate&#39;]}{$data/element[&#64;name&#61;&#39;InstanceCreationTime&#39;]}{$data/element[&#64;name&#61;&#39;StudyDate&#39;]}{$data/element[&#64;name&#61;&#39;ContentDate&#39;]}{$data/element[&#64;name&#61;&#39;DerivationDescription&#39;]}{$data/element[&#64;name&#61;&#39;ProtocolName&#39;]}{$data/element[&#64;name&#61;&#39;PatientID&#39;]}{$data/element[&#64;name&#61;&#39;PatientName&#39;]}{$data/element[&#64;name&#61;&#39;StudyDescription&#39;]}{$data/element[&#64;name&#61;&#39;DicomUrl&#39;]}"""}]}
}


推荐阅读
  • 如何高效启动大数据应用之旅?
    在前一篇文章中,我探讨了大数据的定义及其与数据挖掘的区别。本文将重点介绍如何高效启动大数据应用项目,涵盖关键步骤和最佳实践,帮助读者快速踏上大数据之旅。 ... [详细]
  • 如何撰写PHP电商项目的实战经验? ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • 本文介绍了如何使用Flume从Linux文件系统收集日志并存储到HDFS,然后通过MapReduce清洗数据,使用Hive进行数据分析,并最终通过Sqoop将结果导出到MySQL数据库。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • 2012年9月12日优酷土豆校园招聘笔试题目解析与备考指南
    2012年9月12日,优酷土豆校园招聘笔试题目解析与备考指南。在选择题部分,有一道题目涉及中国人的血型分布情况,具体为A型30%、B型20%、O型40%、AB型10%。若需确保在随机选取的样本中,至少有一人为B型血的概率不低于90%,则需要选取的最少人数是多少?该问题不仅考察了概率统计的基本知识,还要求考生具备一定的逻辑推理能力。 ... [详细]
  • 在拉斯维加斯举行的Interop 2011大会上,Bitcurrent的Alistair Croll发表了一场主题为“如何以云计算的视角进行思考”的演讲。该演讲深入探讨了传统IT思维与云计算思维之间的差异,并提出了在云计算环境下应具备的新思维方式。Croll强调了灵活性、可扩展性和成本效益等关键要素,以及如何通过这些要素来优化企业IT架构和运营。 ... [详细]
  • 本文详细介绍了 jQuery 的入门知识与实战应用,首先讲解了如何引入 jQuery 库及入口函数的使用方法,为初学者提供了清晰的操作指南。此外,还深入探讨了 jQuery 在实际项目中的多种应用场景,包括 DOM 操作、事件处理和 AJAX 请求等,帮助读者全面掌握 jQuery 的核心功能与技巧。 ... [详细]
  • CentOS 7环境下Jenkins的安装与前后端应用部署详解
    CentOS 7环境下Jenkins的安装与前后端应用部署详解 ... [详细]
  • Python 数据分析领域不仅拥有高质量的开发环境,还提供了众多功能强大的第三方库。本文将介绍六个关键步骤,帮助读者掌握 Python 数据分析的核心技能,并深入探讨六款虽不广为人知但却极具潜力的数据处理库,如 Pandas 的替代品和新兴的可视化工具,助力数据科学家和分析师提升工作效率。 ... [详细]
  • 本文详细介绍了如何在PHP中记录和管理行为日志,包括ThinkPHP框架中的日志记录方法、日志的用途、实现原理以及相关配置。 ... [详细]
  • 深入解析HTML5字符集属性:charset与defaultCharset
    本文将详细介绍HTML5中新增的字符集属性charset和defaultCharset,帮助开发者更好地理解和应用这些属性,以确保网页在不同环境下的正确显示。 ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • 微信小程序详解:概念、功能与优势
    微信公众平台近期向200位开发者发送了小程序的内测邀请。许多人对微信小程序的概念还不是很清楚。本文将详细介绍微信小程序的定义、功能及其独特优势。 ... [详细]
  • 微信公众号推送模板40036问题
    返回码错误码描述说明40001invalidcredential不合法的调用凭证40002invalidgrant_type不合法的grant_type40003invalidop ... [详细]
author-avatar
fuotb_204
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有