在深度学习和计算机视觉中,将图像文件转换为张量(Tensor)是数据预处理的重要步骤。Tensor 是一种多维数组,在 PyTorch 中,用于表示和处理数据。
首先,创建一个5*4的图像文件,放大之后,如下所示:
图像由红RGB(255,0 , 0),绿RGB(0,255 , 0),蓝RGB(0,0 , 255),黑RGB(0,0 , 0),白RGB(255,255 , 255)四种颜色组成,图中的每一个方格是一个像素点。将其命名为demo54.png,并放置在下面的脚本同目录下:
from PIL import Image
# 读取图像文件
image = Image.open('demo54.png') # 打开图像
img_data = image.getdata() # 获取图像数据
data_list = list(img_data) # 创建列表
print(data_list) # 打印图像数据
out_list = [] # 创建空列表
for color in data_list: # 遍历图像数据列表
if color == (0, 0, 0): # 判断像素点是否为黑色
out_list.append('黑')
elif color == (255, 255, 255): # 判断像素点是否为白色
out_list.append('白')
elif color == (255, 0, 0): # 判断像素点是否为红色
out_list.append('红')
elif color == (0, 255, 0): # 判断像素点是否为绿色
out_list.append('绿')
elif color == (0, 0, 255): # 判断像素点是否为蓝色
out_list.append('蓝')
print(out_list) # 打印图像数据
[(255, 0, 0), (0, 0, 0), (255, 0, 0), (0, 0, 0), (255, 0, 0), (0, 0, 0), (0, 255, 0), (0, 0, 0), (0, 255, 0), (0, 0, 0), (0, 0, 255), (0, 0, 0), (0, 0, 255), (0, 0, 0), (0, 0, 255), (0, 0, 0), (255, 255, 255), (0, 0, 0), (255, 255, 255), (0, 0, 0)]
['红', '黑', '红', '黑', '红', '黑', '绿', '黑', '绿', '黑', '蓝', '黑', '蓝', '黑', '蓝', '黑', '白', '黑', '白', '黑']
以上的脚本代码反映了图像的像素特征,可以看到,逐行逐列逐像素输出了图像的RGB像素值。
进一步,按照RGB的颜色通道输出:
from PIL import Image
from torchvision import transforms
# 读取图像文件
image = Image.open('demo54.png')
R_channel = image.getchannel("R")
R_data = R_channel.getdata()
G_channel = image.getchannel("G")
G_data = G_channel.getdata()
B_channel = image.getchannel("B")
B_data = B_channel.getdata()
print(list(R_data))
print(list(G_data))
print(list(B_data))
[255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0] # R通道的数据
[0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0] # G通道的数据
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0] # B通道的数据
现在将图像转换为张量(Tensor):
from PIL import Image
from torchvision import transforms
# 读取图像文件
image = Image.open('demo54.png') # 打开图像
transform = transforms.ToTensor() # 定义Tensor转换
# 应用转换,将图像转换为张量
image_tensor = transform(image)
print(image_tensor.shape) # 输出Tensor的形状
print(image_tensor) # 输出tensor的数值
运行结果和解析:
torch.Size([3, 4, 5]) # Tensor的形状,3是通道数,RGB3个通道;4是行数,图像的像素高度height;5是列数,图像的像素宽度witch
tensor([[[1., 0., 1., 0., 1.], # R通道第1行的逐像素数据
[0., 0., 0., 0., 0.], # R通道第2行的逐像素数据
[0., 0., 0., 0., 0.], # R通道第3行的逐像素数据
[0., 1., 0., 1., 0.]], # R通道第4行的逐像素数据
################################# 以上各行共同组成R通道的张量数据
[[0., 0., 0., 0., 0.], # G通道第1行的逐像素数据
[0., 1., 0., 1., 0.], # G通道第2行的逐像素数据
[0., 0., 0., 0., 0.], # G通道第3行的逐像素数据
[0., 1., 0., 1., 0.]], # G通道第4行的逐像素数据
################################# 以上各行共同组成G通道的张量数据
[[0., 0., 0., 0., 0.], # B通道第1行的逐像素数据
[0., 0., 0., 0., 0.], # B通道第2行的逐像素数据
[1., 0., 1., 0., 1.], # B通道第3行的逐像素数据
[0., 1., 0., 1., 0.]]]) # B通道第4行的逐像素数据
################################# 以上各行共同组成B通道的张量数据
# 由RGB3个通道的张量数据共同组成了整个图像的张量数据
脚本中transforms.ToTensor()的解释:将PIL图像或NumPy数组转换为PyTorch的张量,并将像素值范围从[0, 255]缩放到[0, 1]。实际上,我们把最后得出的每个通道的张量数据与之前打印的分颜色通道输出结果进行比较,也就明白transforms.ToTensor()的含义了。
看得出,这个图像文件的Tensor,由RGB三个通道组成,每个像素点与255的比例值构成了阵列的基本元素。图像的所有行、所有列构成了Tensor的阵列。