Как преобразовать данные контура структуры DICOM-RT в координату изображения?

#pydicom

#pydicom

Вопрос:

Я использую модуль 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.Я обнаружил, что он вернул неправильные данные о точках (отрицательные данные)

Я предполагаю, что метод преобразования данных контура структуры DICOM-RT в координату изображения неверен, но я просто не могу найти другого способа. Мой метод неверен? Или как я мог бы это реализовать? Заранее спасибо.

Ответ №1:

Похоже, что у вас отсутствуют скобки вокруг float(x) - float(dcm_origin[0]) (и аналогично для y-линии). Вычитание должно быть выполнено перед разделением.

В остальном все выглядит нормально, предполагая, что imageOrientation соответствует (1, 0, 0, 0, 1, 0).

Комментарии:

1. Привет ~ darcymason, спасибо за ваш ответ. Ваш ответ отлично устранил мою проблему.

Ответ №2:

Я думаю, что значение stop для range() в строке под def convert_global_aix_to_net_pos(data) :

 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 приведет к перебору только 1/3 элементов в ContourData и, следовательно, только 1/3 точек.