医工互联

 找回密码
 注册[Register]

手机动态码快速登录

手机号快速登录

微信登录

微信扫一扫,快速登录

QQ登录

只需一步,快速开始

查看: 133|回复: 0
收起左侧

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

[复制链接]

  离线 

发表于 2023-2-20 09:55:21 | 显示全部楼层 |阅读模式 <
目录
一,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,如图所示:

1.png

 

2.png

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

  1. #!/usr/bin/env python
  2. #-*- coding:utf-8 -*-
  3. # author:HuaCode
  4. # datetime:19-3-28 下午6:31
  5. # software: PyCharm
  6. import numpy as np
  7. import os
  8. import nibabel as nib
  9. import shutil#该模块用于拷贝文件
  10. path_label = "./test/label/"#原始label目录
  11. path_img = "./test/image/"#原始image目录
  12. label_path = "./test/combine_label/"#合并标签目录
  13. target_path = "./test/rename_image/"#重命名image目录
  14. target_img_path = "./test/data_croped/image/"#裁剪后的image保存目录
  15. target_label_path = "./test/data_croped/label/"#裁剪后的label保存目录
  16. croped_img_path = "./test/data/image/"#裁剪后并重命名的image目录
  17. croped_label_path = "./test/data/label/"#裁剪后并重命名的label目录
  18. #将标签文件的左脑和右脑进行合并,并保存
  19. def Combine_Label():
  20.     if not os.path.exists(label_path):
  21.         os.mkdir(label_path)
  22.     list = os.listdir(path_label)#os.listdir()方法用于返回指定的文件夹包含的文件或文件夹的名字的列表,这个列表以字母顺序,它不包括'.'和'..',即使它在文件夹中
  23.     #print(list)
  24.     list.sort()#list.sort()用于对列表进行排序,如果指定参数,则使用比较函数指定的比较函数
  25.     #print(list)
  26.     #因为前面用list.srot(),所以列表中的文件名会按照从小到大的顺序并按照LR的顺序来依次间隔排列
  27.     #这里的合并原理是:先找到左脑L,赋值给file_L,然后跳出本次循环,再找下一个右脑R,找到之后,再次赋值给file_R,然后通过路径加载该文件,并得到数据部分
  28.     file_L = ""
  29.     n1 = 0
  30.     n2 = 0
  31.     for file in list:#从列表中获得单个图像的名字
  32.         #print(file)
  33.         if file[:file.rfind("_")] not in file_L:#temp_file用于存储左边文件名,并用于后面load调用。
  34.             file_L = file#当文件为左边的文件时,将文件名赋值给file_L
  35.             continue
  36.         else:
  37.             file_R = file#当文件名为右边的文件时,将文件名赋值给file_R
  38.         #加载右脑标签
  39.         rimg = nib.load(path_label + file_R)#加载标签
  40.         #print rimg
  41.         n1 = n1 + 1
  42.         print"加载第" + str(n1) + "个右脑标签"
  43.         img_R = rimg.get_data()  # 获取数据部分
  44.         #print img_R.dtype
  45.         # 加载左脑标签
  46.         limg = nib.load(path_label + file_L)  # 加载标签
  47.         n2 = n2 + 1
  48.         print"加载第" + str(n2) + "个左脑标签"
  49.         img_L = limg.get_data()  # 获取数据部分
  50.         # 两个标签进行合并
  51.         combine_img = img_R + img_L * 2
  52.         combine_img.astype(np.int32)
  53.         nib.save(nib.Nifti1Image(combine_img, rimg.affine), label_path + file[:file.rfind("_")] + ".nii")
  54.     print "合并完成!"
  55. #将源文件按照对应的标签来进行命名,使标签文件和对应的源文件的名称相同
  56. def Rename_Image():
  57.     if not os.path.exists(target_path):
  58.         os.mkdir(target_path)
  59.     list = os.listdir(path_img)#获得源文件的名称
  60.     list.sort()#将源文件的名称进行排序,默认按照升序规则排序
  61.     label_list = os.listdir(label_path)
  62.     label_list.sort()#将标签名称进行排序
  63.     combine_list = zip(list, label_list)#将源文件名和标签名打包成一个元组,并以列表的形式返回
  64.     for (img_name, label_name) in combine_list:#解析每一个元组中的源文件名称和标签名称,从而进行对应重命名
  65.         if label_name[:label_name.rfind("_")] in img_name:#如果发现标签名称存在该源文件名称中,则进行拷贝名称
  66.             #shutil.copyfile(file1,file2)将文件2中的内容用文件1中的内容覆盖,新文件的名称为file2
  67.             shutil.copyfile(path_img+img_name, target_path+label_name)#将img_name中的内容覆盖到重新以label_name命名的新文件中,这就是修改名称后的源文件
  68.             print "done" + img_name
  69.     print "the first rename well!"
  70. #将源文件和标签文件裁剪为(64,64,96)大小后保存
  71. def Croped():
  72.     wrong_list = ["002_S_0938","007_S_1304","016_S_4121","029_S_4279","136_S_0429"]
  73.     if not os.path.exists(target_img_path):
  74.         os.makedirs(target_img_path)#递归的建立输入的路径,即使是上层的路径不存在,它也会建立这个路径
  75.     if not os.path.exists(target_label_path):
  76.         os.makedirs(target_label_path)
  77.     img_list = os.listdir(target_path)#获得重命名标签的源文件
  78.     for i, img in enumerate(img_list):#将源文件名称组合成一个索引序列,同时列出名称和对应的下标,一般用在for循环中
  79.         timg = nib.load(target_path + img)#加载源文件
  80.         image = timg.get_data()#获取源文件的数据部分
  81.         image = image.transpose(2,1,0)#原始数组为三维数组(x,y,z),则原始axis排列为(0,1,2),则transpose()的默认参数为(2,1,0),
  82.                                     # 得到转置后的数组视图,不影响原数组的内容以及大小,这里实际上是x轴和z轴进行了交换
  83.         image = image[::-1,::-1,:]#进行了一个左右翻转
  84.         tlabel = nib.load(label_path + img)#加载标签文件
  85.         label = tlabel.get_data()#获取标签的数据部分
  86.         label = label.transpose(2,1,0)
  87.         label = label[::-1,::-1,:]#此时的label为uint8类型的,需要转换为bool类型再进行操作
  88.         bool_label = label.astype(np.bool)#将label转换成bool类型
  89.         img_shape = label.shape#获得文件的大小
  90.         axis_list = np.where(bool_label)#输出满足条件(即非0)元素的坐标,这里的坐标以元组的形式给出,原数组有三维,所以tuple中有三个数组
  91.         #print axis_list#输出元组,元组中有三个数组,数组用arry数组存储
  92.         center_x = (axis_list[0].max() + axis_list[0].min()) / 2#获得x轴的中间值
  93.         #print center_x
  94.         center_y = (axis_list[1].max() + axis_list[1].min()) / 2#获得y轴的中间值
  95.         #print center_y
  96.         center_z = (axis_list[2].max() + axis_list[2].min()) / 2#获得z轴的中间值
  97.         #print center_z
  98.         centerpoint = [np.array(center_x, np.int32), np.array(center_y, np.int32), np.array(center_z, np.int32)]#用列表来存储三个arry数组,arry数组中有两个参数第一个为x轴的坐标,第二个参数为数据类型dtype
  99.         #print centerpoint
  100.         label_block = label[centerpoint[0] - 32:centerpoint[0] + 32, centerpoint[1] - 32:centerpoint[1] + 32,
  101.                             centerpoint[2] - 48:centerpoint[2] + 48]
  102.         #将标签文件裁剪为(64,64,96)大小
  103.         #print label_block.shape
  104.         image_block = image[centerpoint[0]-32:centerpoint[0]+32,centerpoint[1]-32:centerpoint[1]+32,
  105.                             centerpoint[2]-48:centerpoint[2]+48]
  106.         #将源文件裁剪为(64,64,96)大小
  107.         #print image_block.shape
  108.         block_sum = np.sum(label_block.astype(np.bool))#裁剪后标签中的label中bool值为真的像素个数
  109.         #print "block_sum"
  110.         #print block_sum
  111.         all_sum = np.sum(bool_label)#裁剪前标签中的label中bool值为真的像素个数
  112.         #print "all_sum"
  113.         #print all_sum
  114.         if img[img.find("_") + 1:img.rfind("_")] not in wrong_list:
  115.             if block_sum == all_sum:
  116.                 print img + str(" croped")
  117.                 nib.save(nib.Nifti1Image(image_block, timg.affine), target_img_path+img)
  118.                 nib.save(nib.Nifti1Image(label_block, tlabel.affine), target_label_path+img)
  119.             else:
  120.                 print "bad croped********************"
  121.     print "all croped!"
  122. def Rename_All_Image():
  123.     if not os.path.exists(croped_img_path):
  124.         os.makedirs(croped_img_path)
  125.     if not os.path.exists(croped_label_path):
  126.         os.makedirs(croped_label_path)
  127.     list_img = os.listdir(target_img_path)
  128.     list_label = os.listdir(target_label_path)
  129.     list_img.sort()
  130.     list_label.sort()
  131.     combine_list = zip(list_img, list_label)#将源文件和标签文件打包成一个元组,并以列表的形式返回
  132.     for i, (img, label) in enumerate(combine_list):#将源文件名称组合成一个索引序列,同时列出名称和对应的下标,一般用在for
  133.         if label == img:
  134.             print str(i) + img + label
  135.             image = nib.load(target_img_path + img).get_data()
  136.             label = nib.load(target_label_path + label).get_data()
  137.             nib.save(nib.Nifti1Image(image, np.eye(4)), croped_img_path + str(i) + ".nii")
  138.             nib.save(nib.Nifti1Image(label, np.eye(4)), croped_label_path + str(i) + ".nii")
  139.             print str(i) + "rename well"
  140.         else:
  141.             print "bad rename**************************"
  142.             print "label:" + label
  143.             print "img:" + img
  144.     print "all rename well!"
  145. def Verify_Image():
  146.     if not os.path.exists(target_path):
  147.         os.makedirs(target_path)
  148.     if not os.path.exists(target_img_path):
  149.         os.makedirs(target_img_path)
  150.     data = os.listdir(target_path)
  151.     croped_data = os.listdir(target_img_path)
  152.     data.sort()
  153.     croped_data.sort()
  154.     combine_list = zip(data, croped_data)
  155.     for data1,data2 in combine_list:
  156.         data = nib.load(target_path + data1).get_data()
  157.         croped_data = nib.load(target_img_path + data2).get_data()
  158.         center_x = (data.shape[0]) / 2
  159.         center_y = (data.shape[1]) / 2
  160.         center_z = (data.shape[2]) / 2
  161.         centerpoint = [np.array(center_x, np.int32), np.array(center_y, np.int32), np.array(center_z, np.int32)]
  162.         block_data = data[centerpoint[0] - 32:centerpoint[0] + 32, centerpoint[1] - 32:centerpoint[1] + 32,
  163.                       centerpoint[2] - 48:centerpoint[2] + 48]
  164.         assert(np.any(block_data.shape == croped_data.shape))
  165.     print "asserted successfully!"
  166. if __name__ == '__main__':
  167.     Combine_Label();#合并
  168.     Rename_Image()#重命名
  169.     Croped()#裁剪
  170.     Rename_All_Image()#再次重命名
  171.     Verify_Image()#验证
复制代码
四,实现用Keras来构建基于MRI的网络结构

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

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


来源:https://blog.csdn.net/HuaCode/article/details/89222573
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

提醒:禁止复制他人回复等『恶意灌水』行为,违者重罚!
您需要登录后才可以回帖 登录 | 注册[Register] 手机动态码快速登录 微信登录

本版积分规则

发布主题 快速回复 收藏帖子 返回列表 客服中心 搜索
简体中文 繁體中文 English 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french

QQ|RSS订阅|小黑屋|处罚记录|手机版|联系我们|Archiver|医工互联 |粤ICP备2021178090号 |网站地图

GMT+8, 2024-9-20 05:36 , Processed in 0.284519 second(s), 66 queries .

Powered by Discuz!

Copyright © 2001-2023, Discuz! Team.

快速回复 返回顶部 返回列表