在本地部署时,此处代码报错,发现此处的split的分割情况有一些问题,如下:
通过调试发现,此处由于windows系统原因,路径会以’\\’显示,我将分割符号以’\\’来分割,得到正常运行结果。
数据的特性
我将代码进行调试后,发现img是一个(168,168,81,1)的矩阵,也就是说每个nii图片相当于一个81通道的图片(我不知道这样理解是否正确),每一个通道都对应着不同的特征,baseline是随机选取10个通道来进行特征提取的,虽然是随机提取,但是我觉得这样也会是数据丢失很多。之后用来提取的特征是一些方差,平均值等等。一共提取了10个不同的特征,从这里来看,我觉得提取的特征也比较少,对后续的预测是不理想的。
img的输出信息
<class 'nibabel.nifti1.Nifti1Image'>
data shape (128, 128, 63, 1)
affine:
[[ 2.05940509 0. 0. 128. ]
[ 0. 2.05940509 0. 128. ]
[ 0. 0. 2.42500019 63. ]
[ 0. 0. 0. 1. ]]
metadata:
<class 'nibabel.nifti1.Nifti1Header'> object, endian='>'
sizeof_hdr : 348
data_type : b''
db_name : b'073_S_0909'
extents : 16384
session_error : 0
regular : b'r'
dim_info : 0
dim : [ 4 128 128 63 1 0 0 0]
intent_p1 : 0.0
intent_p2 : 0.0
intent_p3 : 0.0
intent_code : none
datatype : uint16
bitpix : 16
slice_start : 0
pixdim : [1. 2.059405 2.059405 2.4250002 0. 0. 0.
]
vox_offset : 0.0
scl_slope : nan
scl_inter : nan
slice_end : 0
slice_code : unknown
xyzt_units : 2
cal_max : 0.0
cal_min : 0.0
slice_duration : 0.0
toffset : 0.0
glmax : 32767
glmin : 0
descrip : b''
aux_file : b''
qform_code : scanner
sform_code : unknown
quatern_b : 0.0
quatern_c : 0.0
quatern_d : 0.0
qoffset_x : 128.0
qoffset_y : 128.0
qoffset_z : 63.0
srow_x : [0. 0. 0. 0.]
srow_y : [0. 0. 0. 0.]
srow_z : [0. 0. 0. 0.]
intent_name : b''
magic : b'n+1'
每个nii文件的输出
论文资料
论文中提到,脑组织是一个结构复杂、形状不规则的功能组织。脑图像的准确分割为临床手术提供了丰富而有价值的信息。然而,脑组织的医学图像通常容易受到干扰,例如噪声、灰度不均匀、局部体积效应和伪影,同时,由于大脑图像边缘对比度较弱,脑组织结构复杂,给识别和分割带来很大困难。
医学图像数据预处理:
Zheng, Y., Wang, S., Li, Q., and Li, B. (2020). Fringe projection profilometry by conducting deep learning from its digital twin. Opt. Express 28, 36568–36583. doi: 10.1364/oe.410428
使用DNN会使图像产生不理想的效果
模糊处理在处理医学图像发挥了重要作用
数据预处理
将nii转换成png
import numpy as np
import os # 遍历文件夹
import nibabel as nib # nii格式一般都会用到这个包
import imageio # 转换成图像
from PIL import Image
import numpy as np
from PIL import Image
np.set_printoptions(threshold=np.inf)
def nii_to_image(niifile):
return 0
# filepath = r'F:\study\ai\datawhale\cv\process\resamble\imagesTr_resampled' # 读取本代码同个文件夹下所有的nii格式的文件
slice_trans = []
def get_img(filenames,filepath,imgfile):
for f in filenames: # 开始读取nii文件
s = f[-4:]
# print(s)
if s != '.nii':
continue
s1 = f[:-4]
# print(s1)
# imgfile_path = imgfile
# if not os.path.exists(imgfile_path):
# os.mkdir(imgfile_path)
# print("imgfile_path:" + imgfile_path)
img_path = os.path.join(filepath, f)
img = nib.load(img_path) # 读取nii
# print("img:")
# print(img)
print(img.shape)
img_fdata = img.get_fdata()
fname = f.replace('.nii', '') # 去掉nii的后缀名
img_f_path = imgfile
# if not os.path.exists(img_f_path):
# os.mkdir(img_f_path)
# 创建nii对应的图像的文件夹
if not os.path.exists(img_f_path):
os.makedirs(img_f_path) #新建文件夹
#开始转换为图像
if '.gz' in s1:
x, y, z,_ = img.shape
print("img2:")
print(img.shape)
else:
x, y, z,_= img.shape
print("img3:")
print(img.shape)
for i in range(z): # z是图像的序列
if i < 20 or i >40:continue
slice = img_fdata[:, :, i,0] # 选择哪个方向的切片都可以
# 将浮点数数据缩放到0-255的范围
scaled_slice = (slice - np.min(slice)) / (np.max(slice) - np.min(slice)) * 255
# 将浮点数数据转换为无符号8位整数
uint8_slice = np.uint8(scaled_slice)
# 创建灰度图像对象
image = Image.fromarray(uint8_slice, mode='L')
# 保存为PNG格式
if 'Train' in imgfile and int(s1) <= 5:
imgfile2 = imgfile.replace('Train','Val')
if not os.path.exists(imgfile2):
os.makedirs(imgfile2)
image.save(os.path.join(imgfile2, f'{s1}_{i}_mask.png'))
else:
image.save(os.path.join(imgfile, f'{s1}_{i}_mask.png'))
path = r"F:\study\ai\datawhale\cv\brain_data"
filepath_train_mci = os.path.join(path,r'origin_data\Train\MCI') # 读取本代码同个文件夹下所有的nii格式的文件
filepath_train_nc = os.path.join(path,r'origin_data\Train\NC') # 读取本代码同个文件夹下所有的nii格式的文件
filepath_test = os.path.join(path,r'origin_data\Test') # 读取本代码同个文件夹下所有的nii格式的文件
filenames_train_mci = os.listdir(filepath_train_mci)
filenames_train_nc = os.listdir(filepath_train_nc)
filenames_test = os.listdir(filepath_test)
savepath_train_mci = os.path.join(path,r'origin_img\Train\MCI')
savepath_train_nc = os.path.join(path,r'origin_img\Train\NC')
savepath_test = os.path.join(path,r'origin_img\Test')
get_img(filenames_train_mci,filepath_train_mci,savepath_train_mci)
get_img(filenames_train_nc,filepath_train_nc,savepath_train_nc)
get_img(filenames_test,filepath_test,savepath_test)
将png进行切片
import os
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import torchvision.transforms as transforms
def second(img, new_path): # 把第一次裁剪的图片填充为正方形,避免resize时会改变比例
img = np.array(img)
# img = img[5:138,15:230]
print(img.shape)
# 以最长的一边为边长,把短的边补为一样长,做成正方形,避免resize时会改变比例
dowm = img.shape[0]
up = img.shape[1]
max1 = max(dowm, up)
dowm = (max1 - dowm) // 2
up = (max1 - up) // 2
dowm_zuo, dowm_you = dowm, dowm
up_zuo, up_you = up, up
if (max1 - img.shape[0]) % 2 != 0:
dowm_zuo = dowm_zuo + 1
if (max1 - img.shape[1]) % 2 != 0:
up_zuo = up_zuo + 1
matrix_pad = np.pad(img, pad_width=((dowm_zuo, dowm_you), # 向上填充1个维度,向下填充两个维度
(up_zuo, up_you), # 向左填充2个维度,向右填充一个维度
(0, 0)) # 通道数不填充
, mode="constant", # 填充模式
constant_values=(0, 0)) # 第一个维度(就是向上和向左)填充6,第二个维度(向下和向右)填充5
print(matrix_pad.shape)
img = Image.fromarray(matrix_pad)
img.save(new_path)
def first(path, save_path): # 第一次裁剪大脑
i = 0
if not os.path.exists(save_path):
os.makedirs(save_path)
for file in os.listdir(path):
i += 1
file_path = os.path.join(path, file)
new_path = os.path.join(save_path, file)
# if i != 50:
# continue
print(file_path)
img = Image.open(file_path).convert('RGB')
img = np.array(img)
# print(img.shape)
index = np.where(img > 50) # 找出像素值大于50的所以像素值的坐标
# print(index)
x = index[0]
y = index[1]
max_x = max(x)
min_x = min(x)
max_y = max(y)
min_y = min(y)
max_x = max_x + 10
min_x = min_x - 10
max_y = max_y + 10
min_y = min_y - 10
if max_x > img.shape[0]:
max_x = img.shape[0]
if min_x < 0:
min_x = 0
if max_y > img.shape[1]:
max_y = img.shape[1]
if min_y < 0:
min_y = 0
img = Image.fromarray(img[min_x:max_x, min_y:max_y, :])
second(img, new_path)
if __name__ == '__main__':
path = r"F:\study\ai\datawhale\cv\brain_data"
filepath_train_mci = os.path.join(path, r'origin_img\Train\MCI') # 读取本代码同个文件夹下所有的nii格式的文件
filepath_train_nc = os.path.join(path, r'origin_img\Train\NC') # 读取本代码同个文件夹下所有的nii格式的文件
filepath_Val_mci = os.path.join(path, r'origin_img\Val\MCI') # 读取本代码同个文件夹下所有的nii格式的文件
filepath_Val_nc = os.path.join(path, r'origin_img\Val\NC') # 读取本代码同个文件夹下所有的nii格式的文件
filepath_test = os.path.join(path, r'origin_img\Test')
savepath_train_mci = os.path.join(path, r'crop_img\Train\MCI')
savepath_train_nc = os.path.join(path, r'crop_img\Train\NC')
savepath_Val_mci = os.path.join(path, r'crop_img\Val\MCI')
savepath_Val_nc = os.path.join(path, r'crop_img\Val\NC')
savepath_test = os.path.join(path, r'crop_img\Test')
first(filepath_train_mci, savepath_train_mci)
first(filepath_train_nc, savepath_train_nc)
# first(filepath_Val_mci, savepath_Val_mci)
# first(filepath_Val_nc, savepath_Val_nc)
first(filepath_test, savepath_test)