python工具包读取图片及格式转换

关于python怎么读取文件,一直没搞清楚,最近使用tensorboard,搞明白了

1导包和设置图片位置

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'

1.读取文件

我接触过的有主要两种

(1)使用PIL

img_PIL = Image.open(img_path)
print(type(img_PI))  
# output:  

(2)使用opencv

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)

2.图片显示

(1)imshow方法

使用matplotlib的imshow方法

plt.imshow(img_PIL)
plt.show()
plt.imshow(img_cv2)
plt.show()

结果分别如下:

python工具包读取图片及格式转换_第1张图片

 python工具包读取图片及格式转换_第2张图片

可见,使用imshow方法都可以显示PIL或numpy.ndarry格式的图片。但是,使用cv2读取的图片有色差

(2)解决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()

python工具包读取图片及格式转换_第3张图片

 

3.图片的通道位置问题

根据一些资料,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])  

(1)transpose

解决的办法是使用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) 

(2)transforms.ToTensor

使用该方法,对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])  改变通道位置

(3)tensorboard显示图片

可以使用tensorboard了

writer = SummaryWriter('logs')
writer.add_image('myimage2', img_array.transpose(2,0,1), 2)  # 通道需要在第一位
writer.add_image('myimage3', img_tensor, 3)

python工具包读取图片及格式转换_第4张图片

 如果不想使用格式转化,还可以使用以下代码

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()

你可能感兴趣的:(python,深度学习,图像处理)