如何将dicom数据集导出为ex​​cel?

时间:2015-05-12 06:07:14

标签: python python-2.7 metadata export-to-excel dicom

我对编码还很陌生,并且有几个问题。我正在研究一些MRI图像,文件扩展名为“.dcm”。我导入了' dicom'允许我从文件中提取特定参数(例如患者姓名年龄,扫描类型等)的模块。然后将这些值写入记事本(值以制表符分隔),然后导出到Excel。

我想要添加到脚本的第一个功能是能够在子文件夹中搜索具有' .dcm'扩展并能够在脚本中打开它们并提取我需要的信息。截至目前,我有这样的说法,它只能找到' .dcm'当前目录中的文件。 如果我使用下面的代码,我可以从子文件夹中获取所有文件名,但是当我尝试使用内置的' dicom.read_file()'来打开它们时。方法,它显然会给我一个错误,该文件无法找到。有办法吗?

my_List= []
for root, dirs, files in os.walk(path):
 for names in files:
  if names.endswith(".dcm"):
   my_List.append(names)

其次,我怎样才能提高代码的效率。我有很多反复的陈述,特别是当我把值写入记事本时。有没有更好/更快的方法呢?我还能改进什么?

最后,有没有一种方法可以直接将它们导出到excel,而不是将我需要的值导出到记事本然后再导出到excel?

for i in range(len(my_List)):     


    ds = dicom.read_file(my_List[i])
    if ds.SeriesDescription not in Series:

        info = {}
        info['PatientName']=ds.PatientName

        info['SeriesDescription']=ds.SeriesDescription
        Series.append(ds.SeriesDescription)
        getRepetitionTime(ds)
        getEchoTime(ds)
        getInversionTime(ds)
        getNumberOfAverages(ds)
        getSpacingBetweenSlices(ds)
        getPercentSampling(ds)
        getPercentPhaseFieldOfView(ds)
        getAcquisitionMatrix(ds)
        getFlipAngle(ds)
        getImagesInAcquisition(ds)
        getPixelSpacing(ds)
        f.write(info['PatientName'])
        f.write("\t")
        f.write(info['SeriesDescription'])
        f.write("\t")
        f.write(info['RepetitionTime'])
        f.write("\t")
        f.write(info['EchoTime'])
        f.write("\t")
        f.write(info['InversionTime'])
        f.write("\t")
        f.write(info['NumberOfAverages'])
        f.write("\t")
        f.write(info['SpacingBetweenSlices'])
        f.write("\t")
        f.write(info['PercentSampling'])
        f.write("\t")
        f.write(info['PercentPhaseFieldOfView'])
        f.write("\t")
        f.write(info['AcquisitionMatrix'])
        f.write("\t")
        f.write(info['FlipAngle'])
        f.write("\t")
        f.write(info['ImagesInAcquisition'])
        f.write("\t")     
        f.write(info['PixelSpacing'])
        f.write("\n")

3 个答案:

答案 0 :(得分:1)

由于我自己是初学者,并且已经发布了查找子网站的答案,我想指出其他代码建议。

首先,我建议您将信息收集过程放入一个可读性和可重用性的方法中:

def collect_info(filename):
    ds = dicom.read_file(filename)
    if ds.SeriesDescription not in Series:
    info = {}

    info['PatientName']=ds.PatientName

    info['SeriesDescription']=ds.SeriesDescription
    Series.append(ds.SeriesDescription)
    getRepetitionTime(ds)
    getEchoTime(ds)
    getInversionTime(ds)
    getNumberOfAverages(ds)
    getSpacingBetweenSlices(ds)
    getPercentSampling(ds)
    getPercentPhaseFieldOfView(ds)
    getAcquisitionMatrix(ds)
    getFlipAngle(ds)
    getImagesInAcquisition(ds)
    getPixelSpacing(ds)
    f.write(info['PatientName'])
    f.write("\t")
    f.write(info['SeriesDescription'])
    f.write("\t")
    f.write(info['RepetitionTime'])
    f.write("\t")
    f.write(info['EchoTime'])
    f.write("\t")
    f.write(info['InversionTime'])
    f.write("\t")
    f.write(info['NumberOfAverages'])
    f.write("\t")
    f.write(info['SpacingBetweenSlices'])
    f.write("\t")
    f.write(info['PercentSampling'])
    f.write("\t")
    f.write(info['PercentPhaseFieldOfView'])
    f.write("\t")
    f.write(info['AcquisitionMatrix'])
    f.write("\t")
    f.write(info['FlipAngle'])
    f.write("\t")
    f.write(info['ImagesInAcquisition'])
    f.write("\t")     
    f.write(info['PixelSpacing'])
    f.write("\n")
    f.close()

其次,这个程序是否有效?如果我是正确的,您只打开一次,并在每次收集信息时关闭它。您必须将f.close命令移动到for循环之外的程序的最后。 现在你的程序看起来像这样:

# ...stuff...
for i in range(len(my_List)):
    collect_info(my_List[i])
f.close()
print 'It took', time.time()-start, 'seconds.'

第三,您可以通过编写以下内容来缩短代码:

f.write(info['EchoTime'] + '\t')

而不是

f.write(info['EchoTime'])
f.write('\t')

请记住,无论代码或语言是什么,每个LOC比率的错误都是相同的,所以请保持简短。此外,长代码很难导航。

第四,您可以将所有getter放入一个返回信息元组的 get_info 方法。然后你可以做到:

for token in get_info():
    f.write(token + '\t')

答案 1 :(得分:1)

对于第一部分,请尝试以下代码:

my_List= []
for root, dirs, files in os.walk(path):
    for names in files:
        if names.endswith(".dcm"):
            my_List.append(os.path.join(root, names ))

对于写作部分,是的,实际上你的函数看起来有点多余,你实际上可以使用python CSV writer。 在此处尝试使用CSV编写器:https://docs.python.org/2/library/csv.html

答案 2 :(得分:1)

可能需要一些调整,因为我没有要测试的任何dcm文件,但你可以得到这个想法:

absolute path