LiTS2017数据集里面包含Training Batch 1和Training Batch 2两个文件夹。Training Batch 1文件夹里面有图像,图像的拓展名为.nii。Training Batch 2文件夹里面有标签,标签拓展名为.nii。 请将我的LiTS2017数据集的3D图像变成2D、RGB三通道、的png格式的图像。数据集的3D标签变成2D单通道的png格式标签。 并将其裁剪为单个肝脏区域。同时,移除segmentation部分无肝脏以及肝脏在图中面积占比小于1.5%的切片,对数据集进行增强操作,如旋转、翻转、缩放等,以扩充数据集,提高模型的泛化能力。 LiTS2017数据集的路径为C:\Users\Administrator\Desktop\LiTS2017。 保存路径为C:\Users\Administrator\Desktop\2D-LiTS2017,请帮我创建好对应文件夹,并且将转换好的数据保存到对应的文件夹。
时间: 2024-02-11 22:08:22 浏览: 211
好的,这是一个比较复杂的任务,需要使用到一些第三方库和编程技巧。我会尽力帮您完成,以下是步骤:
1. 导入必要的库
首先,我们需要导入一些必要的库,包括SimpleITK、numpy、os和PIL等库。请确保这些库都已经安装。
```python
import SimpleITK as sitk
import numpy as np
import os
from PIL import Image
```
2. 定义一些辅助函数
然后,我们定义一些辅助函数,包括读取图像和标签、转换图像和标签、裁剪图像和标签、移除无用切片、增强数据等。
```python
# 读取图像和标签
def read_image_and_label(image_path, label_path):
image = sitk.ReadImage(image_path)
label = sitk.ReadImage(label_path)
return image, label
# 将图像和标签转换为numpy数组
def sitk_to_numpy(sitk_image):
return sitk.GetArrayFromImage(sitk_image)
# 将numpy数组转换为PIL图像
def numpy_to_pil(numpy_array):
return Image.fromarray(numpy_array)
# 将3D图像和标签转换为2D图像和标签
def convert_to_2d(image, label):
image_2d = []
label_2d = []
for i in range(image.shape[0]):
image_slice = image[i,:,:]
label_slice = label[i,:,:]
image_2d.append(image_slice)
label_2d.append(label_slice)
return np.array(image_2d), np.array(label_2d)
# 将标签转换为二值图像
def label_to_binary(label):
label[label > 0] = 1
return label
# 裁剪图像和标签,只保留肝脏区域
def crop_to_liver(image, label):
# 计算肝脏区域
mask = label_to_binary(label)
mask = mask.astype(np.uint8)
mask = sitk.GetImageFromArray(mask)
mask = sitk.BinaryFillhole(mask)
mask = sitk.BinaryDilate(mask, 2)
mask = sitk.BinaryErode(mask, 2)
mask = sitk.GetArrayFromImage(mask)
mask = (mask > 0)
index = np.where(mask)
x_min, x_max = index[0].min(), index[0].max()
y_min, y_max = index[1].min(), index[1].max()
z_min, z_max = index[2].min(), index[2].max()
# 裁剪图像和标签
image = image[x_min:x_max+1, y_min:y_max+1, z_min:z_max+1]
label = label[x_min:x_max+1, y_min:y_max+1, z_min:z_max+1]
return image, label
# 移除segmentation部分无肝脏以及肝脏在图中面积占比小于1.5%的切片
def remove_unwanted_slices(image, label):
mask = label_to_binary(label)
mask = mask.astype(np.uint8)
mask = sitk.GetImageFromArray(mask)
# 移除无用切片
for i in range(mask.GetSize()[2]):
if mask[:,:,i].GetSum() == 0:
image[:,:,i] = 0
label[:,:,i] = 0
# 移除肝脏面积占比小于1.5%的切片
for i in range(mask.GetSize()[2]):
if mask[:,:,i].GetSum() > 0:
area = mask[:,:,i].GetSum()
if area < mask.GetNumberOfPixels() * 0.015:
image[:,:,i] = 0
label[:,:,i] = 0
return image, label
# 数据增强
def augment_data(image, label):
# 随机旋转
angle = np.random.randint(-10, 10)
image = sitk.GetImageFromArray(image)
label = sitk.GetImageFromArray(label)
image = sitk.Rotate(image, angle, (0,1), True)
label = sitk.Rotate(label, angle, (0,1), True)
image = sitk.GetArrayFromImage(image)
label = sitk.GetArrayFromImage(label)
# 随机翻转
if np.random.rand() > 0.5:
image = np.flipud(image)
label = np.flipud(label)
if np.random.rand() > 0.5:
image = np.fliplr(image)
label = np.fliplr(label)
# 随机缩放
scale = np.random.uniform(0.8, 1.2)
image = sitk.GetImageFromArray(image)
label = sitk.GetImageFromArray(label)
image = sitk.Scale(image, [scale, scale, 1])
label = sitk.Scale(label, [scale, scale, 1])
image = sitk.GetArrayFromImage(image)
label = sitk.GetArrayFromImage(label)
# 裁剪
image, label = crop_to_liver(image, label)
return image, label
```
3. 处理数据集
现在,我们可以开始处理数据集了。首先,我们创建保存路径。
```python
# 创建保存路径
save_dir = r'C:\Users\Administrator\Desktop\2D-LiTS2017'
if not os.path.exists(save_dir):
os.makedirs(save_dir)
```
然后,我们遍历数据集,并对每个图像和标签进行预处理。我们将3D图像和标签转换为2D图像和标签,并将标签转换为二值图像。然后,我们裁剪图像和标签,只保留肝脏区域,并移除无用切片。最后,我们对图像和标签进行数据增强,并保存到指定路径。
```python
# 遍历数据集
for folder in ['Training Batch 1', 'Training Batch 2']:
image_folder = os.path.join(r'C:\Users\Administrator\Desktop\LiTS2017', folder, 'volume')
label_folder = os.path.join(r'C:\Users\Administrator\Desktop\LiTS2017', folder, 'segmentation')
for file in os.listdir(image_folder):
if file.endswith('.nii'):
# 读取图像和标签
image_path = os.path.join(image_folder, file)
label_path = os.path.join(label_folder, file)
image, label = read_image_and_label(image_path, label_path)
# 将图像和标签转换为numpy数组
image = sitk_to_numpy(image)
label = sitk_to_numpy(label)
# 将3D图像和标签转换为2D图像和标签
image, label = convert_to_2d(image, label)
# 将标签转换为二值图像
label = label_to_binary(label)
# 裁剪图像和标签,只保留肝脏区域
image, label = crop_to_liver(image, label)
# 移除无用切片
image, label = remove_unwanted_slices(image, label)
# 数据增强并保存图像和标签
for i in range(image.shape[0]):
image_slice = image[i,:,:]
label_slice = label[i,:,:]
image_slice, label_slice = augment_data(image_slice, label_slice)
image_pil = numpy_to_pil(image_slice)
image_pil = image_pil.convert('RGB')
label_pil = numpy_to_pil(label_slice)
image_file = os.path.join(save_dir, file.split('.')[0] + '_{:03d}'.format(i) + '.png')
label_file = os.path.join(save_dir, file.split('.')[0] + '_{:03d}'.format(i) + '_label.png')
image_pil.save(image_file)
label_pil.save(label_file)
```
这样,我们就完成了数据集的处理。请注意,这个过程可能需要一些时间,具体时间取决于您的计算机性能以及数据集的大小。
阅读全文