关于python怎么读取文件,一直没搞清楚,最近使用tensorboard,搞明白了
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
import matplotlib.pyplot as plt
import numpy as np
import cv2
import torch
import torchvision.transforms as transforms
# 使用的图片是著名的蜜蜂蚂蚁数据集,不用多说了
img_path = 'D:/ml/data/hymenoptera/train/ants/9715481_b3cb4114ff.jpg'
我接触过的有主要两种
img_PIL = Image.open(img_path)
print(type(img_PI))
# output:
img_cv2 = cv2.imread(img_path)
print(type(img_cv2)) #
两种方式的区别之一是读取后img的格式不同,PIL读出来的img是PIL格式,cv2读出来的是numpy.ndarry格式。确认一下shape
print(img_cv2.shape)
# output : (333, 500, 3)
使用matplotlib的imshow方法
plt.imshow(img_PIL)
plt.show()
plt.imshow(img_cv2)
plt.show()
结果分别如下:
可见,使用imshow方法都可以显示PIL或numpy.ndarry格式的图片。但是,使用cv2读取的图片有色差
查阅资料python cv2实现改变图像的通道顺序并保存_Jingle-stu的博客-CSDN博客_python 通道顺序,原来cv2按照BGR的通道顺序读取的图像,其他读取图像的方法都是按RGB方式读取图像,如Image.open()
改变图像的颜色通道顺序,有三种方法
# 方法一:分离bgr通道,在进行合并
b, g, r = cv2.split(img)
img1 = cv2.merge([r, g, b])
# 方法二
img2 = img[:, :, (2,1, 0)]
# img2 = img[..., :: -1]
# 方法三 cv2.COLOR_BGR2RGB:表示将bgr图像转成rgb
img3 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
比如下面采用第三种
img_cv2_color = cv2.imread(img_path)
img_cv2_color = cv2.cvtColor(img_cv2_color, cv2.COLOR_BGR2RGB)
plt.imshow(img_cv2_color)
plt.show()
根据一些资料,numpy包的图片是: H * W * C, 而torch包的图片是: C * H * W,于是在使用torch的一些包的时候,要做格式转换,比如tensorboard只能接受CHW的格式
print(img_array.shape) # (333, 500, 3) 不能用于tensorboard
可以使用torch.tensor转换数据格式,但是对于通道问题没什么帮助,不改变通道位置
print(torch.tensor(img_array).shape)
# torch.Size([333, 500, 3])
解决的办法是使用numpy的transpose方法,transpose参数中2指的是将array的第2维数据放到新数据的第0维,以此类推
print(img_array.transpose(2,0,1).shape)
# (3, 333, 500)
甚至可以反复横跳
print(img_array.transpose(2,0,1).transpose(1,2,0).shape)
# (333, 500, 3)
使用该方法,对array和PIL格式都能起作用
tensor_trans = transforms.ToTensor()
img_tensor = tensor_trans(img_PIL)
print(img_tensor.shape)
# torch.Size([3, 333, 500]) 改变通道位置
img_ndarray_trans = tensor_trans(img_array)
print(img_ndarray_trans.shape)
# torch.Size([3, 333, 500]) 改变通道位置
可以使用tensorboard了
writer = SummaryWriter('logs')
writer.add_image('myimage2', img_array.transpose(2,0,1), 2) # 通道需要在第一位
writer.add_image('myimage3', img_tensor, 3)
如果不想使用格式转化,还可以使用以下代码
writer.add_image('myimage', img_array, 1, dataformats='HWC')
具体可以参考add_image的官方解释
Signature:
writer.add_image(
tag,
img_tensor,
global_step=None,
walltime=None,
dataformats='CHW',
)
Docstring:
Add image data to summary.
Note that this requires the ``pillow`` package.
Args:
tag (string): Data identifier
img_tensor (torch.Tensor, numpy.array, or string/blobname): Image data
global_step (int): Global step value to record
walltime (float): Optional override default walltime (time.time())
seconds after epoch of event
dataformats (string): Image data format specification of the form
CHW, HWC, HW, WH, etc.
Shape:
img_tensor: Default is :math:`(3, H, W)`. You can use ``torchvision.utils.make_grid()`` to
convert a batch of tensor into 3xHxW format or call ``add_images`` and let us do the job.
Tensor with :math:`(1, H, W)`, :math:`(H, W)`, :math:`(H, W, 3)` is also suitable as long as
corresponding ``dataformats`` argument is passed, e.g. ``CHW``, ``HWC``, ``HW``.
Examples::
from torch.utils.tensorboard import SummaryWriter
import numpy as np
img = np.zeros((3, 100, 100))
img[0] = np.arange(0, 10000).reshape(100, 100) / 10000
img[1] = 1 - np.arange(0, 10000).reshape(100, 100) / 10000
img_HWC = np.zeros((100, 100, 3))
img_HWC[:, :, 0] = np.arange(0, 10000).reshape(100, 100) / 10000
img_HWC[:, :, 1] = 1 - np.arange(0, 10000).reshape(100, 100) / 10000
writer = SummaryWriter()
writer.add_image('my_image', img, 0)
# If you have non-default dimension setting, set the dataformats argument.
writer.add_image('my_image_HWC', img_HWC, 0, dataformats='HWC')
writer.close()