调用dicom-contour的cfile2pixels函数遇文件未找到错误的解决方法
解决DICOM轮廓与图像命名不匹配导致的FileNotFound错误
问题根源
RTSS格式的轮廓文件中,每个轮廓数据会通过ReferencedSOPInstanceUID关联对应DICOM图像的唯一标识,但你的图像文件采用IMG0000000000.dcm这类自定义命名,而非该UID,导致cfile2pixels函数直接用UID拼接路径时找不到目标文件。
解决方案
通过建立DICOM图像的SOP Instance UID到实际文件名的映射表,让函数能根据UID匹配到正确的图像文件,无需修改原文件命名。
步骤1:生成UID到文件名的映射表
遍历目录下所有DICOM图像,读取每个文件的SOPInstanceUID字段,建立关联映射:
import os import dicom def get_uid_to_filename_map(path): uid_filename_map = {} if path[-1] != '/': path += '/' for fname in os.listdir(path): if not fname.endswith('.dcm'): continue try: dcm_obj = dicom.read_file(os.path.join(path, fname)) uid_filename_map[dcm_obj.SOPInstanceUID] = fname except Exception: # 跳过非图像类DICOM文件(如RTSS轮廓文件) continue return uid_filename_map
步骤2:重写轮廓转像素的逻辑
基于原coord2pixels函数,加入映射表替换UID为实际文件名:
from dicom_contour.contour import coord2pixels as original_coord2pixels def mapped_coord2pixels(contour_data, path, uid_map): # 获取当前轮廓关联的图像UID ref_uid = contour_data.ContourImageSequence[0].ReferencedSOPInstanceUID # 从映射表中取出对应的实际文件名 target_img_fname = uid_map[ref_uid] # 调用原函数,传入正确的图像文件路径 return original_coord2pixels(contour_data, path, img_file=os.path.join(path, target_img_fname))
步骤3:修改cfile2pixels函数适配映射
调整原函数逻辑,使用自定义的映射转换函数替代原coord2pixels调用:
def cfile2pixels_with_map(file, path, uid_map, ROIContourSeq=0): if path[-1] != '/': path += '/' contour_dcm = dicom.read_file(os.path.join(path, file)) roicontour = contour_dcm.ROIContourSequence[ROIContourSeq] contours = [cnt for cnt in roicontour.ContourSequence] # 使用带映射的转换函数生成图像与轮廓数组对 img_contour_pairs = [mapped_coord2pixels(cdata, path, uid_map) for cdata in contours] return img_contour_pairs
步骤4:调用修改后的流程
# 生成UID-文件名映射表 uid_map = get_uid_to_filename_map(path) # 获取轮廓文件(使用你原有的get_contour_file函数) contour_file = get_contour_file(path) # 获取图像与轮廓数组配对列表 contour_arrays = cfile2pixels_with_map(file=contour_file, path=path, uid_map=uid_map, ROIContourSeq=0)
替代方案(可选)
如果允许修改文件命名,可批量将图像文件重命名为对应的SOPInstanceUID,这样原函数无需修改即可直接运行,但此方法会改变文件原有命名规则。
内容的提问来源于stack exchange,提问作者Mona Mehrabani
相关产品推荐
相关产品推荐

