Python下采样阵列

本教程将讨论在Python中对图像进行下采样的方法。

在Python3中用切片法对数组进行下采样

在Python中,图像是一个多维数组。灰度图像用一个二维数组表示,而彩色或RGB图像用一个三维数组表示。

为了简单起见,本教程将侧重于减少二维灰度图像的大小,但这里讨论的方法也可以用来减少RGB图像的大小。

我们的第一个方法是非常直接的。在切片中,顾名思义,我们从一个整体的大图像中取出一个小的切片。

在对图像进行切片时,我们可以给出一个步骤参数,指定在取下一个值之前要跳过多少个值。默认情况下,这个值被设置为1。

下面的代码例子演示了我们如何使用数组切片对图像进行向下取样。

import numpy as np
b = np.arange(0,100)
c = b.reshape([10,10])
print("Original Array:")
print(c)
print("Downsized Array:")
print(c[::2,::2])

输出:

Original Array:
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]
 [50 51 52 53 54 55 56 57 58 59]
 [60 61 62 63 64 65 66 67 68 69]
 [70 71 72 73 74 75 76 77 78 79]
 [80 81 82 83 84 85 86 87 88 89]
 [90 91 92 93 94 95 96 97 98 99]]
Downsized Array:
[[ 0  2  4  6  8]
 [20 22 24 26 28]
 [40 42 44 46 48]
 [60 62 64 66 68]
 [80 82 84 86 88]]

上面写的代码将我们的原始图像c ,从(10,10)减少到(5,5),并存储到new_c

需要注意的是,这个方法从我们的原始100个值中选择了25个值。其余数值的信息在这个方法中完全丢失。

使用Python中的zoom() 函数对数组进行降样处理

ndimage.interpolation.zoom() 函数也被用来对Python中的图像进行上采样或下采样。这个函数需要2个参数;需要放大的原始图像和缩放比例。

这种方法与切片法非常相似。它也跳过了中间值,在下采样时只从我们的原始图像中选择几个值。

下面的代码示例演示了我们如何使用ndimage.interpolation.zoom() 函数对图像进行下采样。

import numpy as np
from scipy import ndimage
b = np.arange(0,100)
c = b.reshape([10,10])
new_c = ndimage.interpolation.zoom(c, 0.5)
print("Original Array:")
print(c)
print("Downsized Array:")
print(new_c)

输出:

Original Array:
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]
 [50 51 52 53 54 55 56 57 58 59]
 [60 61 62 63 64 65 66 67 68 69]
 [70 71 72 73 74 75 76 77 78 79]
 [80 81 82 83 84 85 86 87 88 89]
 [90 91 92 93 94 95 96 97 98 99]]
Downsized Array:
[[ 0  2  4  6  8]
 [20 22 24 26 28]
 [40 42 44 46 48]
 [60 62 64 66 68]
 [80 82 84 86 88]]

上面写的代码与前面的例子的工作方式相同,将我们的原始图像c ,从(10,10)减少到(5,5)。

这种方法比简单的切片要好,因为它也可以用来对图像进行上样处理。我们必须指定一些大于1的缩放值。

在下采样时,这种方法是无效的,因为它跳过了许多像素值,只从我们的原始图像中选择了几个。下面将介绍一种更有效的方法,通过组合多个像素值来估计新的数值。

用Python中的block_reduce() 函数对数组进行降样处理

切片和缩放方法都会导致阶梯效应,即使我们对输入图像进行下采样,也会使我们的整个图像变得模糊。

处理中间值的一个更好的方法是使用它们周围的像素来估计它们。这可以通过不同的方式来完成,比如插值和简单的平均值。

为了简单起见,我们将使用简单手段的方法。python的skimage.measure 模块里面的block_reduce() 函数是用来减少多维数组的大小。

这个block_reduce() 函数需要3个主要参数;原始数组,块大小,以及应用于每个块的函数。

块的大小告诉我们原始图像中的多少个值将合并成我们缩小后的图像中的一个值,func 参数指定了将应用于合并一个块中所有值的函数。

由于在我们之前的所有例子中,我们一直在将一个(10, 10)的图像减少到一个(5, 5)的图像,我们的块大小将是(2, 2),由于我们希望新的值是整个块的平均值,而不仅仅是块中的一个值,我们将使用np.mean 作为func

下面的代码例子演示了我们如何使用block_reduce() 方法对我们的图像进行下采样。

import numpy as np
from skimage.measure import block_reduce
b = np.arange(0,100)
c = b.reshape([10,10])
new_c = block_reduce(c, block_size=(2,2), func=np.mean)
print("Original Array:")
print(c)
print("Downsized Array:")
print(new_c)

输出:

Original Array:
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]
 [50 51 52 53 54 55 56 57 58 59]
 [60 61 62 63 64 65 66 67 68 69]
 [70 71 72 73 74 75 76 77 78 79]
 [80 81 82 83 84 85 86 87 88 89]
 [90 91 92 93 94 95 96 97 98 99]]
Downsized Array:
[[ 5.5  7.5  9.5 11.5 13.5]
 [25.5 27.5 29.5 31.5 33.5]
 [45.5 47.5 49.5 51.5 53.5]
 [65.5 67.5 69.5 71.5 73.5]
 [85.5 87.5 89.5 91.5 93.5]]

上节写的代码从我们的原始图像c ,取一个(2,2)块,取该块内所有4个值的平均值,并将结果放入我们的新图像new_c

这种方法比上面讨论的前两种方法要好,因为它取的是所有数值的综合效果,而不是只从原始图像块中取一个数值,跳过每个块中的其余3个数值。