目录
一,MRI简介
二,MRI数据集获取
三,MRI数据集预处理
四,实现用Keras来构建基于MRI的网络结构
核磁共振成像(英语:Nuclear Magnetic Resonance Imaging,简称NMRI),又称自旋成像(英语:spin imaging),也称磁共振成像(Magnetic Resonance Imaging,简称MRI),台湾又称磁振造影,香港又称磁力共振扫描,是利用核磁共振(nuclear magnetic resonance,简称NMR)原理,依据所释放的能量在物质内部不同结构环境中不同的衰减,通过外加梯度磁场检测所发射出的电磁波,即可得知构成这一物体原子核的位置和种类,据此可以绘制成物体内部的结构图像。
具体关于MRI影像更多方面的介绍,可以查看维基百科上面的具体介绍:核磁共振影像MRI
MRI数据集的获取可以从网络公开数据库ADNI上获取,但是需要进行注册账号,并申请下载,且周期比较长,所以想要获得该数据集的伙伴可以提前注册该账号,并进行下载。具体方法百度即可。
我免费分享自己下载的MRI数据集,链接:https://pan.baidu.com/s/1EvYmJGuMA3HHetTMEJvJxw密码:71f9
MRI数据集的获取得的原始MRI数据集分为Image和Label两部分,分别对各自进行预处理操作。即标签的合并及重命名(原始数据中的Label部分分为左脑R和右脑L,分别是标记的脑部左右海马体,需要将其进行合并成同一个数据并进行第一次整体重命名)、数据的裁剪、数据增广等操作。得的原始MRI数据集分为Image和Label两部分,分别对各自进行预处理操作。即标签的合并及重命名(原始数据中的Label部分分为左脑R和右脑L,分别是标记的脑部左右海马体,需要将其进行合并成同一个数据并进行第一次整体重命名)、数据的裁剪、数据增广等操作。
#!/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()#验证