你不能不知道的六种 Python 图像库的图片读取方法总结

一、前言

在研究深度学习计算机视觉的时候,经常需要进行图像读取,但是各种第三方库的方法又不一样,用的时候又有点萌萌的,不知道有什么区别,比较常用的就是 OpenCVPILImage,但是在格式上也总是有各种各样的问题,所以这一次就好好总结主流Python图像库的一些基本使用方法和需要注意的地方。

1. Opencv
2. PIL(pillow)
3. matplotlib.image
4. scipy.misc
5. skimage
6. Tensorflow

二、opencv——cv2.imread

OpenCV作为最常用的图像处理库,实现了图像处理和计算机视觉方面的很多通用算法,可以说是很全面和强大了。如果你只想掌握一个图像库的话,OpenCV是你的最佳选择。

注意

  • OpenCV 读进来的图片已经是一个 numpy 矩阵了,彩色图片维度是高度、宽度、通道数(height,width,channels),数据类型是 uint8 。
  • OpenCV 读进来的图片的通道排列是 BGR ,而不是主流的 RGB ,需要转换才能变成 RGB 。
  • OpenCV 读取灰度图的时候,可以直接参数读取灰度图;或者先读入彩色图,再转灰度图。
import cv2
import matplotlib.pyplot as plt

# 读入图片:默认彩色图,cv2.IMREAD_GRAYSCALE灰度图,cv2.IMREAD_UNCHANGED包含alpha通道
img = cv2.imread('2.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度图
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 转换为RGB

# plt显示图像
plt.subplot(131)
plt.imshow(img)
plt.title('img')
plt.axis('off')

plt.subplot(132)
plt.imshow(gray)
plt.title('gray')
plt.axis('off')

plt.subplot(133)
plt.imshow(img_rgb)
plt.title('img_rgb')
plt.axis('off')
plt.show()

# cv2显示图像
cv2.imshow('src', img)
cv2.imshow('gray', gray)
cv2.imshow('RGB', img_rgb)

print(img.shape)  # (h,w,c)
print(img.size)  # 像素总数目
print(img.dtype)  # 像素类型
print(gray.shape)
print(gray.size)
print(gray.dtype)

cv2.imwrite('test.jpg', img_rgb)  # 保存图像
cv2.waitKey()  # 一直显示

# (336, 500, 3)
# 504000
# uint8
# (336, 500)
# 168000
# uint8

plt显示图像:
在这里插入图片描述
cv2显示图像:
在这里插入图片描述
细心的同学发现一个问题,pltcv2显示图像颜色恰好是相反的,这是一个接口的问题,因为plt是RGB接口的,但是cv2是BGR接口的,所以plt显示的是正确的颜色,也就是‘BGR’、灰度图、‘RGB’,但是cv2显示就是相反的颜色。

除此之外,OpenCV 对于读进来的图片的通道排列是 BGR ,而不是主流的 RGB ,这也是它最被人诟病的地方,容易出错,千万要注意。

# opencv读入的矩阵是BGR,转为RGB
# img_cv2(BGR) --> img_rgb(RGB)
img_cv2 = cv2.imread('1.jpg')
img_rgb = cv2.cvtColor(img_cv2, cv2.COLOR_BGR2RGB)

OpenCV 读取灰度图的时候,可以直接参数读取灰度图;或者先读入彩色图,再转灰度图。

import cv2

# 直接参数读取灰度图
gray1 = cv2.imread('1.jpg', cv2.IMREAD_GRAYSCALE)  # 灰度图
cv2.imshow('gray1', gray1)
# 也可以这么写,先读入彩色图,再转灰度图
src = cv2.imread('1.jpg')
gray2 = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray2', gray2)

cv2.waitKey()

在这里插入图片描述

两种读取灰度图方法的结果是完全相同的。

正常情况下,我们的图片是0-255的,但是有时候我们需要归一化处理为0~1。

# opencv读入的图片矩阵数值是0到255
import cv2

img_norm = cv2.imread('1.jpg')
img_norm = img_norm.astype("float") / 255.0  # 注意需要先转化数据类型为float
print(img_norm.dtype)
print(img_norm)
cv2.imshow('img_norm', img_norm)
cv2.waitKey()

# float64
[[[0.88235294 0.89019608 0.86666667]
  [0.88235294 0.88627451 0.87058824]
  [0.8745098  0.87843137 0.8627451 ]
  ...
  ...
  [0.         0.08235294 0.10588235]
  [0.         0.02745098 0.04705882]
  [0.         0.03137255 0.04313725]]]

在这里插入图片描述
OpenCV如何进行存储图片呢?使用cv2.imwrite函数即可。

# 存储图片
cv2.imwrite('test1.jpg',img_norm)  # 得到的是全黑的图片,因为我们把它归一化了
# 所以要得到可视化的图,需要先*255还原
img_test = img_norm * 255
cv2.imwrite('test2.jpg',img_test)  # 这样就可以看到彩色原图了

在这里插入图片描述

三、PIL——PIL.Image.open

PIL 即 Python Imaging Library,也即为我们所称的 Pillow,已经是 Python 平台事实上的图像处理标准库了。PIL 功能非常强大,但API却非常简单易用。它比 OpenCV 更为轻巧,正因如此,它深受大众的喜爱。

from PIL import Image
import numpy as np

img = Image.open('1.jpg')
print(img.format)
print(img.size)  # 注意,省略了通道。 (w,h)
print(img.mode)  # L为灰度图,RGB为真彩色,RGBA为加了透明通道
img.show()  # 显示图片
gray = img.convert('L')  # 转化为灰度图
print(gray.mode)  # L为灰度图,RGB为真彩色,RGBA为加了透明通道
gray.show()

# pillow读进来的图片不是矩阵,我们将图片转矩阵
arr = np.array(img)
print(arr.shape)
print(arr.dtype)
print(arr)
# 灰度图的转化与彩图转化一样
arr_gray = np.array(gray)
print(arr_gray.shape)
print(arr_gray.dtype)
print(arr_gray)

# 矩阵再转为图像,进行存储
new_im = Image.fromarray(arr)
new_im.save('test.png')

# JPEG
# (500, 336)
# RGB
# L

# (336, 500, 3)
# uint8
[[[221 227 225]
  [222 226 225]
  [220 224 223]
  ...
  ...
  [ 27  21   0]
  [ 12   7   0]
  [ 11   8   0]]]
  
# (336, 500)
# uint8
[[224 224 222 ... 223 223 223]
 [226 225 224 ... 222 222 222]
 [225 225 225 ... 222 222 222]
 ...
 [240 242 245 ...   1   1   5]
 [242 239 242 ...  10   2   5]
 [236 229 232 ...  20   7   7]]

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、matplotlib——matplotlib.image.imread

Matplotlib 是 Python 的 2D 绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。

import matplotlib.pyplot as plt

image = plt.imread('1.jpg')
plt.imshow(image)
plt.show()

image2 = plt.imread('1.jpg')
plt.imshow(image2)
plt.axis('off')  # 也可以关闭显示x,y轴上的数字
plt.show()

# plt.imread读入的就是一个矩阵,跟opencv一样,但彩图读进的是RGB,与opencv有区别
print(image.shape)  # (h,w,c)
print(image.size)
print(image.dtype)
print(image)

# (336, 500, 3)
# 504000
# uint8
[[[221 227 225]
  [222 226 225]
  [220 224 223]
  ...
  ...
  [ 27  21   0]
  [ 12   7   0]
  [ 11   8   0]]]

在这里插入图片描述
在这里插入图片描述

import matplotlib.pyplot as plt

image = plt.imread('1.jpg')
im_r = image[:, :, 0]  # 红色通道
plt.imshow(im_r)
plt.show()
# 此时会发现显示的是热量图,不是我们预想的灰度图,可以添加 cmap 参数解决
plt.imshow(im_r, cmap='Greys_r')
plt.show()

在这里插入图片描述
在这里插入图片描述

# 与opencv结合使用
import cv2
import matplotlib.pyplot as plt

image2 = cv2.imread('1.jpg')
plt.imshow(image2)
plt.axis('off')
plt.show()
# 发现图像颜色怪怪的,原因是我们前面提到的cv2读取图片时的RGB顺序不同的原因,转换一下就可以了

image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB)
plt.imshow(image2)
plt.axis('off')
plt.show()
# 所以无论用什么库读进图片,只要把图片改为矩阵,那么matplotlib就可以处理了

