Python读入图片并转换为np数组

Posted by AspenStars on May 5, 2020

Pillow 库

Pillow是Python中首选的图像处理工具库。

安装Pillow

1
pip install Pillow

确认安装成功

1
2
import PIL
print('Pillow Version:', PIL.__version__)

如果输出Pillow的版本则安装成功

加载图片

在这里,有两种加载图像的方法:使用Pillow库和使用Matplotlib库

1 使用Pillow库

Image类是PIL的核心,它的属性有助于对图像的像素、格式和对比度等进行操作

Image的一些函数

  • open():可以直接加载图像,有一些info属性
    • format:关于图像的数字文件格式的信息;
    • mode:像素格式(例如RGB或L)的信息;
    • size:图像的尺寸
1
2
3
4
5
6
7
8
9
10
# load and show an image with Pillow
from PIL import Image
# Open the image form working directory
image = Image.open('kolala.jpeg')
# summarize some details about the image
print(image.format)
print(image.size)
print(image.mode)
# show the image
load_image.show()

out:

1
2
3
JPEG
(800, 450)
RGB

2 使用Matplotlib库

Matplotlib库也能加载图像并显示。
与PIL一样,它也有image类来执行同样的功能。
读取图像的函数是imread(),它以像素数组的形式加载图像
显示图像的函数是imshow()

Matplotlib库的pyplot类用于显示图像(必须绘制在该框架中)

1
2
3
4
5
6
7
8
9
10
11
# load and display an image with Matplotlib
from matplotlib import image
from matplotlib import pyplot
# load image as pixel array
image = image.imread('kolala.jpeg')
# summarize shape of the pixel array
print(image.dtype)
print(image.shape)
# display the array of pixels as an image
pyplot.imshow(image)
pyplot.show()

从图像转换到Numpy数组,以及从Numpy数组转换到图像

NumPy使用asarray()PIL图像转换为NumPy数组。
np.array()函数效果相同。
type()函数显示数据的类型
Image.fromarray()函数来反转这个过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from PIL import Image
import numpy as np

# load the image
image = Image.open('kolala.jpeg')
# convert image to numpy array
data = np.asarray(image)
print(type(data))
# summarize shape
print(data.shape)

# create Pillow image
image2 = Image.fromarray(data)
print(type(image2))

# summarize image details
print(image2.mode)
print(image2.size)

操作和保存图像

1 将图像转换为灰度图

使用convert('L')

1
2
3
4
5
6
7
import numpy as np
from PIL import Image

im = np.array(Image.open('kolala.jpeg').convert('L')) #you can pass multiple arguments in single line
print(type(im))

gr_im= Image.fromarray(im).save('gr_kolala.png')

2 调整图像大小

使用numpy的resize()

1
2
3
load_img_rz = np.array(Image.open('kolala.jpeg').resize((200,200)))
Image.fromarray(load_img_rz).save('r_kolala.jpeg')
print("After resizing:",load_img_rz.shape)

3 裁剪图片

直接使用数组切片

1
2
3
4
5
6
7
8
im = np.array(Image.open('kolala.jpeg'))

print("Before trimming:",im.shape)

im_trim = im[128:384, 128:384]
print("After trimming:",im_trim.shape)

Image.fromarray(im_trim).save('trim_kolala.jpeg')

另:OpenCV库

OpenCV是一个执行传统计算机视觉算法的库。

安装

1
pip install opencv-contrib-python

cv2软件包提供了imread()函数来加载图像。OpenCV以NumPy数组格式读取PIL图像。

下面将图像颜色从BGR转换为RGB,并保存

1
2
3
4
5
6
import cv2

im = cv2.imread('kolala.jpeg')
img = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)   # BGR -> RGB
cv2.imwrite('opncv_kolala.png', img) 
print (type(img))

resize()函数

改变图像大小意味着改变尺寸,无论是单独的高或宽,还是两者。也可以按比例调整图像大小。

  1. 语法

    函数原型两种方式

    1
    2
    3
    
     cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])  dst
    
     cv.Resize(src, dst, interpolation=CV_INTER_LINEAR)  None
    
  2. 参数:
    • src :【必需】原图像
    • dsize:【必需】输出图像所需大小
    • dst :【可选】输出图像,要求大小与dsize相同或者能够根据原图片和fxfy计算得到。并且数据类型与src相同
    • fx :【可选】沿水平轴的比例因子
    • fy :【可选】沿垂直轴的比例因子
    • interpolation :【可选】插值方式

    插值方式: |方式|含义| |-|-| |cv.INTER_NEAREST |最近邻插值 |cv.INTER_LINEAR |双线性插值 |cv.INTER_CUBIC |4x4像素邻域上的双三次插值 |cv.INTER_AREA |使用像素区域关系重新采样。它可能是图像抽取的首选方法,因为它可以提供无莫尔条纹的结果。但是当图像被缩放时,它类似于INTER_NEAREST方法。

    通常的,缩小使用cv.INTER_AREA,放大使用cv.INTER_CUBIC(较慢)和cv.INTER_LINEAR(较快效果也不错)。默认情况下,所有的放缩都使用cv.INTER_LINEAR。

  3. 例子 完整例子
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
     import cv2
        
     img = cv2.imread('./Pictures/python.png', cv2.IMREAD_UNCHANGED)
        
     print('Original Dimensions : ',img.shape)
        
     scale_percent = 60       # percent of original size
     width = int(img.shape[1] * scale_percent / 100)
     height = int(img.shape[0] * scale_percent / 100)
    
     dim = (width, height)
     # resize image
     resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
        
     print('Resized Dimensions : ',resized.shape)
        
     cv2.imshow("Resized image", resized)
     cv2.waitKey(0)
     cv2.destroyAllWindows()
    

    文档例子

    1
    2
    3
    4
    5
    
     // explicitly specify dsize=dst.size(); fx and fy will be computed from that.
     resize(src, dst, dst.size(), 0, 0, interpolation);
    
     // specify fx and fy and let the function compute the destination image size.
     resize(src, dst, Size(), 0.5, 0.5, interpolation);
    

参考资料

  1. Gaurav Singhal - Importing Image Data into NumPy Arrays
  2. Rogn - Python-OpenCV中的resize()函数
  3. Geometric Image Transformations