DICOM图像坐标系和病人坐标系的相互转换

本代码是https://nipy.org/nibabel/dicom/dicom_orientation.html#dicom-slice-affine的实现,关于两个坐标系的描述,可参考:https://www.cnblogs.com/zhhfan/p/9936945.html

需求:在Mimics中对3D图像中的关键点进行了标注,保存了关键点的坐标,该坐标属于病人坐标系,在做关键点检测时,需要把病人坐标系中的点坐标映射到图像坐标系。

代码如下:

import os
import numpy as np
import pydicom
import pylab

def get_affine_matrix(dicom_dir):
    '''
    Calculate the affine matrix which maps the voxel from the DICOM voxel space (column, row, depth) to patient
    coordinate system (x, y, z)
    reference: https://nipy.org/nibabel/dicom/dicom_orientation.html#dicom-slice-affine
    written by Shumao Pang, [email protected]
    :param dicom_dir: a dicom series dir
    :return: a numpy array with shape of (4, 4)
    '''
    dicom_file_list = os.listdir(dicom_dir)
    slice_num = len(dicom_file_list)
    dicom_list = [0] * slice_num
    for dicom_file in dicom_file_list:
        ds = pydicom.read_file(os.path.join(dicom_dir, dicom_file))
        instance_number = ds.InstanceNumber
        dicom_list[instance_number - 1] = ds
    pixel_spacing = dicom_list[0].PixelSpacing
    image_orientation_patient = dicom_list[0].ImageOrientationPatient
    orientation_matrix = np.reshape(image_orientation_patient, [3, 2], order='F')
    orientation_matrix = orientation_matrix[:, ::-1]

    first_image_position_patient = np.array(dicom_list[0].ImagePositionPatient)
    last_image_position_patient = np.array(dicom_list[-1].ImagePositionPatient)
    k = (last_image_position_patient - first_image_position_patient) / (slice_num - 1)

    affine_matrix = np.zeros((4, 4), dtype=np.float32)
    affine_matrix[:3, 0] = orientation_matrix[:, 0] * pixel_spacing[0]
    affine_matrix[:3, 1] = orientation_matrix[:, 1] * pixel_spacing[1]
    affine_matrix[:3, 2] = k
    affine_matrix[:3, 3] = first_image_position_patient
    affine_matrix[3, 3] = 1.0
    return affine_matrix

if __name__ == '__main__':
    data_dir = '/data/dicom_case1'
    affine_matrix = get_affine_matrix(data_dir)
    inv_affine_matrix = np.linalg.inv(affine_matrix)

    print('affine matrix:\n', affine_matrix)
    print('inv affine matrix:\n', inv_affine_matrix)

    image_coord = np.array([0, 0, 0]) # (row, column, depth)
    input = np.ones(4, dtype=np.float32)
    input[:3] = image_coord
    # map the image coord to patient coord
    patient_coord = np.matmul(affine_matrix, input)
    print('image coord:\n', image_coord)
    print('patient coord:\n', patient_coord)

    # map the patient coord to image coord
    inv_image_coord = np.matmul(inv_affine_matrix, patient_coord).astype(int)[:3] # (row, column, depth)
    print('inv image coord:\n', inv_image_coord)


 

你可能感兴趣的:(python)