You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何递归遍历目录生成含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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:35:14