在这里插入图片描述
在这里插入图片描述

# pillow和matplotlib结合
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

image3 = Image.open('1.jpg')
image3 = np.array(image3)
plt.figure()
plt.imshow(image3)
plt.axis('off')
# 存储图像,注意,必须在show之前savefig,否则存储的图片一片空白
plt.savefig('timo.jpg')
plt.show()

在这里插入图片描述
在这里插入图片描述
如果先plt.show,再plt.savefig,保存的图片就是全白色的。
在这里插入图片描述
在这里插入图片描述

import matplotlib.pyplot as plt

im_1 = plt.imread('1.jpg')
im_2 = plt.imread('2.jpg')
figure = plt.figure(figsize=(10, 5))  # 调整显示图片的大小
'''
figsize参数:指定绘图对象的宽度和高度,单位为英寸;
dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80。
因此本例中所创建的图表窗口的宽度为10*80 = 800像素
'''
plt.axis("off")  # 不显示刻度

ax = figure.add_subplot(121)  # 图片以1行2列的形式显示
plt.axis('off')
ax.imshow(im_1)  # 第一张图
ax.set_title('image 1')  # 给图片加titile

ax = figure.add_subplot(122)
plt.axis('off')
ax.imshow(im_2)  # 第二张图
ax.set_title('image 2')  # 给图片加titile

