毕业设计一深度学习之MRI数据集预处理(合并,裁剪以及重命名等操作)

目录

一,MRI简介

二,MRI数据集获取

三,MRI数据集预处理

四,实现用Keras来构建基于MRI的网络结构


一,MRI简介

核磁共振成像(英语:Nuclear Magnetic Resonance Imaging,简称NMRI),又称自旋成像(英语:spin imaging),也称磁共振成像Magnetic Resonance Imaging,简称MRI),台湾又称磁振造影,香港又称磁力共振扫描,是利用核磁共振(nuclear magnetic resonance,简称NMR)原理,依据所释放的能量在物质内部不同结构环境中不同的衰减,通过外加梯度磁场检测所发射出的电磁波,即可得知构成这一物体原子核的位置和种类,据此可以绘制成物体内部的结构图像。

具体关于MRI影像更多方面的介绍,可以查看维基百科上面的具体介绍:核磁共振影像MRI

二,MRI数据集获取

方法一:

MRI数据集的获取可以从网络公开数据库ADNI上获取,但是需要进行注册账号,并申请下载,且周期比较长,所以想要获得该数据集的伙伴可以提前注册该账号,并进行下载。具体方法百度即可。

方法二:

我免费分享自己下载的MRI数据集,链接:https://pan.baidu.com/s/1EvYmJGuMA3HHetTMEJvJxw密码:71f9

