LIDC-IDRI数据集的dicom文件XML标注读取

LIDC-IDRI数据集的dicom文件XML标注读取


最近用到LIDC-IDRI数据集,这里说一下这个xml文件的标注怎么读取。
数据集的获取我是在paperswithcode上面找到的:https://paperswithcode.com/dataset/lidc-idri

首先来看一下这个标注文件的地址,它是附带在dicom数据里面的。如下图
xml标注地址
尝试着打开一个,可以发现它的结构这样子的。

<?xml version="1.0" encoding="UTF-8"?>
<LidcReadMessage uid="1.3.6.1.4.1.14519.5.2.1.6279.6001.1307390687803.0" xmlns="http://www.nih.gov" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nih.gov  http://troll.rad.med.umich.edu/lidc/LidcReadMessage.xsd">
<ResponseHeader>
<Version>1.8.1</Version>
<MessageId>-421198203</MessageId>
<DateRequest>2007-11-01</DateRequest>
<TimeRequest>12:30:44</TimeRequest>
<RequestingSite>removed</RequestingSite>
<ServicingSite>removed</ServicingSite>
<TaskDescription>Second unblinded read</TaskDescription>
<CtImageFile>removed</CtImageFile>
<SeriesInstanceUid>1.3.6.1.4.1.14519.5.2.1.6279.6001.179049373636438705059720603192</SeriesInstanceUid>
<DateService>2008-08-18</DateService>
<TimeService>02:05:51</TimeService>
<ResponseDescription>1 - Reading complete</ResponseDescription>
<StudyInstanceUID>1.3.6.1.4.1.14519.5.2.1.6279.6001.298806137288633453246975630178</StudyInstanceUID></ResponseHeader>
<readingSession>
    <annotationVersion>3.12</annotationVersion>
    <servicingRadiologistID>540461523</servicingRadiologistID>
    <unblindedReadNodule>
      <noduleID>Nodule 001</noduleID>
      <characteristics>
        <subtlety>5</subtlety>
        <internalStructure>1</internalStructure>
        <calcification>6</calcification>
        <sphericity>3</sphericity>
        <margin>3</margin>
        <lobulation>3</lobulation>
        <spiculation>4</spiculation>
        <texture>5</texture>
        <malignancy>5</malignancy>
      </characteristics>
      <roi>
        <imageZposition>-125.000000 </imageZposition>
        <imageSOP_UID>1.3.6.1.4.1.14519.5.2.1.6279.6001.110383487652933113465768208719</imageSOP_UID>
        <inclusion>TRUE</inclusion>
        <edgeMap>
          <xCoord>312</xCoord>
          <yCoord>355</yCoord>
        </edgeMap>
        <edgeMap>
          <xCoord>311</xCoord>
          <yCoord>356</yCoord>
        </edgeMap>
        <edgeMap>
          <xCoord>310</xCoord>
          <yCoord>357</yCoord>
        </edgeMap>

这里省略了后面的很多,只展示了开始的一部分,下面我们来分析一下这个xml每个标识都代表了什么。
这里我们就要用到数据集中的annotations document文件,如下图这个:
在这里插入图片描述
这个文件描述了xml的标注方式以及每个标识符所代表的意思。
这里就不展开讲了,就讲几个关键的。

ResponseHeader

这个是头部分,记录了这个病例(也就是单个病人的CT图像)的信息。

readingSession

这个是某个医生的标注。这个数据集中每个病例都是由4个影像医生分别标注的。就是会有4个标注,每个ReadingSession表示一个医生的标注。

unblindedReadNodule

这个是医生采用非盲的方式标注的。这里我不是很懂这里的非盲指的是什么。医学上的盲的非盲指的是医生和病人相互不知道和相互知道的两种情况,这里的非盲我觉得可能是指医生是事先知道这个病人有肺结节的可能。

noduleID

这个是对每个肺结节的编号.其实没啥用。

characteristics

这个是对每个结节的描述。比如说大小啊啥的,具体可以去文件里面查。

roi

这个是每一层dcm文件的标注情况,这个就是roi具体所在的地方。其中imageZposition这个标识指的是这个roi所在的Z轴的位置,也就是它所在的slice。但这个值对应的并不是具体的那一层,而是和dcm文件里面的A字段相对应的,具体的方法可以用下面这个代码到,这面的打印中(0020, 1041) Slice Location这个字段的值-125.0就是对应的imageZposition,但他们取的小数点后精确度不一样,可以自己调一下:

import pydicom as dicom
#这个函数只能读取单个的dcm文件,不能读取整个目录
dimage  = dicom.dcmread(fine_name)
print (dimage)

