图片类型转换 | 字数总计: 1.2k | 阅读时长: 4分钟 | 阅读量: |
前言 在计算机视觉任务中,大多数时候都涉及到图片的加载、训练以及训练结果的可视化 。在实操过程中,经常会遇到图片各种类型之间的转换问题
三种类型PIL、tensor、numpy,一种显示plt
图片的读入 通常是有两种读入方式,分别是用PIL中的Image读入和用openCV读入。PIL(Python Imaging Library)是Python中最基础的图像处理库,OpenCV是一个很强大的图像处理库,适用面更广。两种读入方式是有区别的,主要有以下几个区别
图片格式不同,Image读入的是“RGB”,Opencv读入的是“BGR”。
读入图片的尺寸不同,Image读入的是 w h ,Opencv读入的是h w c 。其中w是宽,h是高,c是通道数。
Image读入是Image类无法直接显示其像素点的值(可以转换成numpy显示),Opencv读入的直接是numpy的格式。可以直接显示其像素值。
代码演示 1 2 3 4 5 6 7 8 9 10 11 12 13 import os.pathfrom PIL import Imageimport cv2import numpy as npimport matplotlib.pyplot as pltimport torchvision.transforms as standard_transformsimage = Image.open ("1.jpg" ).convert("RGB" ) image2 = cv2.imread("1.jpg" ) print ("Image read" ,image.size) print ("Opencv read" ,image2.shape) print (image)print (image2)
图片的转换 在视觉任务中加载图片通常要将其变为tensor,才能参与训练。下面将描述如何将读入的图片变成tensor,或者将tensor转成能够直接显示的图片格式(tensor类型的图片是无法直接可视化 的)
PIL与tensor的相互转换 PIL和tensor的相互转换,要利用torchision中transforms中的一些类。PIL转tensor用里面的ToTensor 转PIL用里面的ToPILImage 类(这个类也可以将numpy格式的转为PIL)。
1 2 transform1 = standard_transforms.ToTensor() transform2 = standard_transforms.ToPILImage()
将上一节中的image转为tensor。要注意的是转为tensor后图片中像素点的方式也发生了变化,会将 w,h,c变为c,h,w ,并且像素值由[0,255]变成了[0,1]。另外通常对于tensor要变为(n,c,h,w),这时候要用到 unsqueeze(x) 是增加一维 , squeeze(x) 去掉维度为1的维度 。其中x是对dim=x的进行增或者减
1 2 3 4 5 6 7 8 9 10 image = Image.open ("1.jpg" ).convert("RGB" ) image2 = cv2.imread("1.jpg" ) image_tensor = transform1(image) image_recover = transform2(image_tensor) image_tensor_add = image_tensor.unsqueeze(0 ) print ("Image read" ,image.size) print ("Opencv read" ,image2.shape) print ("tensor" ,image_tensor.size()) print ("tensor recover to Image" ,image_recover.size)print ("tensor add " ,image_tensor_add.size())
numpy与tensor的相互转换 numpy转tensor 一种是直接利用torchvision.transform里的ToTensor直接转换。一种是用torch.from_numpy()转换,但是这种方法需要注意一下numpy的数据排列要将(h,w,c)变为(c,h,w)。并且还要将像素点的值变为[0,1]。
1 2 3 4 5 6 7 8 image_tensor_form_numpy = transform1(image2) print ("image_tensor_form_numpy: " ,image_tensor_form_numpy.shape)image_tensor_from_numpy2 = cv2.cvtColor(image2,cv2.COLOR_BGR2RGB) image_tensor_from_numpy2 = torch.from_numpy(image_tensor_from_numpy2.transpose((2 , 0 , 1 ))) image_tensor_from_numpy2 = image_tensor_from_numpy2.float ().div(255 ) print ("image_tensor_from_numpy2 :" ,image_tensor_from_numpy2.size())
tensor转numpy 先将tensor中的所有像素点的值乘 255,回到之前的状态。利用np.array(),将tensor变为numpy,并进行形状的变化。再将其变回原来的BGR格式
1 2 3 4 image_numpy_form_tensor = image_tensor.mul(255 ).byte() image_numpy_form_tensor = np.array(image_numpy_form_tensor).transpose(1 ,2 ,0 ) image_numpy_form_tensor = cv2.cvtColor(image_numpy_form_tensor,cv2.COLOR_RGB2BGR) print ("image_numpy_form_tensor: " ,image_numpy_form_tensor.shape)
numpy与PIL的相互转换 PIL转numpy PIL转numpy直接利用np.array(),就可以将PIL变成numpy,并且数据格式也自动变为(h,w,c) , 然后再将其变为BGR格式即可。
1 2 3 image_numpy_form_Image = np.array(image) image_numpy_form_Image = cv2.cvtColor(image_numpy_form_Image,cv2.COLOR_RGB2BGR) print ("image_numpy_form_Image " ,image_numpy_form_Image.shape)
numpy转PIL 先numpy的格式由BGR变为RGB,再用Image.fromarray()转换为PIL格式。数据格式也由(h,w,c)变回(w,h,c)
1 2 3 image_Image_from_numpy = cv2.cvtColor(image2,cv2.COLOR_BGR2RGB) image_Image_from_numpy = Image.fromarray(image_Image_from_numpy) print ("image_Image_from_numpy: " ,image_Image_from_numpy.size)
总结 不同图片类型的转换是很有必要的,在适合的时候用适合的类型。尤其是tensor与两种类型的相互转换。搞清楚这些转换,可以在图片的处理上更加游刃有余。
图片格式转换时,主要考虑两点:通道顺序和维度顺序
附 plt转PIL 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def plt2PIL (plt_img, save_path, size=(16 , 16 ), dpi=14 ): """ @brief:plt图转PIL图,去白边、坐标轴,显示并保存 @param:plt_img, save_path, size=(16, 16), dpi=14 @return:NONE """ plt.figure(figsize=size, dpi=dpi) plt.gca().xaxis.set_major_locator(plt.NullLocator()) plt.gca().yaxis.set_major_locator(plt.NullLocator()) plt.subplots_adjust(top=1 , bottom=0 , right=1 , left=0 , hspace=0 , wspace=0 ) plt.margins(0 , 0 ) plt.imshow(plt_img) plt.axis('off' ) plt.savefig(save_path, pad_inches=0 ) plt.show()
参考博客:pytorch中图片类型的转换——PIL、tensor、numpy
https://blog.csdn.net/weixin_43593330/article/details/107673739 https://blog.csdn.net/qq_36955294/article/details/82888443 https://www.cnblogs.com/ocean1100/p/9494640.html