nifty2Dicom nifty数据转为dicom格式(python)

122 阅读2分钟

dicom2nifty 的脚本网上都有很多但是,你nifty转为dicom 的却不是很多。这边我自己实验了一个 真实可用的代码:

其实转为dicom 只要写好头文件信息(Tag)和保存好数据格式就行了,我们一般读取进来用sitk.uint8 类型即可。

image.png

image.png

image.png

最主要的其实就是spaceing size orientation

代码转自一个 github上 改写了一下(侵权请联系我)

from __future__ import print_function
import SimpleITK as sitk
import sys, time, os

import cv2
import numpy as np
from pydicom.uid import generate_uid
def convert(input_nifti_path: str,  output_dicom_path: str):
    img = sitk.ReadImage(input_nifti_path,sitk.sitkUInt8) # 这边最好为整形数据
    # img = sitk.Normalize(img)

    modification_time = time.strftime("%H%M%S")
    modification_date = time.strftime("%Y%m%d")

    FrameOfReferenceUID='1.2.826.0.1.3680043.2.1125.'+ modification_date + ".2"
    direction = img.GetDirection()
    series_tag_values = [("0008|0005", "ISO_IR 192"),
                         ("0008|0031", modification_time),  # Series Time
                         ("0008|0021", modification_date),  # Series Date
                         ("0008|0008", "DERIVED\SECONDARY"),  # Image Type
                         ("0020|000d", "1.2.826.0.1.3680043.2.1125." + modification_date + ".1"),
                         ("0020|000e", "1.2.826.0.1.3680043.2.1125." + modification_date + ".1" + modification_time),
                         ("0020|0052", "1.2.826.0.1.3680043.2.1125." + modification_date + ".2"),
                         ("0020|0011", "1"),
                         # Series Instance UID
                         ("0020|0037",
                          '\'.join(map(str, (direction[0], direction[3], direction[6],  # Image Orientation (Patient)
                                              direction[1], direction[4], direction[7])))),
                         ("0008|103e", "datu")
                         ]
    list(map(lambda i: write_slices(output_dicom_path, series_tag_values, img, i), range(img.GetDepth())))
    # list(map(lambda i: write_slices(output_dicom_path, series_tag_values, img, i), range(0,1)))
def write_slices(data_directory, series_tag_values, new_img, i):
    spacing = new_img.GetSpacing()
    origin = new_img.GetOrigin()
    PixelSpacing = [spacing[0], spacing[1]]
    SliceThickness = spacing[2]
    SliceLocation = origin[2]+i*SliceThickness
    ImagePositionPatient=[origin[0], origin[1],SliceLocation]
    image_slice = new_img[:, :, i]
    # Tags shared by the series.
    list(map(lambda tag_value: image_slice.SetMetaData(tag_value[0], tag_value[1]), series_tag_values))

    # Slice specific tags.
    image_slice.SetMetaData("0008|0012", time.strftime("%Y%m%d"))  # Instance Creation Date
    image_slice.SetMetaData("0008|0013", time.strftime("%H%M%S"))  # Instance Creation Time

    # Setting the type to CT preserves the slice location.
    image_slice.SetMetaData("0008|0060", "MR")  # set the type to CT so the thickness is carried over
    image_slice.SetMetaData("0018|0050", str(SliceThickness))  # Instance Number
    image_slice.SetMetaData("0018|5100",'HFS')
    image_slice.SetMetaData("0010|0010","patienName")
    image_slice.SetMetaData("0010|0020",'patienID')

    # (0020, 0032) image position patient determines the 3D spacing between slices.
    image_slice.SetMetaData("0020|0032", '\'.join( map(str, new_img.TransformIndexToPhysicalPoint((0, 0, i)))))  # Image Position (Patient)
    image_slice.SetMetaData("0020|0013", str(i))  # Instance Number
    image_slice.SetMetaData("0020|1041", str(new_img.TransformIndexToPhysicalPoint((0, 0, i))[2]))  # Instance Number

    # Write to the output directory and add the extension dcm, to force writing in DICOM format.
    writer = sitk.ImageFileWriter()
    writer.KeepOriginalImageUIDOn()
    writer.SetFileName(os.path.join(data_directory, str(i) + '.dcm'))
    writer.Execute(image_slice)


if __name__ == "__main__":
    input_nifti_path = r'./data1.nii.gz'
    output_dicom_path = r'./data/out'

    convert(input_nifti_path, output_dicom_path)
    

看下效果图:

image.png