【使用torchvision中的make_grid实现多张图片拼成一张图】
注意:以下代码由Jupyter Notebook 实现
1.首先看看传统的做法
读取4张lena的照片,拼成4*4图片
import cv2
import numpy as np
img1_path = r".\pics\lena.jpg"
img2_path = r".\pics\lena2.jpg"
img3_path = r".\lena3.jpg"
img4_path = r".\lena4.jpg"
img1 = cv2.cvtColor(cv2.imread(img1_path), cv2.COLOR_BGR2RGB)
print(np.shape(img1)) # 或者用img1.shape (h,w,c) (200, 200, 3)
输出:
(200, 200, 3)
# 转成RGB形式
img2 = cv2.cvtColor(cv2.imread(img2_path), cv2.COLOR_BGR2RGB)
img3 = cv2.cvtColor(cv2.imread(img3_path), cv2.COLOR_BGR2RGB)
img4 = cv2.cvtColor(cv2.imread(img4_path), cv2.COLOR_BGR2RGB)
import matplotlib.pyplot as plt
img_tmp1 = np.hstack((img1,img2)) # 拼成一行
print(np.shape(img_tmp1)) # (200, 400, 3)
img_tmp2 = np.hstack((img3,img4))
img_tmp3 = np.vstack((img_tmp1,img_tmp2))
print(np.shape(img_tmp3))
#cv2.imwrite(r".\pics\lenacat.jpg", img_tmp3)
plt.imshow(img_tmp3)
plt.xticks([])
plt.yticks([])
plt.show()
输出:
(200, 400, 3)
(400, 400, 3)
这种做法的缺点是,不能设定图片间隔
2.采用torchvision.utils中的make_grid函数绘制多张图片拼成一张图
读取图片可以采用OpenCV2或者PIL,再合并图片矩阵,输出(照片数,通道,高,宽)的tensor张量
import cv2
import os
import matplotlib.pyplot as plt
import torch
from torchvision.utils import save_image,make_grid
import numpy as np
import torchvision
from PIL import Image
#获取图片路径
pic_dir = r"D:\AlgorithmFile\PythonDaily\PytorchDaily\TorchBasic\pics"
# 路径使用'/'间隔符号,路径的读取前面不用加r
images = []
for filename in os.listdir(pic_dir):
print(filename) # 显示文件名
# opencv和PIL二选一
# img = cv2.imread(pic_dir+ "/" + filename) # 使用cv直接读成numpy矩阵
# print(type(img)) # <class 'numpy.ndarray'>
# img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) # (宽,高,通道)
img = Image.open(pic_dir+ "/" + filename) # 使用PIL需要转成numpy矩阵 参考:http://t.csdn.cn/rwF6Q
print(type(img)) # <class 'PIL.JpegImagePlugin.JpegImageFile'>
img = np.array(img)
img = img.transpose(2,0,1) # (宽,高,通道)转成#(通道,宽,高)
images.append(img)
images = torch.tensor(images) #转成tensor张量,注意千万别写成Tensor,原因参考:http://t.csdn.cn/XN0mF
print(images.size())
输出:
lena.jpg
lena2.jpg
lena3.jpg
lena4.jpg
torch.Size([4, 3, 200, 200])
使用make_grid函数将(照片数,通道,高,宽)的tensor张量输出一张图片的tensor张量
image_batch = make_grid(images, nrow= 2, padding=5, pad_value=255)
print(image_batch.size())
image_batch = np.array(image_batch).transpose(1,2,0)
plt.imshow(image_batch)
plt.xticks([]) # 去掉横坐标值
plt.yticks([]) # 去掉纵坐标值
'''
def make_grid(
tensor: Union[torch.Tensor, List[torch.Tensor]],
nrow: int = 8,
padding: int = 2,
normalize: bool = False,
range: Optional[Tuple[int, int]] = None,
scale_each: bool = False,
pad_value: int = 0,
)
'''
'''
tensor:4D张量,形状为(B x C x H x W),分别表示样本数,通道数,图像高度,图像宽度。或者是一个图像列表
nrow:每行的图片数量,默认值为8
padding:相邻图像之间的间隔。默认值为2,图片间隔
normalize:如果为True,则把图像的像素值通过range指定的最大值和最小值归一化到0-1。默认为False
range:元组,用于指定最大值和最小值。默认使用图像像素的最大最小值。
sacle_each:如果为True,就单独对每张图像进行normalize;如果是False,统一对所有图像进行normalize。默认为Flase
pad_value:float,上述padding会使得图像之间留出空隙,默认为0。表示0-255之间的颜色
参考:https://blog.csdn.net/qq7835144/article/details/108523997
'''
输出:
torch.Size([3, 415, 415])