如何将DICOM数据集导出到Excel?

2024-05-13 02:06:51 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我想添加到脚本中的第一个特性是能够在子文件夹中搜索扩展名为“.dcm”的文件,并且能够在脚本中打开每个文件并提取我需要的信息。到目前为止,我已经将它设置为只在当前目录中查找'.dcm'文件。 如果我使用下面的代码,我可以从子文件夹中获取所有文件名,但是当我尝试使用内置的dicom.read_文件方法,它显然会给我一个找不到文件的错误。有办法吗?在

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

其次,如何提高代码的效率。我有很多重复的语句,尤其是当我将值写入记事本时。有更好/更快的方法吗?我还能改进什么?在

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

^{pr2}$

Tags: 文件方法代码in脚本文件夹fornames
3条回答

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

import xlsxwriter
import os
import dicom


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

for dcm_file in dcm_files:
    ds = dicom.read_file(dcm_file)
    workbook = xlsxwriter.Workbook(os.path.basename(dcm_file) + '.xlsx')
    worksheet = workbook.add_worksheet()

    data = (
            ["RepetitionTime", ds.get("RepetitionTime", "None")],
            ["EchoTime", ds.get("EchoTime", "None")],
            .
            .
            .
            )

    row = 0
    col = 0

    for name, value in (data):
        worksheet.write(row, col,     name)
        worksheet.write(row, col + 1, value)
        row += 1

    workbook.close()

由于我自己是初学者,找到子方向的答案已经发布了,我想指出其他的代码建议。在

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

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一次,并且每次收集信息时都将其关闭。你必须把f.close命令移到程序的末尾,在for循环之外。 现在你的程序应该是这样的:

^{pr2}$

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

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

而不是

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

请记住,无论代码或语言是什么,bug/LOC比率都是恒定不变的,所以保持简短。而且,长代码很难导航。在

第四,可以将所有的getter放入一个返回信息元组的getinfo方法中。然后你就可以:

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

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

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

相关问题 更多 >