1. 加载图像和标签 (transforms.LoadImaged):
- LoadImaged(keys=["image", "label"]) 用于加载图像和标签文件。这里的 keys 表示字典的键名,图像和标签将作为键值对加载。
2. 添加通道维度 (transforms.AddChanneld):
- AddChanneld(keys=["image", "label"]) 为图像和标签添加一个通道维度。对于单通道图像(如灰度图像),这将添加一个额外的维度。
3. 调整图像方向 (transforms.Orientationd):
- Orientationd(keys=["image", "label"], axcodes="RAS") 将图像和标签的方向调整为 RAS(右-前-上)标准。这是医学图像处理中常用的方向标准。
4. 调整图像分辨率 (transforms.Spacingd):
- Spacingd(keys=["image", "label"], pixdim=(args.space_x, args.space_y, args.space_z), mode=("bilinear", "nearest")) 根据给定的体素尺寸 (pixdim) 调整图像和标签的空间分辨率。
- mode 参数指定插值方法,图像使用双线性插值(bilinear),标签使用最近邻插值(nearest)。
5. 缩放图像强度 (transforms.ScaleIntensityRanged):
- ScaleIntensityRanged(keys=["image"], a_min=args.a_min, a_max=args.a_max, b_min=args.b_min, b_max=args.b_max, clip=True) 将图像的强度值缩放到指定范围内。
- a_min 和 a_max 是输入强度值的范围,b_min 和 b_max 是输出强度值的范围,clip=True 表示截断超出范围的值。
6. 裁剪前景区域 (transforms.CropForegroundd):
- CropForegroundd(keys=["image", "label"], source_key="image") 根据图像的前景区域裁剪图像和标签,以去除背景区域。
7. 随机正负样本裁剪 (transforms.RandCropByPosNegLabeld):
- RandCropByPosNegLabeld(keys=["image", "label"], label_key="label", spatial_size=(args.roi_x, args.roi_y, args.roi_z), pos=1, neg=1, num_samples=4, image_key="image", image_threshold=0) 从正样本和负样本中随机裁剪图像和标签。
- spatial_size 指定裁剪的空间大小,pos 和 neg 表示正负样本的比例,num_samples 表示裁剪的样本数。
8. 随机翻转图像 (transforms.RandFlipd):
- RandFlipd(keys=["image", "label"], prob=args.RandFlipd_prob, spatial_axis=0) 随机沿指定轴翻转图像和标签。
- 这里分别沿 0 轴、1 轴和 2 轴进行随机翻转,概率由 args.RandFlipd_prob 指定。
9. 随机旋转图像 (transforms.RandRotate90d):
- RandRotate90d(keys=["image", "label"], prob=args.RandRotate90d_prob, max_k=3) 随机旋转图像和标签 90 度,最多旋转 3 次,概率由 args.RandRotate90d_prob 指定。
10. 随机缩放图像强度 (transforms.RandScaleIntensityd):
- RandScaleIntensityd(keys="image", factors=0.1, prob=args.RandScaleIntensityd_prob) 随机缩放图像的强度值,缩放因子由 factors 指定,概率由 args.RandScaleIntensityd_prob 指定。
11. 随机平移图像强度 (transforms.RandShiftIntensityd):
- RandShiftIntensityd(keys="image", offsets=0.1, prob=args.RandShiftIntensityd_prob) 随机平移图像的强度值,平移量由 offsets 指定,概率由 args.RandShiftIntensityd_prob 指定。
12. 转换为张量 (transforms.ToTensord):
- ToTensord(keys=["image", "label"]) 将图像和标签转换为 PyTorch 张量,以便在训练中使用。
代码示例
假设我们有以下三维图像和标签:
- 图像:一个形状为
(64, 64, 64)
的 numpy 数组 - 标签:一个形状为
(64, 64, 64)
的 numpy 数组
import numpy as np
import matplotlib.pyplot as plt
from monai.transforms import (
Compose, LoadImaged, AddChanneld, Orientationd, Spacingd,
ScaleIntensityRanged, CropForegroundd, RandCropByPosNegLabeld,
RandFlipd, RandRotate90d, RandScaleIntensityd, RandShiftIntensityd,
ToTensord
)
from monai.data import Dataset, DataLoader
# 创建示例图像和标签
image = np.random.rand(64, 64, 64)
label = (np.random.rand(64, 64, 64) > 0.5).astype(np.int)
# 保存为字典形式
data = [{"image": image, "label": label}]
# 定义预处理和数据增强流水线
train_transform = Compose(
[
LoadImaged(keys=["image", "label"]),
AddChanneld(keys=["image", "label"]),
Orientationd(keys=["image", "label"], axcodes="RAS"),
Spacingd(
keys=["image", "label"], pixdim=(1.0, 1.0, 1.0), mode=("bilinear", "nearest")
),
ScaleIntensityRanged(
keys=["image"], a_min=0.0, a_max=1.0, b_min=0.0, b_max=1.0, clip=True
),
CropForegroundd(keys=["image", "label"], source_key="image"),
RandCropByPosNegLabeld(
keys=["image", "label"],
label_key="label",
spatial_size=(32, 32, 32),
pos=1,
neg=1,
num_samples=4,
image_key="image",
image_threshold=0,
),
RandFlipd(keys=["image", "label"], prob=0.5, spatial_axis=0),
RandFlipd(keys=["image", "label"], prob=0.5, spatial_axis=1),
RandFlipd(keys=["image", "label"], prob=0.5, spatial_axis=2),
RandRotate90d(keys=["image", "label"], prob=0.5, max_k=3),
RandScaleIntensityd(keys="image", factors=0.1, prob=0.5),
RandShiftIntensityd(keys="image", offsets=0.1, prob=0.5),
ToTensord(keys=["image", "label"]),
]
)
# 创建数据集和数据加载器
dataset = Dataset(data, transform=train_transform)
dataloader = DataLoader(dataset, batch_size=1)
# 获取预处理后的数据
batch = next(iter(dataloader))
image_transformed = batch["image"][0].numpy()
label_transformed = batch["label"][0].numpy()
# 显示预处理后的图像和标签的切片
def show_slices(image, label, slice_idx):
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].imshow(image[:, :, slice_idx], cmap="gray")
axes[0].set_title("Transformed Image Slice")
axes[1].imshow(label[:, :, slice_idx], cmap="gray")
axes[1].set_title("Transformed Label Slice")
plt.show()
show_slices(image_transformed, label_transformed, slice_idx=32)