三,MRI数据集预处理(主要部分

1,介绍:

MRI数据集的获取得的原始MRI数据集分为Image和Label两部分,分别对各自进行预处理操作。即标签的合并及重命名(原始数据中的Label部分分为左脑R和右脑L,分别是标记的脑部左右海马体,需要将其进行合并成同一个数据并进行第一次整体重命名)、数据的裁剪、数据增广等操作。得的原始MRI数据集分为Image和Label两部分,分别对各自进行预处理操作。即标签的合并及重命名(原始数据中的Label部分分为左脑R和右脑L,分别是标记的脑部左右海马体,需要将其进行合并成同一个数据并进行第一次整体重命名)、数据的裁剪、数据增广等操作。

2,如图所示:

 

3,预处理代码(Python实现)

#!/usr/bin/env python
#-*- coding:utf-8 -*-
# author:HuaCode
# datetime:19-3-28 下午6:31
# software: PyCharm

import numpy as np
import os
import nibabel as nib
import shutil#该模块用于拷贝文件

path_label = "./test/label/"#原始label目录
path_img = "./test/image/"#原始image目录
label_path = "./test/combine_label/"#合并标签目录
target_path = "./test/rename_image/"#重命名image目录
target_img_path = "./test/data_croped/image/"#裁剪后的image保存目录
target_label_path = "./test/data_croped/label/"#裁剪后的label保存目录
croped_img_path = "./test/data/image/"#裁剪后并重命名的image目录
croped_label_path = "./test/data/label/"#裁剪后并重命名的label目录

#将标签文件的左脑和右脑进行合并,并保存
def Combine_Label():
    if not os.path.exists(label_path):
        os.mkdir(label_path)
    list = os.listdir(path_label)#os.listdir()方法用于返回指定的文件夹包含的文件或文件夹的名字的列表,这个列表以字母顺序,它不包括'.'和'..',即使它在文件夹中
    #print(list)
    list.sort()#list.sort()用于对列表进行排序,如果指定参数,则使用比较函数指定的比较函数
    #print(list)
    #因为前面用list.srot(),所以列表中的文件名会按照从小到大的顺序并按照LR的顺序来依次间隔排列
    #这里的合并原理是:先找到左脑L,赋值给file_L,然后跳出本次循环,再找下一个右脑R,找到之后,再次赋值给file_R,然后通过路径加载该文件,并得到数据部分
    file_L = ""
    n1 = 0
    n2 = 0
    for file in list:#从列表中获得单个图像的名字
        #print(file)
        if file[:file.rfind("_")] not in file_L:#temp_file用于存储左边文件名,并用于后面load调用。
            file_L = file#当文件为左边的文件时,将文件名赋值给file_L
            continue
        else:
            file_R = file#当文件名为右边的文件时,将文件名赋值给file_R
        #加载右脑标签
        rimg = nib.load(path_label + file_R)#加载标签
        #print rimg
        n1 = n1 + 1
        print"加载第" + str(n1) + "个右脑标签"
        img_R = rimg.get_data()  # 获取数据部分
        #print img_R.dtype
        # 加载左脑标签
        limg = nib.load(path_label + file_L)  # 加载标签
        n2 = n2 + 1
        print"加载第" + str(n2) + "个左脑标签"
        img_L = limg.get_data()  # 获取数据部分
        # 两个标签进行合并
        combine_img = img_R + img_L * 2
        combine_img.astype(np.int32)
        nib.save(nib.Nifti1Image(combine_img, rimg.affine), label_path + file[:file.rfind("_")] + ".nii")
    print "合并完成!"

#将源文件按照对应的标签来进行命名,使标签文件和对应的源文件的名称相同
def Rename_Image():
    if not os.path.exists(target_path):
        os.mkdir(target_path)
    list = os.listdir(path_img)#获得源文件的名称
    list.sort()#将源文件的名称进行排序,默认按照升序规则排序
    label_list = os.listdir(label_path)
    label_list.sort()#将标签名称进行排序
    combine_list = zip(list, label_list)#将源文件名和标签名打包成一个元组,并以列表的形式返回
    for (img_name, label_name) in combine_list:#解析每一个元组中的源文件名称和标签名称,从而进行对应重命名
        if label_name[:label_name.rfind("_")] in img_name:#如果发现标签名称存在该源文件名称中,则进行拷贝名称
            #shutil.copyfile(file1,file2)将文件2中的内容用文件1中的内容覆盖,新文件的名称为file2
            shutil.copyfile(path_img+img_name, target_path+label_name)#将img_name中的内容覆盖到重新以label_name命名的新文件中,这就是修改名称后的源文件
            print "done" + img_name
    print "the first rename well!"


#将源文件和标签文件裁剪为(64,64,96)大小后保存
def Croped():
    wrong_list = ["002_S_0938","007_S_1304","016_S_4121","029_S_4279","136_S_0429"]
    if not os.path.exists(target_img_path):
        os.makedirs(target_img_path)#递归的建立输入的路径,即使是上层的路径不存在,它也会建立这个路径
    if not os.path.exists(target_label_path):
        os.makedirs(target_label_path)
    img_list = os.listdir(target_path)#获得重命名标签的源文件
    for i, img in enumerate(img_list):#将源文件名称组合成一个索引序列,同时列出名称和对应的下标,一般用在for循环中
        timg = nib.load(target_path + img)#加载源文件
        image = timg.get_data()#获取源文件的数据部分
        image = image.transpose(2,1,0)#原始数组为三维数组(x,y,z),则原始axis排列为(0,1,2),则transpose()的默认参数为(2,1,0),
                                    # 得到转置后的数组视图,不影响原数组的内容以及大小,这里实际上是x轴和z轴进行了交换
        image = image[::-1,::-1,:]#进行了一个左右翻转
        tlabel = nib.load(label_path + img)#加载标签文件
        label = tlabel.get_data()#获取标签的数据部分
        label = label.transpose(2,1,0)
        label = label[::-1,::-1,:]#此时的label为uint8类型的,需要转换为bool类型再进行操作
        bool_label = label.astype(np.bool)#将label转换成bool类型
        img_shape = label.shape#获得文件的大小
        axis_list = np.where(bool_label)#输出满足条件(即非0)元素的坐标,这里的坐标以元组的形式给出,原数组有三维,所以tuple中有三个数组
        #print axis_list#输出元组,元组中有三个数组,数组用arry数组存储

        center_x = (axis_list[0].max() + axis_list[0].min()) / 2#获得x轴的中间值
        #print center_x
        center_y = (axis_list[1].max() + axis_list[1].min()) / 2#获得y轴的中间值
        #print center_y
        center_z = (axis_list[2].max() + axis_list[2].min()) / 2#获得z轴的中间值
        #print center_z
        centerpoint = [np.array(center_x, np.int32), np.array(center_y, np.int32), np.array(center_z, np.int32)]#用列表来存储三个arry数组,arry数组中有两个参数第一个为x轴的坐标,第二个参数为数据类型dtype
        #print centerpoint
        label_block = label[centerpoint[0] - 32:centerpoint[0] + 32, centerpoint[1] - 32:centerpoint[1] + 32,
                            centerpoint[2] - 48:centerpoint[2] + 48]
        #将标签文件裁剪为(64,64,96)大小
        #print label_block.shape
        image_block = image[centerpoint[0]-32:centerpoint[0]+32,centerpoint[1]-32:centerpoint[1]+32,
                            centerpoint[2]-48:centerpoint[2]+48]
        #将源文件裁剪为(64,64,96)大小
        #print image_block.shape
        block_sum = np.sum(label_block.astype(np.bool))#裁剪后标签中的label中bool值为真的像素个数
        #print "block_sum"
        #print block_sum
        all_sum = np.sum(bool_label)#裁剪前标签中的label中bool值为真的像素个数
        #print "all_sum"
        #print all_sum
        if img[img.find("_") + 1:img.rfind("_")] not in wrong_list:
            if block_sum == all_sum:
                print img + str(" croped")
                nib.save(nib.Nifti1Image(image_block, timg.affine), target_img_path+img)
                nib.save(nib.Nifti1Image(label_block, tlabel.affine), target_label_path+img)
            else:
                print "bad croped********************"
    print "all croped!"


def Rename_All_Image():
    if not os.path.exists(croped_img_path):
        os.makedirs(croped_img_path)
    if not os.path.exists(croped_label_path):
        os.makedirs(croped_label_path)
    list_img = os.listdir(target_img_path)
    list_label = os.listdir(target_label_path)
    list_img.sort()
    list_label.sort()
    combine_list = zip(list_img, list_label)#将源文件和标签文件打包成一个元组,并以列表的形式返回
    for i, (img, label) in enumerate(combine_list):#将源文件名称组合成一个索引序列,同时列出名称和对应的下标,一般用在for
        if label == img:
            print str(i) + img + label
            image = nib.load(target_img_path + img).get_data()
            label = nib.load(target_label_path + label).get_data()
            nib.save(nib.Nifti1Image(image, np.eye(4)), croped_img_path + str(i) + ".nii")
            nib.save(nib.Nifti1Image(label, np.eye(4)), croped_label_path + str(i) + ".nii")
            print str(i) + "rename well"
        else:
            print "bad rename**************************"
            print "label:" + label
            print "img:" + img
    print "all rename well!"


def Verify_Image():
    if not os.path.exists(target_path):
        os.makedirs(target_path)
    if not os.path.exists(target_img_path):
        os.makedirs(target_img_path)
    data = os.listdir(target_path)
    croped_data = os.listdir(target_img_path)
    data.sort()
    croped_data.sort()
    combine_list = zip(data, croped_data)
    for data1,data2 in combine_list:
        data = nib.load(target_path + data1).get_data()
        croped_data = nib.load(target_img_path + data2).get_data()
        center_x = (data.shape[0]) / 2
        center_y = (data.shape[1]) / 2
        center_z = (data.shape[2]) / 2
        centerpoint = [np.array(center_x, np.int32), np.array(center_y, np.int32), np.array(center_z, np.int32)]
        block_data = data[centerpoint[0] - 32:centerpoint[0] + 32, centerpoint[1] - 32:centerpoint[1] + 32,
                      centerpoint[2] - 48:centerpoint[2] + 48]
        assert(np.any(block_data.shape == croped_data.shape))
    print "asserted successfully!"


if __name__ == '__main__':
    Combine_Label();#合并
    Rename_Image()#重命名
    Croped()#裁剪
    Rename_All_Image()#再次重命名
    Verify_Image()#验证

四,实现用Keras来构建基于MRI的网络结构

基于MRI网络的构建,这个目前我正在进行,后续会更新基于U-net,Densenet以及二者融合的改版网络结构以及训练的模型,敬请期待……

PS:毕业设计,多多关照!有需要交流的,留下QQ:404125822,可以一起交流^_^

  • 24
    点赞
  • 172
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 29
    评论
MRI图像预处理是进行大脑影像数据处理的关键步骤之一,它有助于提取和分析大脑结构和功能的信息。在MRI图像的预处理中,automask是其中一个非常重要的步骤,用于生成一个脑部区域的掩膜,以去除非脑部组织的干扰。 automask是由DPABI(Data Processing & Analysis of Brain Imaging)软件包提供的一种预处理工具。DPABI是一个基于MATLAB的开源软件包,专门用于大脑影像数据的预处理和分析。automask功能的目标是生成一个二进制掩膜图像,其中只有脑部组织的像素被保留,而非脑部组织的像素则被忽略。 automask预处理过程中,首先会对原始MRI图像进行平滑处理,以减少噪音和增强图像质量。然后,该工具会基于灰度阈值进行二值化处理,将脑部像素的灰度值设为1,非脑部像素的灰度值设为0。这样一来,automask能够将非脑部组织完全排除在脑部掩膜之外。 通过automask生成的脑部掩膜,可以用于大脑结构和功能的进一步分析。脑部掩膜的生成有助于减少分析过程中对非脑部区域的干扰。例如,在功能磁共振成像(fMRI)分析中,将脑部掩膜应用于时间序列数据可以提高信号质量和准确性,从而增强功能连接和活动区域的检测。 总的来说,automask是DPABI软件中的一项关键预处理功能,它利用二值化方法生成一个脑部掩膜,去除非脑部组织的干扰,有助于提高大脑影像数据的质量和准确性,为后续分析提供更可靠的结果。
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HuaCode

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值