Numpy 创建图像数组
在Python中,Numpy是处理数值运算的重要库之一。而对于图像处理而言,将图像转化为数组是极为必要的一步。本篇文章将介绍如何使用Numpy创建图像数组。
阅读更多:Numpy 教程
图像数组介绍
图像在计算机中是以数组形式存在的。一个彩色的图像由红、绿、蓝三种基本颜色构成,每种颜色各用一个8位字节表示。因此,图像数组的最小单位就是一个像素(pixel),其大小即为3 * 8 = 24位(3个8位字节)。
一个M * N的图像数组,其形状为(M, N, 3),其中第三维的大小为3,表示红、绿、蓝三种颜色。如果是黑白图像,则大小为(M, N, 1)。
下面我们来通过代码实现一个简单的彩色图像数组。
import numpy as np
M = 20
N = 30
image = np.zeros((M, N, 3), dtype=np.uint8)
# 在第一行红色通道上填充255,即纯红
image[0, :, 0] = 255
上面的代码首先创建了一个20 * 30 * 3的图像数组(默认为全黑),然后在第一行的红色通道(第0维)上填充了255,即纯红。使用Matplotlib库将其显示出来:
import matplotlib.pyplot as plt
plt.imshow(image)
plt.show()
加载图像数组
我们可以通过Matplotlib库的imread函数将图片文件加载成图像数组。这里我们可以使用一张猫咪图片作为例子。首先需要下载这张图片(注意使用的是绝对路径):
from urllib import request
import os
import ssl
# 解决SSL证书不受信的问题
ssl._create_default_https_context = ssl._create_unverified_context
url = 'https://raw.githubusercontent.com/luohuasheng/image-hosting/master/cat.jpg'
path = 'cat.jpg'
if not os.path.exists(path):
request.urlretrieve(url, path, context=ssl._create_unverified_context())
然后我们可以使用imread将其加载成图像数组:
from matplotlib.image import imread
image = imread('cat.jpg')
print('shape:', image.shape) # 打印数组形状
运行结果:
shape: (285, 380, 3)
我们可以使用imshow将其显示出来,如下所示:
plt.imshow(image)
plt.show()
创建黑白图像数组
黑白图像只有一种颜色,因此其数组形状为(M, N)或者(M, N, 1)。我们可以使用np.ones、np.zeros等函数创建全黑或全白的数组。
M = 20
N = 30
image = np.zeros((M, N))
print('shape:', image.shape) # 打印数组形状
print(image) # 打印数组内容,全部为0
运行结果:
shape: (20, 30)
[[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
...
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
我们也可以将其转化为uint8类型,表示像素值的范围为0到255。
image = np.zeros((M, N), dtype=np.uint8)
print('shape:', image.shape)
print(image)
运行结果:
shape: (20, 30)
[[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]]
同样,我们也可以创建全白的数组:
image = np.ones((M, N), dtype=np.uint8) * 255
print('shape:', image.shape)
print(image)
运行结果:
shape: (20, 30)
[[255 255 255 ... 255 255 255]
[255 255 255 ... 255 255 255]
[255 255 255 ... 255 255 255]
...
[255 255 255 ... 255 255 255]
[255 255 255 ... 255 255 255]
[255 255 255 ... 255 255 255]]
创建彩色图像数组
我们可以使用np.random.randint随机生成每个像素的红、绿、蓝三种颜色的值。下面的代码创建了一张随机的彩色图像:
M = 20
N = 30
image = np.zeros((M, N, 3), dtype=np.uint8)
image[:, :, 0] = np.random.randint(0, 256, size=(M, N)) # 红色通道
image[:, :, 1] = np.random.randint(0, 256, size=(M, N)) # 绿色通道
image[:, :, 2] = np.random.randint(0, 256, size=(M, N)) # 蓝色通道
plt.imshow(image)
plt.show()
图像数组的拼接与切割
我们可以使用np.concatenate函数将两个图像数组拼接成一个。下面的代码将两张猫咪图片水平拼接成一张:
image1 = imread('cat.jpg')
image2 = imread('cat.jpg')
image_h = np.concatenate((image1, image2), axis=1)
plt.imshow(image_h)
plt.show()
我们也可以将其垂直拼接:
image_v = np.concatenate((image1, image2), axis=0)
plt.imshow(image_v)
plt.show()
除了拼接,我们还可以将一张大图像切割成多个小图像。下面的代码将一张600 * 600的图像切割成3 * 3个小图像:
image = imread('cat.jpg')
M, N, _ = image.shape # 读取图像形状
M0, N0 = M // 3, N // 3 # 计算每个小图像的形状
images = [] # 保存切割后的图像数组
for i in range(3):
for j in range(3):
images.append(image[i * M0:(i + 1) * M0, j * N0:(j + 1) * N0])
fig, axs = plt.subplots(3, 3, figsize=(6, 6))
for i in range(3):
for j in range(3):
axs[i, j].imshow(images[i * 3 + j])
plt.show()
总结
本文介绍了如何使用Numpy创建图像数组,以及加载、保存、拼接、切割等常用操作。掌握这些操作可以方便我们对图像进行各种处理和分析。
极客教程