plt.savefig('twp.jpg')
plt.show()

在这里插入图片描述
在这里插入图片描述

五、scipy.misc——scipy.misc.imread

from scipy import misc
import matplotlib.pyplot as plt

im = misc.imread('1.jpg')
print(im.dtype)
print(im.size)
print(im.shape)
# 存储图像,这个不需要先存储,和前面不一样
misc.imsave('misc1.png', im)
plt.imshow(im)
plt.show()
print(im)

# uint8
# 504000
# (336, 500, 3)
[[[221 227 225]
  [222 226 225]
  [220 224 223]
  ...
  ...
  [ 27  21   0]
  [ 12   7   0]
  [ 11   8   0]]]

在这里插入图片描述

六、skimage——skimage.io.imread

from skimage import io

image = io.imread('1.jpg')
print(image.shape)  # numpy矩阵,(h,w,c)
print(image.dtype)
print(image.size)
io.imshow(image)
# 存储图像,这个不需要先存储,和前面不一样
io.imsave('sk.png', image)
io.show()
print(image)

# (336, 500, 3)
# uint8
# 504000
[[[221 227 225]
  [222 226 225]
  [220 224 223]
  ...
  ...
  [ 27  21   0]
  [ 12   7   0]
  [ 11   8   0]]]

在这里插入图片描述
在这里插入图片描述

from skimage import io
# from skimage import color

image2 = io.imread('1.jpg',as_grey=True)  # 读入灰度图
# image3 = io.imread('1.jpg')
# image3 = color.rgb2grey(image3)
'''
skimage.color.rgb2grey(rgb)
skimage.color.rgb2hsv(rgb)
skimage.color.rgb2lab(rgb)
skimage.color.gray2rgb(image)
skimage.color.hsv2rgb(hsv)
skimage.color.lab2rgb(lab)
'''
print(image2.dtype)
print(image2.size)
print(image2.shape)
io.imshow(image2)
io.imsave('sk_gray.png',image2)
io.show()
print(image2)

# float64
# 168000
# (336, 500)
[[0.88463059 0.88265843 0.87481529 ... 0.87390667 0.87390667 0.87390667]
 [0.89247373 0.88658    0.88265843 ... 0.87307333 0.87307333 0.87307333]
 [0.88658    0.88658    0.8843251  ... 0.87253765 0.87253765 0.87253765]
 ...
 [0.94454039 0.95238353 0.96414824 ... 0.00333333 0.00361608 0.01876667]
 [0.95238353 0.94061882 0.95238353 ... 0.04138824 0.01061098 0.01872196]
 [0.92885412 0.90140314 0.91316784 ... 0.08141529 0.02963843 0.03161059]]

在这里插入图片描述
在这里插入图片描述

七、Tensorflow——tf.image.decode

tf.image.decode是一系列的函数:

  • tf.image.decode_bmp

channels = ?
0:使用BMP编码图像中的通道数量。
3:输出RGB图像。
4:输出RGBA图像。

  • tf.image.decode_jpeg

channels = ?
0:使用JPEG编码图像中的通道数量。
1:输出灰度图像。
3:输出RGB图像。

  • tf.image.decode_png

channels = ?
0:使用PNG编码图像中的通道数量。
1:输出灰度图像。
3:输出RGB图像。
4:输出RGBA图像。

实例推荐博客——TensorFlow图像数据处理函数——图像大小调整(最全面的可运行的代码)

八、总结

TensorFlow 的读取方式使用的比较少,除了 TensorFlow 之外,大都是比较热门的方法。

除了 OpenCV 读入的彩色图片以 BGR 顺序存储外,其他所有图像库读入彩色图片都以 RGB 存储。

除了 PIL 读入的图片是 img 类之外,其他库读进来的图片都是以 numpy 矩阵。

综合来看,还是 OpenCV 的性能更好,更推荐使用。

如果想要更多的资源,欢迎关注 @我是管小亮,文字强迫症MAX~

回复【福利】即可获取我为你准备的大礼,包括C++,编程四大件,NLP,深度学习等等的资料。

想看更多文(段)章(子),欢迎关注微信公众号「程序员管小亮」~

在这里插入图片描述

#、参考文章

原文地址:https://www.cnblogs.com/hzcya1995/p/13302762.html