如何递归遍历目录生成含DICOM元数据的CSV研究汇总文件
最优实现方案:遍历DICOM目录生成CSV记录
核心逻辑
- 继续用Pathlib处理目录遍历,它的层级路径操作天生适配你的目录结构,完全能hold住复杂场景
- 直接从目录路径里提取年、月、日、研究名称、模态这些固定层级的信息,不用重复从DICOM文件里抠
- 每个模态目录下只读取第一个DICOM文件的元数据(同研究同模态的DICOM元数据基本一致),大幅提升处理效率
- 先把所有研究的记录攒在列表里,最后一次性写入CSV,减少频繁IO的开销
代码实现
from pathlib import Path import pydicom import csv def extract_dicom_metadata(dicom_path): """提取DICOM核心元数据,做容错处理避免崩溃""" try: # 只读取元数据,跳过像素数据,速度更快 ds = pydicom.dcmread(dicom_path, stop_before_pixels=True) return { "patient_name": getattr(ds, "PatientName", ""), "institution_name": getattr(ds, "InstitutionName", ""), "study_description": getattr(ds, "StudyDescription", ""), "modality": getattr(ds, "Modality", "") } except Exception as e: print(f"读取{dicom_path}失败: {e}") return { "patient_name": "", "institution_name": "", "study_description": "", "modality": "" } def process_dicom_directory(root_dir): root = Path(root_dir) study_records = [] # 遍历所有模态目录(层级:年/月/日/研究/模态) for modality_dir in root.glob("*/*/*/*/*"): if not modality_dir.is_dir(): continue # 从路径拆分出层级信息 path_parts = modality_dir.parts # 假设路径结构是「root/年/月/日/研究名称/模态」,索引从1开始跳过root year = path_parts[1] month = path_parts[2] day = path_parts[3] study_name = path_parts[4] modality = path_parts[5] # 找模态目录下的第一个DICOM文件 dicom_files = list(modality_dir.glob("*.dcm")) if not dicom_files: print(f"模态目录{modality_dir}下无DICOM文件,跳过") continue dicom_metadata = extract_dicom_metadata(dicom_files[0]) # 组装完整记录 record = { "year": year, "month": month, "day": day, "study_name": study_name, "modality": modality, "patient_name": dicom_metadata["patient_name"], "institution_name": dicom_metadata["institution_name"], "study_description": dicom_metadata["study_description"] } study_records.append(record) # 批量写入CSV if study_records: csv_columns = ["year", "month", "day", "study_name", "modality", "patient_name", "institution_name", "study_description"] with open("dicom_study_records.csv", "w", newline="", encoding="utf-8") as csvfile: writer = csv.DictWriter(csvfile, fieldnames=csv_columns) writer.writeheader() writer.writerows(study_records) print(f"已生成CSV记录,共{len(study_records)}条") else: print("未找到有效研究记录") # 调用示例:替换成你的根目录路径 process_dicom_directory("/path/to/your/dicom/root")
关键细节说明
- 跳过像素数据:用
stop_before_pixels=True读取DICOM,只加载元数据,处理速度提升明显 - 容错机制:用
getattr处理缺失的DICOM字段,同时捕获读取异常,避免单个损坏文件导致整个程序中断 - 路径索引调整:如果你的根目录本身包含在层级路径里(比如
/data/dicom/2024/05/20/...),记得调整path_parts的索引(比如年对应的索引改为2) - 研究合并:如果同一个研究跨多个模态,当前代码会为每个模态生成一条记录;如果要按研究合并,可以在收集记录时用
study_name作为key,把多模态信息整合到同一条记录中
内容的提问来源于stack exchange,提问作者Eoin Vaughan
相关产品推荐
相关产品推荐

