7-18 nii.gz文件的处理

CBCT的分类结果是以nii.gz格式存储的,为此要对分类结果进行展示就必须对nii.gz格式文件进行解析,然后以合适的方式进行可视化。

同样的,前端js方面依旧缺乏解析的库,为此想了一个代替方案,通过后端python的SimpleITK 库对nii.gz格式进行解析,并由此生成不同视图的图片,在前端展示dicom文件时将对应的分类图片叠加上去,以此来展示分类的结果。

而在这个过程中遇到了一些困难,nii.gz文件是用0-33的数字来标记不同牙齿或部位的,而前端显示应该用不同颜色来标记不同牙齿或部位,为此需要生成一定数量的具有区分度的颜色,为此编写相应程序,生成了33种不同的具有区分度的颜色,并且手动调整了牙槽骨对应的颜色,使得更有区分性和辨识度。

同时在展示的时候为了不对后面的dicom文件进行遮挡,图片需要具有透明度,而刚开始采用的jpg文件,并不支持透明度,为此修改为转化为具有透明度的png格式。

import SimpleITK as sitk
import numpy as np
import os

from PIL import Image


def read_nii(file_path):
    ds = sitk.ReadImage(file_path)  # 读取nii数据的第一个函数sitk.ReadImage
    # print('ds: ', ds)
    data = sitk.GetArrayFromImage(ds)  # 把itk.image转为array
    # print('data: ', data)
    print('shape_of_data', data.shape)
    spacing = ds.GetSpacing()  # 三维数据的间隔
    # print('spacing_of_data', spacing)
    return data


# 从十六进制的颜色得到RGB颜色
def color(value):
    digit = list(map(str, range(10))) + list("ABCDEF")
    if isinstance(value, tuple):
        string = '#'
        for vi in value:
            a1 = vi // 16
            a2 = vi % 16
            string += digit[a1] + digit[a2]
        return string
    elif isinstance(value, str):
        a1 = digit.index(value[1]) * 16 + digit.index(value[2])
        a2 = digit.index(value[3]) * 16 + digit.index(value[4])
        a3 = digit.index(value[5]) * 16 + digit.index(value[6])
        return [a1, a2, a3]


def getRGBColor(colorArray):
    colorMapRGB = []
    for i in range(len(colorArray)):
        colorMapRGB.append(color(colorArray[i]))
    return colorMapRGB

# niiDataArray(读取nii文件获得的三维数组)
# type(需要得到的图片的类型有1:横断面上下切、2矢状面左右切、3冠状面前后切)
# imgId(获得的图片在该面的位置)
def getImgFromNiiDataArray(niiDataArray, type, imgId, colorMap):
    shape = niiDataArray.shape
    if type == 1:
        imgData = np.array(niiDataArray[imgId, :, :])
    elif type == 2:
        imgData = np.array(niiDataArray[:, imgId, :])
    elif type == 3:
        imgData = np.array(niiDataArray[:, :, imgId])

    imgR = np.zeros(imgData.shape)
    imgG = np.zeros(imgData.shape)
    imgB = np.zeros(imgData.shape)
    imgA = np.zeros(imgData.shape)
    for i in range(1, 33):
        imgR[imgData == i] = colorMap[i - 1][0]
        imgG[imgData == i] = colorMap[i - 1][1]
        imgB[imgData == i] = colorMap[i - 1][2]
        imgA[imgData == i] = 255

    r = Image.fromarray(imgR).convert('L')
    g = Image.fromarray(imgG).convert('L')
    b = Image.fromarray(imgB).convert('L')
    a = Image.fromarray(imgA).convert('L')
    image = Image.merge('RGBA', (r, g, b, a))
    return image


# 以png格式输出nii文件中三种视图的所有图片
# 会在target目录下生成三个文件夹(横断面,矢状面,冠状面)
# 里面装了对应得一系列png图片
def exportAllImgByPNG(niiDataArray, targetPath):
    if os.path.exists(os.path.join(targetPath, '横断面')) == False:
        os.mkdir(os.path.join(targetPath, '横断面'))
    if os.path.exists(os.path.join(targetPath, '矢状面')) == False:
        os.mkdir(os.path.join(targetPath, '矢状面'))
    if os.path.exists(os.path.join(targetPath, '冠状面')) == False:
        os.mkdir(os.path.join(targetPath, '冠状面'))

    dataShape = niiDataArray.shape
    #
    for i in range(dataShape[0]):
        imge = getImgFromNiiDataArray(niiDataArray, 1, i, rgbColorMap)
        imge.save(os.path.join(targetPath, '横断面', '_' + str(i) + '.png'))
    for i in range(dataShape[1]):
        imge = getImgFromNiiDataArray(niiDataArray, 2, i, rgbColorMap)
        imge.save(os.path.join(targetPath, '矢状面', '_' + str(i) + '.png'))
    for i in range(dataShape[2]):
        imge = getImgFromNiiDataArray(niiDataArray, 3, i, rgbColorMap)
        imge.save(os.path.join(targetPath, '冠状面', '_' + str(i) + '.png'))


# 33个颜色,分别对应牙槽骨和32颗牙齿的颜色,0为牙槽骨的颜色,1~32为牙齿的颜色
colorMap = ['#00AA00', '#F93408', '#F57A34', '#F7951E', '#F6C238', '#FBE92F', '#E5F827', '#B6F313', '#97F922',
            '#75F72A',
            '#35F80A', '#23FD23', '#1DF645', '#37F57C', '#03FE8C', '#29FEC4', '#36FBE9', '#2CEBFE', '#29C1FA',
            '#048BFB',
            '#1B6CFA', '#153FFE', '#2F2FFD', '#3A10F4', '#610DF4', '#8F0AFD', '#B714F4', '#DE11F3', '#FE30EB',
            '#FD19BF',
            '#FB279B', '#FD1C6E', '#FD0532'
            ]




if __name__ =='__main__':
    rgbColorMap = getRGBColor(colorMap)  # 得到各部位颜色
    # print(rgbColorMap)

    niifile_path = "./lvsili_label_tooth.nii.gz"
    # file_path = "./lvsiling_label_alveolar.nii.gz"

    niiDataArray = read_nii(niifile_path)
    exportAllImgByPNG(niiDataArray, './teethImg')
    # imge = getImgFromNiiDataArray(niiDataArray, 1, 100, rgbColorMap)
    # imge.show()
    # imge.save('./dog.png')


上一篇:python读写nii格式的数据


下一篇:Linux系统下dcm2niix_afni的shell语句报错:Example output filename:‘/1.nii.gz.nii.gz’