文章目录
- Python读取图像的两种推荐方式
- 使用PIL读取图像
- 使用opencv-python读取图像
- numpy.darray 与 Tensor 相互转换
- PIL.Image 与 numpy.ndarray 相互转换
- PIL.Image 转换成 Tensor
- Tensor 转换成 PIL.Image
- 参考链接
Python读取图像的两种推荐方式
??uint8是无符号八位整型,表示的是区间[0, 255]内的整数。
使用PIL读取图像
1 2 | from PIL import Image img = Image.open('./lena.png') # PIL读入的图像自然就是uint8格式 |
使用opencv-python读取图像
1 2 3 4 5 6 7 | import cv2 from PIL import Image img_cv2_color = cv2.imread('lena.png') # cv2读入的图像默认是uint8格式的numpy.darray img_cv2_gray = cv2.imread('lena.png', 0) # img_cv2_gray.shape (512,512) cv2.imwrite('img_cv2_color.jpg', img_cv2_color) img = Image.fromarray(img_cv2_color) |
??cv2.imread()返回numpy.darray,可直接用Image.fromarray()转换成PIL.Image,读取灰度图像的shape为(H,W),读取彩色图像的shape为(H,W,3)。
??cv2写图像时,输入的灰度图像的shape可以为(H,W)或(H,W,1),输入的彩色图像的shape应该为(H,W,3);
??若要从numpy.ndarray得到PIL.Image,灰度图像的shape必须为(H,W),彩色图像的shape必须为(H,W,3);
numpy.darray 与 Tensor 相互转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | >>> import numpy as np >>> import torch >>> a = np.arange(5) >>> a array([0, 1, 2, 3, 4]) >>> b = torch.from_numpy(a) # numpy.darray 转换成 Tensor >>> b tensor([0, 1, 2, 3, 4], dtype=torch.int32) >>> print(a, '\n', b) [0 1 2 3 4] tensor([0, 1, 2, 3, 4], dtype=torch.int32) >>> c = torch.arange(5) >>> c tensor([0, 1, 2, 3, 4]) >>> d = c.numpy() # Tensor 转换成 numpy.darray >>> d array([0, 1, 2, 3, 4], dtype=int64) >>> e = np.array(c) # Tensor 转换成 numpy.darray >>> e array([0, 1, 2, 3, 4], dtype=int64) >>> print(c, '\n', d, '\n', e) tensor([0, 1, 2, 3, 4]) [0 1 2 3 4] [0 1 2 3 4] |
PIL.Image 与 numpy.ndarray 相互转换
1 2 3 4 5 6 7 8 9 10 11 12 13 | from PIL import Image import numpy as np img_pil = Image.open('./lena.png') # PIL读入的图像自然就是uint8格式 a = np.array(img_pil) # PIL.Image 转换成 numpy.darray # a = np.asarray(img_pil) # PIL.Image 转换成 numpy.darray # 先把numpy.darray转换成np.unit8, 确保像素值取区间[0,255]内的整数 # 灰度图像需保证numpy.shape为(H,W),不能出现channels,可通过执行np.squeeze()剔除channels; # 彩色图象需保证numpy.shape为(H,W,3) a = a.astype(np.uint8) # a.astype('uint8') # a = np.uint8(a) # 再转换成PIL Image形式 img = Image.fromarray(a) # numpy.darray 转换成 PIL.Image |
??若要从numpy.ndarray得到PIL.Image,灰度图像的shape必须为(H,W),彩色图像的shape必须为(H,W,3);
PIL.Image 转换成 Tensor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from PIL import Image import torch import torchvision.transforms as transforms path_img = "./lena.png" # your path to image img_pil = Image.open(path_img).convert('RGB') # 0~255 img_transforms = transforms.Compose([ # transforms.Resize((224, 224)), transforms.ToTensor(), # transforms.Normalize(norm_mean, norm_std), ]) img_tensor = img_transforms(img_pil) # img_tensor.unsqueeze_(0) # CHW --> BCHW # fmap_1 = convlayer1(img_tensor) |
Tensor 转换成 PIL.Image
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # 先把Tensor转换成numpy.darray,再把numpy.darray 转换成 PIL.Image import numpy as np import torch import torchvision.transforms as transforms from PIL import Image from matplotlib import pyplot as plt img_transforms = transforms.Compose([ # transforms.Resize((224, 224)), transforms.ToTensor(), # transforms.Normalize(norm_mean, norm_std), ]) def transform_invert(img_, transform_train): """ 将data 进行反transfrom操作 :param img_: Tensor :param transform_train: torchvision.transforms :return: PIL image """ if 'Normalize' in str(transform_train): norm_transform = list(filter(lambda x: isinstance(x, transforms.Normalize), transform_train.transforms)) mean = torch.tensor(norm_transform[0].mean, dtype=img_.dtype, device=img_.device) std = torch.tensor(norm_transform[0].std, dtype=img_.dtype, device=img_.device) img_.mul_(std[:, None, None]).add_(mean[:, None, None]) # img_ = img_.transpose(0, 2).transpose(0, 1) # C*H*W --> H*W*C img_ = img_.permute(1, 2, 0) # C*H*W --> H*W*C if 'ToTensor' in str(transform_train): img_ = np.array(img_) # 先把Tensor转换成numpy.darray img_ -= np.min(img_) img_ /= np.max(img_) img_ = img_ * 255 # 再把numpy.darray转换成PIL.Image if img_.shape[2] == 3: img_ = Image.fromarray(img_.astype('uint8')).convert('RGB') elif img_.shape[2] == 1: img_ = Image.fromarray(img_.astype('uint8').squeeze()) else: raise Exception("Invalid img shape, expected 1 or 3 in axis 2, but got {}!".format(img_.shape[2]) ) return img_ # img_pil = Image.open('./lena.png').convert('RGB') # 彩色图像 img_pil = Image.open('./lena.png').convert('L') # 灰度图像 # plt.imshow(img_pil) # plt.show() img_tensor = img_transforms(img_pil) img = transform_invert(img_tensor, img_transforms) plt.imshow(img) plt.show() |
参考链接
python、PyTorch图像读取与numpy转换_Python_便纵有千种风情 20180615
python处理图像何时要将图像转化为uint8格式?uint8是什么?用array()方法打开图像后图像是什么格式?20190214
(待阅读) cv2.imshow()和plt.imshow()显示的色差问题_Python_Max 20190308