LiTS2017数据集里面包含Training Batch 1和Training Batch 2两个文件夹。Training Batch 1文件夹里面有图像,图像的拓展名为.nii。Training Batch 2文件夹里面有标签,标签拓展名为.nii。 请将我的LiTS2017数据集的3D图像变成2D、RGB三通道、的png格式的图像。数据集的3D标签变成2D单通道的png格式标签。 并将其裁剪为单个肝脏区域。同时,移除标签中无肝脏的图片以及肝脏在图片中面积占比小于2%的切片,对数据集进行增强操作,如旋转、翻转、缩放等,以扩充数据集,提高模型的泛化能力。 LiTS2017数据集的路径为C:\Users\Administrator\Desktop\LiTS2017。 保存路径为C:\Users\Administrator\Desktop\2D-LiTS2017,请帮我创建好对应文件夹,并且将转换好的数据保存到对应的文件夹。
时间: 2024-02-11 14:08:33 浏览: 120
好的,我明白了您的要求。为了执行这个任务我们需要使用Python的一些库,包括SimpleITK、numpy、PIL等。请确保您已经安装了这些库。
首先,我们需要创建一个Python文件并导入所需的库:
```python
import os
import numpy as np
import SimpleITK as sitk
from PIL import Image
```
然后,我们需要定义一些函数来执行不同的任务。
### 1. 将3D图像转换为2D RGB图像
```python
def convert_img_to_png(img_path):
img = sitk.ReadImage(img_path)
img_array = np.transpose(sitk.GetArrayFromImage(img), (1, 2, 0))
img_array = (img_array / np.max(img_array)) * 255
img_array = img_array.astype(np.uint8)
img_array = np.expand_dims(img_array, axis=-1)
img_array = np.concatenate([img_array] * 3, axis=-1)
img_slices = img_array.shape[2]
for i in range(img_slices):
img_slice = img_array[:, :, i, :]
img = Image.fromarray(img_slice)
img.save(os.path.join(output_path, f"{os.path.basename(img_path).split('.')[0]}_{i}.png"))
```
这个函数将读取3D图像文件,将其转换为2D RGB图像,然后将每个2D图像保存为PNG文件。请注意,我们需要将图像归一化并扩展为RGB通道。
### 2. 将3D标签转换为2D单通道图像
```python
def convert_label_to_png(label_path):
label = sitk.ReadImage(label_path)
label_array = np.transpose(sitk.GetArrayFromImage(label), (1, 2, 0))
label_array[label_array > 0] = 1
label_slices = label_array.shape[2]
for i in range(label_slices):
label_slice = label_array[:, :, i]
img = Image.fromarray(label_slice)
img.save(os.path.join(output_path, f"{os.path.basename(label_path).split('.')[0]}_{i}.png"))
```
这个函数将读取3D标签文件,将其转换为2D单通道图像,然后将每个2D图像保存为PNG文件。请注意,我们需要将标签图像二值化。
### 3. 裁剪图像并移除无肝脏的图片
```python
def crop_and_remove_empty(img_path, label_path):
img = sitk.ReadImage(img_path)
label = sitk.ReadImage(label_path)
img_array = sitk.GetArrayFromImage(img)
label_array = sitk.GetArrayFromImage(label)
img_array[label_array == 0] = 0
nonzero = np.nonzero(img_array)
x_min, x_max = np.min(nonzero[0]), np.max(nonzero[0])
y_min, y_max = np.min(nonzero[1]), np.max(nonzero[1])
z_min, z_max = np.min(nonzero[2]), np.max(nonzero[2])
img_array = img_array[x_min:x_max + 1, y_min:y_max + 1, z_min:z_max + 1]
label_array = label_array[x_min:x_max + 1, y_min:y_max + 1, z_min:z_max + 1]
img_slices = img_array.shape[2]
for i in range(img_slices):
img_slice = img_array[:, :, i]
label_slice = label_array[:, :, i]
img_area = np.sum(img_slice > 0)
liver_area = np.sum(label_slice > 0)
liver_ratio = liver_area / img_area
if img_area == 0 or liver_ratio < 0.02:
continue
img = sitk.GetImageFromArray(img_slice)
label = sitk.GetImageFromArray(label_slice)
img.SetOrigin(img.GetOrigin())
label.SetOrigin(label.GetOrigin())
img.SetSpacing(img.GetSpacing())
label.SetSpacing(label.GetSpacing())
img_name = os.path.join(output_path, f"{os.path.basename(img_path).split('.')[0]}_{i}.nii.gz")
label_name = os.path.join(output_path, f"{os.path.basename(label_path).split('.')[0]}_{i}.nii.gz")
sitk.WriteImage(img, img_name)
sitk.WriteImage(label, label_name)
```
这个函数将读取原始的3D图像和标签文件,将其裁剪为单个肝脏区域,然后移除无肝脏的图片以及肝脏在图片中面积占比小于2%的切片。请注意,我们需要使用SimpleITK库来读取和写入NIFTI文件。
### 4. 数据增强
```python
def augment_data(img_path, label_path):
img = sitk.ReadImage(img_path)
label = sitk.ReadImage(label_path)
img_array = sitk.GetArrayFromImage(img)
label_array = sitk.GetArrayFromImage(label)
img_slices = img_array.shape[2]
for i in range(img_slices):
img_slice = img_array[:, :, i]
label_slice = label_array[:, :, i]
img_flip = np.flip(img_slice, axis=0)
label_flip = np.flip(label_slice, axis=0)
img_rotate = np.rot90(img_slice, k=1, axes=(0, 1))
label_rotate = np.rot90(label_slice, k=1, axes=(0, 1))
img_scale = sitk.GetImageFromArray(img_slice)
img_scale.SetSpacing((img.GetSpacing()[0] * 1.1, img.GetSpacing()[1] * 1.1))
label_scale = sitk.GetImageFromArray(label_slice)
label_scale.SetSpacing((img.GetSpacing()[0] * 1.1, img.GetSpacing()[1] * 1.1))
img_name = os.path.join(output_path, f"{os.path.basename(img_path).split('.')[0]}_{i}")
label_name = os.path.join(output_path, f"{os.path.basename(label_path).split('.')[0]}_{i}")
sitk.WriteImage(sitk.GetImageFromArray(img_flip), f"{img_name}_flip.nii.gz")
sitk.WriteImage(sitk.GetImageFromArray(label_flip), f"{label_name}_flip.nii.gz")
sitk.WriteImage(sitk.GetImageFromArray(img_rotate), f"{img_name}_rotate.nii.gz")
sitk.WriteImage(sitk.GetImageFromArray(label_rotate), f"{label_name}_rotate.nii.gz")
sitk.WriteImage(img_scale, f"{img_name}_scale.nii.gz")
sitk.WriteImage(label_scale, f"{label_name}_scale.nii.gz")
```
这个函数将读取裁剪后的3D图像和标签文件,然后对每个2D切片进行数据增强操作,包括翻转、旋转和缩放。请注意,我们需要使用SimpleITK库来读取和写入NIFTI文件。
最后,我们需要设置输入和输出路径,以及调用上述函数来执行任务。
```python
input_path = r"C:\Users\Administrator\Desktop\LiTS2017"
output_path = r"C:\Users\Administrator\Desktop\2D-LiTS2017"
if not os.path.exists(output_path):
os.makedirs(output_path)
for root, dirs, files in os.walk(os.path.join(input_path, "Training Batch 1")):
for file in files:
if file.endswith(".nii"):
convert_img_to_png(os.path.join(root, file))
for root, dirs, files in os.walk(os.path.join(input_path, "Training Batch 2")):
for file in files:
if file.endswith(".nii"):
convert_label_to_png(os.path.join(root, file))
for root, dirs, files in os.walk(os.path.join(output_path, "Training Batch 1")):
for file in files:
if file.endswith(".nii.gz"):
crop_and_remove_empty(os.path.join(root, file), os.path.join(output_path, "Training Batch 2", file))
for root, dirs, files in os.walk(os.path.join(output_path, "Training Batch 1")):
for file in files:
if file.endswith(".nii.gz"):
augment_data(os.path.join(root, file), os.path.join(output_path, "Training Batch 2", file)))
```
这个脚本将执行上述任务,并将转换后的图像和标签文件保存到指定的输出路径。请注意,这个脚本可能需要一些时间来运行,具体取决于您的计算机性能和数据集大小。
阅读全文