PIL,cv2,plt的使用与区别
1 比较三者的打开图片、显示图片、打开的图片的类型
from PIL import Image
import cv2
import matplotlib.pyplot as plt
import numpy as np
# 比较三者的打开图片、显示图片、打开图片的类型
# ************PIL************
PIL_img = Image.open('D:/images/Rimi.jpg')
print(type(PIL_img)) # <class 'PIL.JpegImagePlugin.JpegImageFile'>
print(PIL_img.size) # (1152, 720) (w,h)
print(np.array(PIL_img).shape) # (720, 1152, 3) (h,w,c)
PIL_img.show()
# ************cv2************
cv2_img = cv2.imread('D:/images/Rimi.jpg')
print(type(cv2_img)) # <class 'numpy.ndarray'>
print(cv2_img.shape) # (720, 1152, 3) (h,w,c)
cv2.imshow('cv2', cv2_img)
# cv2.waitKey()
# ************plt***********
plt_img = plt.imread('D:/images/Rimi.jpg')
print(type(plt_img)) # <class 'numpy.ndarray'>
print(plt_img.shape) # (720, 1152, 3) (h,w,c)
plt.imshow(plt_img) # PIL_img也可以显示
plt.show()
可以看到cv2与plt打开的图片类型都是numpy,而PIL是自己独自的类型。当然这三者可以互相转换。(注意:plt可以显示numpy类型的图像,也可以显示PIL类型的)
且PIL打开图像的shape为(w,h),而cv2与plt打开rgb图像都是(h,w,c)。将PIL格式图像转为numpy后,其格式也变为(h,w,c)
2 图像类型的转换(PIL与numpy)
# PIL转numpy
img_trans = np.array(PIL_img)
print(type(img_trans)) # <class 'numpy.ndarray'>
# numpy转PIL
img_trans = Image.fromarray(cv2_img)
print(type(img_trans)) # <class 'PIL.Image.Image'>```
3 PIL,cv2,plt混用
3.1 cv2、plt读PIL打开的图像
PIL_img = Image.open('D:/images/Rimi.jpg')
cv2.imshow('cv2', np.array(PIL_img)) # cv2显示
plt.imshow(np.array(PIL_img)) # plt显示
plt.show()
首先将图像转为numpy,可以看到plt正常读出来了。但是cv2显示出来图像失真了。这是由于cv2读取图像是以BGR的顺序读的,而plt与PIL都是以RGB读的,所以plt可以正常的显示出图片
所以只需要将读取的图像从RGB转为BGR就行了,如下:
PIL_img = Image.open('D:/images/Rimi.jpg')
cv2.imshow('cv2', np.array(PIL_img)[..., ::-1]) # ::-1代表逆序输出
cv2.waitKey()
3.2 PIL、plt读cv2打开的图片
cv2_img = cv2.imread('D:/images/Rimi.jpg')
Image.fromarray(cv2_img).show() # PIL显示
plt.imshow(cv2_img) # plt显示
plt.show()
执行结果如下,前面说了PIL与plt显示图像的格式都是RGB,而cv2打开是BGR,所以结果当然会失真
解决办法同样是加上[…, ::-1]
3.3 PIL,cv2读plt打开的图像
众所周知,有一说一,结果必然是cv2显示失真,PIL显示正常
plt_img = plt.imread('D:/images/Rimi.jpg')
Image.fromarray(plt_img).show() # PIL显示
cv2.imshow('cv2', plt_img) # cv2显示
cv2.waitKey()