为了账号安全,请及时绑定邮箱和手机立即绑定

在 PyTorch 中进行数据增强后得到坏图像

在 PyTorch 中进行数据增强后得到坏图像

幕布斯6054654 2022-11-29 16:59:12
我正在研究一个核分割问题,我试图在染色组织图像中识别细胞核的位置。给定的训练数据集有一张染色组织的图片和一个带有细胞核位置的掩码。由于数据集很小,我想尝试在 PyTorch 中进行数据增强,但在这样做之后,由于某种原因,当我输出我的蒙版图像时,它看起来很好,但相应的组织图像不正确。我所有的训练图像都在X_trainshape(128, 128, 3)中,相应的掩码在Y_trainshape中(128, 128, 1),类似的交叉验证图像和掩码分别在X_val和Y_val中。Y_trainY_val有dtype = np.bool,有。_ X_train_X_valdtype = np.uint8在数据增强之前,我会这样检查我的图像:fig, axis = plt.subplots(2, 2)axis[0][0].imshow(X_train[0].astype(np.uint8))axis[0][1].imshow(np.squeeze(Y_train[0]).astype(np.uint8))axis[1][0].imshow(X_val[0].astype(np.uint8))axis[1][1].imshow(np.squeeze(Y_val[0]).astype(np.uint8))输出如下: Before Data Augmentation对于数据扩充,我定义了一个自定义类,如下所示:在这里我导入torchvision.transforms.functional了TF和torchvision.transforms as transforms。images_np并且masks_np是 numpy 数组的输入。class Nuc_Seg(Dataset):def __init__(self, images_np, masks_np):    self.images_np = images_np    self.masks_np = masks_npdef transform(self, image_np, mask_np):    ToPILImage = transforms.ToPILImage()    image = ToPILImage(image_np)    mask = ToPILImage(mask_np.astype(np.int32))    angle = random.uniform(-10, 10)    width, height = image.size    max_dx = 0.2 * width    max_dy = 0.2 * height    translations = (np.round(random.uniform(-max_dx, max_dx)), np.round(random.uniform(-max_dy, max_dy)))    scale = random.uniform(0.8, 1.2)    shear = random.uniform(-0.5, 0.5)    image = TF.affine(image, angle = angle, translate = translations, scale = scale, shear = shear)    mask = TF.affine(mask, angle = angle, translate = translations, scale = scale, shear = shear)    image = TF.to_tensor(image)    mask = TF.to_tensor(mask)    return image, maskdef __len__(self):    return len(self.images_np)我得到这个作为我的输出: After Data Augmentation 1当我将行更改axis_1.imshow(img.astype(np.uint8))为时axis_1.imshow(img),我得到这张图片: 数据扩充后 2面具的图像是正确的,但由于某种原因,细胞核的图像是错误的。使用 时.astype(np.uint8),组织图像完全是黑色的。没有.astype(np.uint8),核的位置是正确的,但配色方案全乱了(我希望图像像数据增强之前看到的那样,灰色或粉红色),加上网格中同一图像的 9 个副本由于某种原因显示。你能帮我得到组织图像的正确输出吗?
查看完整描述

1 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

您正在将图像转换为 PyTorch 张量,并且在 PyTorch 中图像的大小为[C, H, W]。当您将它们可视化时,您正在将张量转换回 NumPy 数组,其中图像的大小为[H, W, C]。因此,您正在尝试重新排列维度,但您使用的是torch.reshape,它不会交换维度,而只会以不同的方式对数据进行分区。

一个例子使这一点更清楚:

# Incrementing numbers with size 2 x 3 x 3

image = torch.arange(2 * 3 * 3).reshape(2, 3, 3)

# => tensor([[[ 0,  1,  2],

#             [ 3,  4,  5],

#             [ 6,  7,  8]],

#

#            [[ 9, 10, 11],

#             [12, 13, 14],

#             [15, 16, 17]]])


# Reshape keeps the same order of elements but for a different size

# The numbers are still incrementing from left to right

image.reshape(3, 3, 2)

# => tensor([[[ 0,  1],

#             [ 2,  3],

#             [ 4,  5]],

#

#            [[ 6,  7],

#             [ 8,  9],

#             [10, 11]],

#

#            [[12, 13],

#             [14, 15],

#             [16, 17]]])

要重新排序您可以使用的尺寸permute:


# Dimensions are swapped

# Now the numbers increment from top to bottom

image.permute(1, 2, 0)

# => tensor([[[ 0,  9],

#             [ 1, 10],

#             [ 2, 11]],

#

#            [[ 3, 12],

#             [ 4, 13],

#             [ 5, 14]],

#

#            [[ 6, 15],

#             [ 7, 16],

#             [ 8, 17]]])

使用 时.astype(np.uint8),组织图像完全是黑色的。


PyTorch 图像表示为值介于 [0, 1] 之间的浮点数,但 NumPy 使用介于 [0, 255] 之间的整数值。将浮点值转换为np.uint8将导致只有 0 和 1,其中不等于 1 的所有内容都将设置为 0,因此整个图像为黑色。


您需要将这些值乘以 255 以将它们置于 [0, 255] 范围内。


img = img.permute(1, 2, 0) * 255

img = img.numpy().astype(np.uint8)

当您将张量转换为 PIL 图像时,此转换也会自动完成transforms.ToPILImage(或者TF.to_pil_image如果您更喜欢函数式版本,则使用)并且 PIL 图像可以直接转换为 NumPy 数组。这样您就不必担心尺寸、值范围或类型,上面的代码可以替换为:


img = np.array(TF.to_pil_image(img))


查看完整回答
反对 回复 2022-11-29
  • 1 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号