#(0020, 1040) Position Reference Indicator        LO: 'SN'
#(0020, 1041) Slice Location                      DS: "-125.0"
#(0028, 0002) Samples per Pixel                   US: 1
#(0028, 0004) Photometric Interpretation          CS: 'MONOCHROME2'
#(0028, 0010) Rows                                US: 512
print(dimage.SliceLocation)
#-125.000000
print(dimage.SOPInstanceUID)
#1.3.6.1.4.1.14519.5.2.1.6279.6001.110383487652933113465768208719

除此之外,imageSOP_UID这个字段也可以为当前的roi找到唯一对应的dcm文件,因为每一个dcm文件都有自己的唯一标识符,可以在对应的SOP Instance UID字段中找到,如上图.
好了,最后的edgeMap标识就表示坐标点了。xCoord和yCoord分别是x坐标和y坐标。
整个代码可以简单的如下:

import pydicom as dicom
import os
import cv2
import numpy as np
import lxml.etree as etree
#这个函数输入的是xml的路径,返回的是读取的坐标
#这里获得的坐标是所有层的,但只读取了单个病理医生标注的第一个结节,后面的全都不读,要是想要读的话可以改一下代码
def xml_reader(path):
    anno = {}
    xmlns = '{http://www.nih.gov}'
    tree = etree.parse(path)
    #for ann in tree.findall('./Annotation'):
    assert tree.findall(xmlns + 'ResponseHeader')!=[] , '{}.has no ResponseHeader'.format(path)
    Res = tree.findall(xmlns + 'ResponseHeader')[0]
    #anno['SeriesInstanceUid']   = Res.findall(xmlns + 'SeriesInstanceUid')[0].text
    #anno['StudyInstanceUID']    = Res.findall(xmlns + 'StudyInstanceUID')[0].text
    #anno['session'] = []
    if tree.findall(xmlns + 'readingSession')==[]: return {}
    i = tree.findall(xmlns + 'readingSession')[0]
    Nodules = []
    if i.findall(xmlns + 'unblindedReadNodule')==[]: return {}
    j = i.findall(xmlns + 'unblindedReadNodule')[0]
    Nodule = []
    for k in j.findall(xmlns + 'roi'):
        roi = {}
        roi['imageSOP_UID'] = k.findall(xmlns + 'imageSOP_UID')[0].text
        roi['roi'] = []
        for l in k.findall(xmlns + 'edgeMap'):
            x = int(l.findall(xmlns + 'xCoord')[0].text)
            y = int(l.findall(xmlns + 'yCoord')[0].text)
            roi['roi'].append([x,y])
        Nodule.append(roi)
    Nodules.append(Nodule)
    anno['session']=Nodules
    return anno

roi_contour = xml_reader(xml_name)
#获取读取到的roi的坐标点
r = roi_contour['session'][0]
temp    = np.zeros((512, 512), np.uint8)
mask    = np.array(r['roi'],dtype=np.int)
#用cv2根据多边形画图。
temp    = cv2.fillConvexPoly(temp, mask, (255,255,255))

好了xml的解析就结束了。

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
LIDC-IDRI数据集是一个广泛使用的医学影像数据集,主要用于肺部CT图像分析和肺部肿瘤识别。该数据集由美国国立卫生研究院(NIH)赞助,共包含1010个患者的肺部CT图像。 LIDC-IDRI数据集的主要目的是为医学影像研究人员和机器学习算法提供一个标准的评估平台。数据集中的图像经过专业的放射科医生标注,具有丰富的信息,其中包括肺结节的位置、大小、形状、密度等。 该数据集提供了一定数量的肺结节的真实标注,这使得研究人员能够针对肺癌等疾病进行更准确的诊断和治疗。此外,LIDC-IDRI数据集还提供了一些额外的临床数据,例如患者的年龄、性别、吸烟史等,这些信息有助于进一步分析肺癌与患者的相关因素之间的关系。 由于LIDC-IDRI数据集的规模大且有丰富的标注信息,它被广泛应用于肺部肿瘤的自动检测和识别算法的开发。研究人员可以基于该数据集开展机器学习和深度学习的算法研究,以提高肺癌的早期检测和精准治疗。 LIDC-IDRI数据集的应用不仅仅限于医学领域,还可以扩展到计算机视觉和人工智能等领域。通过结合医学影像数据和先进的算法,可以开发出更准确和高效的肺部肿瘤诊断工具,为患者提供更好的医疗服务。 总之,LIDC-IDRI数据集是一个重要的肺部CT图像数据集,为医学影像分析及肺癌诊断研究提供了宝贵的资源。通过利用这个数据集,研究人员可以开展各种肺部肿瘤相关的研究,为肺癌患者的治疗和管理提供更好的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值