图像计算#

我们在上一章看到,图像以Numpy数组的形式存在。在这里,我们将看到可以用这些数组进行的不同类型的图像处理计算,比如算术运算、组合图像等。

我们在上一章看到,我们可以使用例如np.random.random函数创建图像。让我们创建两个小图像:

import numpy as np
from matplotlib import pyplot as plt
image1 = np.ones((3,5))
image1
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
image2 = np.random.random((3,5))
image2
array([[0.1389824 , 0.99979463, 0.82577042, 0.79474507, 0.23101268],
       [0.27034647, 0.01410389, 0.20435784, 0.0721552 , 0.61984191],
       [0.85459468, 0.58800162, 0.62462822, 0.01819988, 0.06607906]])

简单计算#

回顾上一章,我们看到可以像对简单数字进行算术运算一样对图像进行运算:

image1_plus = image1 + 3
image1_plus
array([[4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4.],
       [4., 4., 4., 4., 4.]])

这对所有基本运算如加法、乘法等都有效。甚至幂运算也可以:

image1_plus ** 2
array([[16., 16., 16., 16., 16.],
       [16., 16., 16., 16., 16.],
       [16., 16., 16., 16., 16.]])

组合图像#

如果图像的大小相同,我们同样可以像对简单数字一样对它们进行数学运算:同样包括加法、乘法等。例如:

image1 + image2
array([[1.1389824 , 1.99979463, 1.82577042, 1.79474507, 1.23101268],
       [1.27034647, 1.01410389, 1.20435784, 1.0721552 , 1.61984191],
       [1.85459468, 1.58800162, 1.62462822, 1.01819988, 1.06607906]])

逐像素函数#

除了允许我们创建各种类型的数组外,Numpy还为我们提供了可以对数组进行操作的函数。在许多情况下,输入是一个图像,输出是相同大小的图像,其中某个函数已应用于每个单独的像素

例如,我们可能想对图像应用对数函数来减少像素可以取的值的范围。这里我们会使用np.log函数:

np.log(image2)
array([[-1.97340794e+00, -2.05388747e-04, -1.91438488e-01,
        -2.29733884e-01, -1.46528267e+00],
       [-1.30805091e+00, -4.26130469e+00, -1.58788269e+00,
        -2.62893591e+00, -4.78290819e-01],
       [-1.57127986e-01, -5.31025584e-01, -4.70598659e-01,
        -4.00634024e+00, -2.71690330e+00]])

正如我们所看到的,输入图像有3行5列,输出图像具有相同的维度。你可以在Numpy中找到许多以这种方式操作的函数,例如取指数(np.exp()),进行三角运算(np.cos()np.sin())等。

图像统计#

另一类函数以图像作为输入,但通过计算图像或其部分的统计数据返回不同大小的输出。例如,我们可以计算所有 image2像素值的平均值:

np.mean(image2)
0.4215075982440046

或者我们可以指定要沿图像的某个维度计算平均值,在2D中沿列或行。让我们回顾一下image2是什么:

image2
array([[0.1389824 , 0.99979463, 0.82577042, 0.79474507, 0.23101268],
       [0.27034647, 0.01410389, 0.20435784, 0.0721552 , 0.61984191],
       [0.85459468, 0.58800162, 0.62462822, 0.01819988, 0.06607906]])

现在我们对列取平均值,这意味着沿第一个轴或axis=0

np.mean(image2, axis=0)
array([0.42130785, 0.53396671, 0.55158549, 0.29503338, 0.30564455])

同样的逻辑适用于所有其他统计函数,如取最小值(np.min()),最大值(np.max()),标准差(np.std()),中位数(np.median())等。

注意,这些函数中的大多数也可以直接在Numpy数组变量上调用。例如

np.std(image2)
0.3362691013424119

image2.std()
0.3362691013424119

是完全等价的。在后一种情况下使用点符号,你可能会听说std()image2的一个方法

最后,我们可能想看一下像素值的实际分布。 为此,我们看一下图像的直方图

number_of_bins = 10
min_max = [0,1]
histogram,bins = np.histogram(image2.ravel(),number_of_bins,min_max)
plt.hist(image2.ravel(), number_of_bins, min_max)
plt.show()
../_images/f1096d40d837e3fb2566f9bf2ec79e1169ddc427af6ff8d26e10e49374e021af.png

练习#

numpy.random模块中,找到一个生成泊松噪声的函数,并创建一个4x9的图像。计算其均值和标准差。