SimpleITK模块以多种语言为 ITK 提供简化的接口,支持Python、R、Java、C#、Lua、Ruby、TCL 和 C++ 中的开源多维图像分析,由 Insight Toolkit 社区为生物医学科学及其他领域开发。
官方文档链接:https://simpleitk.org/#

在实际使用中,医学影像标注nii.gz文件的读取与保存用它比较方便。

nii.gz文件的读取

import SimpleITK as sitk
import skimage.io as io

def read_img(path):
    img = sitk.ReadImage(path)
    data = sitk.GetArrayFromImage(img) 
    # print(data.shape)
    return data

nii.gz文件保存为标注json文件

import os
import numpy as np
import cv2
import SimpleITK as sitk 
import json

def read_img(path): # 读取nii.gz文件
    img = sitk.ReadImage(path)
    data = sitk.GetArrayFromImage(img)
    # print(data.shape)
    return data

def save_json(save_path, dict_name): # 存为json文件
    jsonData = json.dumps(dict_name)
    with open(save_path,'w') as jsonf:
        jsonf.write(jsonData)

def copy_ (back, img, size): # 标注之外的地方作为背景类
    # print(type(img), img.shape)
    for i in range(size[0]):
        for j in range(size[1]):
            if img[i][j] > 0:
                back[i][j] = 0
    return back

def resize_ann(img, size): # 将图像转换到需要的尺寸
    path = 'mid_path.jpg' # 中间文件,先保存再以灰度图模式读取
    cv2.imwrite(path, img)
    # print(path,size)
    original_img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
    # print(original_img.shape)
    resize_img = cv2.resize(original_img, size, cv2.INTER_NEAREST)
    # print(resize_img.shape)
    # cv.imwrite('save_path.jpg', resize_img)
    return resize_img


def save_ann(path1, path2):

    # 例如有两种标注,分别存在path1和path2,且含有多层
    img_arr1 = read_img(path1)
    img_arr2 = read_img(path2)

    x=0 
    img_arr_size = img_arr1.shape
    # print(img_arr.shape)    

    # 读取niigz
    for i in range(img_arr1.shape[0]):

        img_need1 = img_arr1[i,:,:] 
        img_need2 = img_arr2[i,:,:] 

        # 检查是否需要转置
        # img_need = img_need.T   
        # print(img_need)
        # 检查标注值
        # print(np.max(img_need))

        # 统一尺寸大小为(512,512)
        resize_size = (512,512)
        if np.max(img_need1) == 0:
            im_0 = np.zeros((512,512), dtype="uint8")
        else:
            # 如果尺寸不一需要转换
            im_0 = resize_ann(img_need1, resize_size)
            im_0[im_0>1]=1

        if np.max(img_need2) == 0:
            im_1 = np.zeros((512,512), dtype="uint8")
        else:
            im_1 = resize_ann(img_need2, resize_size)
            im_1[im_1>1]=1

        back = np.ones((512,512), dtype="uint8")
        back = copy_(back, im_0, resize_size)
        back = copy_(back, im_1, resize_size)
            
        im_0 = im_0.tolist()
        im_1 = im_1.tolist()
        back = back.tolist()

        imglist = []
        for x in [im_0, im_1, back]:
            imglist.append(x)

        if not os.path.exists(path_ann):    #  如果不存在就创建文件夹
            os.mkdir(path_ann)

        path_ann = 'save_path' + 'save_name'

        save_json(path_ann, imglist)

分割结果保存为nii.gz文件

import os
import numpy as np
import cv2
import SimpleITK as sitk 
import json

def save_niigz(save_path, save_pred):

    # 如果有标注可能需要继承相关参数,包括图像尺寸等
    img = sitk.ReadImage('ann_path')

    # 获取标注数组
    # nii_img = sitk.GetArrayFromImage(img)

    # 从标注获取相关参数
    origin = img.GetOrigin() #order: x, y, z
    type = img.GetOrigin() #order: x, y, z
    spacing = img.GetSpacing() #order:x, y, z
    direction = img.GetDirection()
    size = img.GetSize()
    size = (size[0], size[1])
    # print(size)

    # 修改数据类型,例如分类信息用sitkLabel
    pixelType = sitk.sitkLabelUInt8
    out = sitk.Image(size,pixelType)

    res = []
    for i in range(len(save_res)):
        # 保证每一层的尺寸统一
        res.append(resize_ann(save_pred[i], size, ))

    out = sitk.GetImageFromArray(res) 
    out.SetDirection(direction)
    out.SetSpacing(spacing)
    out.SetOrigin(origin)
    # 直接输出可以查看参数信息
    # print(out)
    
    sitk.WriteImage(out, save_path)

关于数据类型的问题可以查阅
文档说明1
文档说明2

其他操作参考以下笔记:
http://www.360doc.com/content/20/1128/18/460_948421999.shtml

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/camilia/p/16697344.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!