img1 = np.array(img) img2 = torchvision.transforms.ToTensor()(img1)如何使得img的值与属性不变
时间: 2024-02-19 19:57:46 浏览: 97
可以通过使用`torchvision.transforms.Normalize`函数来将图像进行规范化,使得图像的属性不变。
具体操作步骤如下:
1. 定义一个`transforms.Compose`对象,将`ToTensor()`和`Normalize()`函数添加到该对象中。
```
transforms = torchvision.transforms.Compose([torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])])
```
2. 使用定义好的`transforms`对象来对图像进行处理。
```
img1 = np.array(img)
img2 = transforms(img1)
```
这样处理后,图像的值和属性都不会发生改变。其中,`mean`和`std`是在ImageNet数据集上计算得到的均值和标准差。如果你的图像不是基于ImageNet数据集训练的,可以使用其他数据集的均值和标准差来进行规范化。
相关问题
img1 = np.array(img) img2 = torchvision.transforms.ToTensor()(img1) apply(img2, torchvision.transforms.RandomErasing(p=0.9, scale=(0.02, 0.33), ratio=(0.3, 3.3), value='random'),"zg10_") 如何使得img的属性不变
由于 `img2` 是通过 `ToTensor()` 转换得到的,因此它已经不再是 `PIL.Image` 类型的数据,而是 `torch.Tensor` 类型的数据。如果要保留原始图像 `img` 的属性,可以在 `apply` 函数内部对 `img` 进行备份,并在函数返回时将备份更新为变换后的图像,如下所示:
```
def apply(img, transform, prefix):
img_copy = img.copy() # 备份原始图像
img_tensor = torchvision.transforms.ToTensor()(img_copy) # 将图像转换为 Tensor
transformed_tensor = transform(img_tensor) # 对 Tensor 进行变换
transformed_img = torchvision.transforms.ToPILImage()(transformed_tensor) # 将 Tensor 转换为 PIL.Image
# 对变换后的图像进行处理,如保存、显示等
# ...
img_copy = transformed_img.copy() # 更新备份为变换后的图像
return transformed_img
```
这样就能保留原始图像的属性,并且在变换后得到变换后的图像。
import torch import torch.nn as nn import torch.nn.functional as F import torchvision.transforms as transforms import skimage.segmentation as seg import numpy as np # 超参数 from PIL import Image num_superpixels = 1000 compactness = 10 sigma = 1 # 定义模型 class SuperpixelSegmentation(nn.Module): def init(self): super(SuperpixelSegmentation, self).init() self.convs = nn.Sequential( nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(64, num_superpixels, kernel_size=1, stride=1) ) def forward(self, x): x = self.convs(x) return x # 加载图像 imgA = Image.open('1.png').convert('RGB') imgB = Image.open('2.jpg').convert('RGB') # 超像素分割 imgA_np = np.array(imgA) segments = seg.slic(imgA_np, n_segments=num_superpixels, compactness=compactness, sigma=sigma) segments = torch.from_numpy(segments).unsqueeze(0).unsqueeze(0).float() segments = F.interpolate(segments, size=(imgA.height, imgA.width), mode='nearest').long() # 应用超像素块范围到图像B imgB_np = np.array(imgB) for i in range(num_superpixels): mask = (segments == i) imgB_np[mask.expand(3, -1, -1)] = np.mean(imgB_np[mask.expand(3, -1, -1)], axis=1, keepdims=True) # 显示超像素分割图像 imgA_segments = np.zeros_like(imgA_np) for i in range(num_superpixels): mask = (segments == i) imgA_segments[mask.expand(3, -1, -1)] = np.random.randint(0, 255, size=(3,)) imgA_segments = Image.fromarray(imgA_segments.astype(np.uint8)) imgB_segments = Image.fromarray(imgB_np) # 显示图像 transforms.ToPILImage()(imgA).show() transforms.ToPILImage()(imgB).show() imgA_segments.show() imgB_segments.show()上述代码出现错误:RuntimeError: expand(CPUBoolType{[1, 1, 512, 512]}, size=[3, -1, -1]): the number of sizes provided (3) must be greater or equal to the number of dimensions in the tensor (4)
这个错误出现的原因是在这行代码中:
```
imgB_np[mask.expand(3, -1, -1)] = np.mean(imgB_np[mask.expand(3, -1, -1)], axis=1, keepdims=True)
```
`mask.expand(3, -1, -1)`的输出的维度是 `[3, 1, 512, 512]`,但是`imgB_np`的维度是 `[512, 512, 3]`,所以二者无法进行广播操作。你需要将`imgB_np`的维度改为`[3, 512, 512]`,然后再进行操作。修改的代码如下所示:
```
imgB_np = np.transpose(imgB_np, (2, 0, 1))
for i in range(num_superpixels):
mask = (segments == i)
imgB_np[:, mask] = np.mean(imgB_np[:, mask], axis=1, keepdims=True)
imgB_np = np.transpose(imgB_np, (1, 2, 0))
```
这里我们先对`imgB_np`进行了转置操作,将通道维度放在最前面,reshape成了`[3, 512, 512]`的维度,然后进行超像素块的操作,最后再将维度转置回来,得到了`[512, 512, 3]`的维度。
阅读全文