如何将DICOM-RT结构轮廓数据转换成图像坐标?
How to convert DICOM-RT structure Contour data into image coordinate?
我使用 Python-pydicom 模块加载患者样本:
def load_data(sample):
data=dict()
# dcms data
dcms_data=dict()
for dcm_file in sample['dcm_files']: # 遍历读取数据
ds = pydicom.dcmread(dcm_file)
array = ds.pixel_array
origin = ds.ImagePositionPatient # 网格原点在世界坐标系的位置
spacing = ds.PixelSpacing # 采样间隔
uid = ds.SOPInstanceUID
dcms_data[uid] = {'dcmSpacing': spacing, 'dcmOrigin': origin, 'array': array}
data['dcms_data']=dcms_data
# rt data
rt_data = dict() # 以{RUID:label_data}形式返回结果
ds = pydicom.dcmread(sample['rt_file'])
sequences = ds.ROIContourSequence[0].ContourSequence
for sequence in sequences:
ruid = sequence.ContourImageSequence[0].ReferencedSOPInstanceUID
array = sequence.ContourData
num = sequence.NumberOfContourPoints
rt_data[ruid] = {'pointNumber': num, 'array': array}
data['rt_data']=rt_data
# 返回结果
return data
然后我将 DICOM-RT 结构轮廓数据转换为图像坐标:
def convert_global_aix_to_net_pos(data):
point_data = {} # 返回坐标{uid:data}
for uid, value in data['rt_data'].items():
num = value['pointNumber']
label_data = value['array']
dcm_origin = data['dcms_data'][uid]['dcmOrigin']
dcm_spacing = data['dcms_data'][uid]['dcmSpacing']
point = [] # 坐标[(x1,y1),(...),...]
for i in range(0,num,3):
x = label_data[i] # 轮廓世界坐标系
y = label_data[i + 1]
X = int(float(x) - float(dcm_origin[0]) / float(dcm_spacing[0])) # 轮廓X坐标
Y = int(float(y) - float(dcm_origin[1]) / float(dcm_spacing[1])) # 轮廓Y坐标
point.append((X, Y))
point_data[uid] = point
return point_data
但是当我在 dicom 上测试这个函数时 files.I 发现它返回了错误的点数据(负数据)
我猜我将DICOM-RT Struct轮廓数据转换为图像坐标的方法是错误的,但我找不到其他方法。
我的方法错了吗?或者我该如何实施?
提前致谢。
您似乎在 float(x) - float(dcm_origin[0])
周围缺少括号(y 行也是如此)。减法需要先做除法
否则它看起来没问题,假设 ImageOrientationPatient 为 (1, 0, 0, 0, 1, 0)。
我认为 def convert_global_aix_to_net_pos(data)
下行中 range()
的停止值:
for i in range(0, num, 3):
应该是:
for i in range(0, len(label_data), 3):
原因是num
是从sequence.NumberOfContourPoints
导出的,label_data
是从sequence.ContourData
导出的,并且:
3*len(sequence.NumberOfContourPoints) = len(sequence.ContourData)
由于每个轮廓点由3个连续的轮廓数据元素组成。
在 NumberOfContourPoints
处停止将导致仅遍历 ContourData
中 1/3 的元素,因此只有 1/3 的点。
我使用 Python-pydicom 模块加载患者样本:
def load_data(sample):
data=dict()
# dcms data
dcms_data=dict()
for dcm_file in sample['dcm_files']: # 遍历读取数据
ds = pydicom.dcmread(dcm_file)
array = ds.pixel_array
origin = ds.ImagePositionPatient # 网格原点在世界坐标系的位置
spacing = ds.PixelSpacing # 采样间隔
uid = ds.SOPInstanceUID
dcms_data[uid] = {'dcmSpacing': spacing, 'dcmOrigin': origin, 'array': array}
data['dcms_data']=dcms_data
# rt data
rt_data = dict() # 以{RUID:label_data}形式返回结果
ds = pydicom.dcmread(sample['rt_file'])
sequences = ds.ROIContourSequence[0].ContourSequence
for sequence in sequences:
ruid = sequence.ContourImageSequence[0].ReferencedSOPInstanceUID
array = sequence.ContourData
num = sequence.NumberOfContourPoints
rt_data[ruid] = {'pointNumber': num, 'array': array}
data['rt_data']=rt_data
# 返回结果
return data
然后我将 DICOM-RT 结构轮廓数据转换为图像坐标:
def convert_global_aix_to_net_pos(data):
point_data = {} # 返回坐标{uid:data}
for uid, value in data['rt_data'].items():
num = value['pointNumber']
label_data = value['array']
dcm_origin = data['dcms_data'][uid]['dcmOrigin']
dcm_spacing = data['dcms_data'][uid]['dcmSpacing']
point = [] # 坐标[(x1,y1),(...),...]
for i in range(0,num,3):
x = label_data[i] # 轮廓世界坐标系
y = label_data[i + 1]
X = int(float(x) - float(dcm_origin[0]) / float(dcm_spacing[0])) # 轮廓X坐标
Y = int(float(y) - float(dcm_origin[1]) / float(dcm_spacing[1])) # 轮廓Y坐标
point.append((X, Y))
point_data[uid] = point
return point_data
但是当我在 dicom 上测试这个函数时 files.I 发现它返回了错误的点数据(负数据)
我猜我将DICOM-RT Struct轮廓数据转换为图像坐标的方法是错误的,但我找不到其他方法。 我的方法错了吗?或者我该如何实施? 提前致谢。
您似乎在 float(x) - float(dcm_origin[0])
周围缺少括号(y 行也是如此)。减法需要先做除法
否则它看起来没问题,假设 ImageOrientationPatient 为 (1, 0, 0, 0, 1, 0)。
我认为 def convert_global_aix_to_net_pos(data)
下行中 range()
的停止值:
for i in range(0, num, 3):
应该是:
for i in range(0, len(label_data), 3):
原因是num
是从sequence.NumberOfContourPoints
导出的,label_data
是从sequence.ContourData
导出的,并且:
3*len(sequence.NumberOfContourPoints) = len(sequence.ContourData)
由于每个轮廓点由3个连续的轮廓数据元素组成。
在 NumberOfContourPoints
处停止将导致仅遍历 ContourData
中 1/3 的元素,因此只有 1/3 的点。