新奇的imread

在使用Python进行图像处理时,毫无疑问第一件事就是读取图像。Python开源社区创造了大量的库,为Python的使用带来的很多的便利。就读取图像一事,就有多个库提供了imread方法。但在之前使用时,从来没有对它们之间的异同进行深入地考虑过,都是拿来即用。偶然的一次尝试,发现这些方法之间好像确实存在一些不同。

opencv-python

imreadAPI定义[1]

1
2
3
4
retval = cv.imread(filename[, flags])

# filename: Name of file to be loaded.
# flags: Flag that can take values of cv::ImreadModes

使用 cv.imread() 函数读取一张图像,图片应该在工作目录中,或者应该提供完整的图像路径。[2]

第二个参数是一个 flag,指定了应该读取图像的方式

Note

  • 你可以简单地分别传递整数 1、0 或-1,而不是这三个 flag。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Name: opencv-python
# Version: 4.7.0.72

import cv2
import numpy as np

img_path = '../datasets/lenna/lena_std.jpg'
img = cv2.imread(img_path)

print(type(img)) # <class 'numpy.ndarray'>
print(img.shape) # (512, 512, 3)

cv2.imshow("lenna", img)
cv2.waitKey(0)

print(img)
# [[[125 137 225]
# BGR模式
  • 如何理解(512, 512, 3)?

    • 直接看这就是一个512×512×3的3d array,从物理意义上说,这张图片拥有三个通道,每个通道的矩阵尺寸是512×512.
    • 但计算机认为这个3d array是有512个通道,每个通道矩阵的尺寸是512×3.
  • 彩色图像 OpenCV 用的 BGR 模式,但是 Matplotlib 显示用的 RGB 模式。因此如果图像用 OpenCV 加载,则 Matplotlib 中彩色图像将无法正常显示。[2][4]

  • 如何将OpenCV的BGR模式转为RGB模式?

1
img2 = cv2.cvtColor(img , cv2.COLOR_BGR2RGB)
1
2
b,g,r = cv2.split(img)
img2 = cv2.merge([r,g,b])

matplotlib.pyplot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Name: matplotlib
# Version: 3.3.0

import matplotlib.pyplot as plt

img_path = '../datasets/lenna/lena_std.jpg'
img = plt.imread(img_path)

print(type(img)) # <class 'numpy.ndarray'>
print(img.shape) # (512, 512, 3)

print(img)
# [[[225 137 125]

plt.imshow(img)
plt.show()

后面的几种方法都可以用plt.imshow()方法进行图像的显示。

matplotlib.image

1
2
3
4
5
6
7
8
9
10
11
12
13
# Name: matplotlib
# Version: 3.3.0

import matplotlib.image as matimage

img_path = '../datasets/lenna/lena_std.jpg'
img = matimage.imread(img_path)

print(type(img)) # <class 'numpy.ndarray'>
print(img.shape) # (512, 512, 3)

print(img)
# [[[225 137 125]

imageio

1
2
3
4
5
6
7
8
9
10
11
12
13
# Name: imageio
# Version: 2.27.0

import imageio.v2 as imageio

img_path = '../datasets/lenna/lena_std.jpg'
img = imageio.imread(img_path)

print(type(img)) # <class 'imageio.core.util.Array'>
print(img.shape) # (512, 512, 3)

print(img)
# [[[225 137 125]

Pillow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Name: Pillow
# Version: 9.5.0

from PIL import Image
import numpy as np

img_path = '../datasets/lenna/lena_std.jpg'
img = Image.open(img_path)

print(type(img)) # <class 'PIL.JpegImagePlugin.JpegImageFile'>

img = np.array(img)
print(type(img)) # <class 'numpy.ndarray'>
print(img.shape) # (512, 512, 3)

print(img)
# [[[225 137 125]

skimage

1
2
3
4
5
6
7
8
9
10
11
12
13
# Name: scikit-image
# Version: 0.20.0

import skimage.io as io

img_path = '../datasets/lenna/lena_std.jpg'
img = io.imread(img_path)

print(type(img)) # <class 'numpy.ndarray'>
print(img.shape) # (512, 512, 3)

print(img)
# [[[225 137 125]

scipy

scipy中的imread已经被移除了![3]

1
2
3
4
5
6
7
8
9
# Name: scipy
# Version: 1.9.1

import scipy.misc as misc

img_path = '../datasets/lenna/lena_std.jpg'
img = misc.imread(img_path)

# AttributeError: module 'scipy.misc' has no attribute 'imread'
1
2
3
4
5
6
7
8
9
# Name: scipy
# Version: 1.9.1

import scipy.ndimage as spyimage

img_path = '../datasets/lenna/lena_std.jpg'
img = spyimage.imread(img_path)

# AttributeError: module 'scipy.ndimage' has no attribute 'imread'

参考


新奇的imread
https://cosmicdusty.cc/post/CV/FancyImread/
作者
Murphy
发布于
2023年5月3日
许可协议