如何将 dicom 数据集导出到 excel?
How do I export dicom datasets to excel?
我对编码还是很陌生,有几个问题。我正在处理一些文件扩展名为“.dcm”的 MRI 图像。我导入了 '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)
其次,如何提高我的代码效率。我有很多反复出现的语句,尤其是当我将值写入记事本时。有 better/faster 的方法吗?我还能改进什么?
最后,有没有办法直接将它们导出到 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")
由于我自己是初学者,查找子目录的答案已经发布,我想指出其他代码建议。
首先,我建议您将信息收集过程放入一种可读性和可重用性的方法中,如下所示:
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 循环之外。
现在你的程序看起来像这样:
# ...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 方法中,该方法 returns 一个信息元组。那么你可以这样做:
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
可能需要一些调整,因为我没有任何要测试的 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()
我对编码还是很陌生,有几个问题。我正在处理一些文件扩展名为“.dcm”的 MRI 图像。我导入了 '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)
其次,如何提高我的代码效率。我有很多反复出现的语句,尤其是当我将值写入记事本时。有 better/faster 的方法吗?我还能改进什么?
最后,有没有办法直接将它们导出到 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")
由于我自己是初学者,查找子目录的答案已经发布,我想指出其他代码建议。
首先,我建议您将信息收集过程放入一种可读性和可重用性的方法中,如下所示:
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 循环之外。 现在你的程序看起来像这样:
# ...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 方法中,该方法 returns 一个信息元组。那么你可以这样做:
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
可能需要一些调整,因为我没有任何要测试的 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()