用给定范围内的随机值填充一个numpy数组?

3

我希望能够使用一组随机值来边框一个数组(实际上是一个图像文件)。numpy.pad() 函数没有任何模式可以完成此操作。是否有一种简洁的方式来实现这个功能,或者我必须从头开始创建一个函数?


https://docs.scipy.org/doc/numpy/reference/generated/numpy.pad.html。你可以不使用`pad_with`参数,而是传递一个随机整数序列或任何你想要的东西。 - Woody Pride
2个回答

2

我认为你需要自行创建一个填充函数并将其传递给np.pad。这个函数用随机整数进行填充。

def random_pad(vec, pad_width, *_, **__):
    vec[:pad_width[0]] = np.random.randint(20, 30, size=pad_width[0])
    vec[vec.size-pad_width[1]:] = np.random.randint(30,40, size=pad_width[1])

你可以像这样使用np.pad:

您可以将其与np.pad一起使用:

In [13]: img = np.arange(12).reshape(3, 4)

In [14]: img
Out[14]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [15]: np.pad(img, ((2,3), (1,4)), mode=random_pad)
Out[15]: 
array([[26, 21, 22, 24, 21, 37, 37, 37, 39],
       [26, 25, 23, 29, 20, 39, 38, 30, 31],
       [26,  0,  1,  2,  3, 37, 31, 32, 36],
       [29,  4,  5,  6,  7, 30, 32, 33, 37],
       [24,  8,  9, 10, 11, 33, 34, 33, 37],
       [26, 36, 36, 36, 30, 32, 36, 38, 31],
       [29, 33, 34, 38, 35, 31, 33, 37, 33],
       [23, 37, 33, 33, 34, 32, 37, 33, 35]])

1

虽然不是最节省空间的方法,但一种实现方式是创建一个新数组,并将现有数组放置在其中心。

>>> import numpy as np
>>> np.random.seed(444)
>>> arr = np.zeros((4, 5))  # your image array
>>> newsize = tuple(i + 2 for i in arr.shape)
>>> new = np.random.randint(low=0, high=50, size=newsize)
>>> new[1:-1, 1:-1] = arr
>>> new
array([[ 3, 48, 23,  8,  3, 39, 12],
       [47,  0,  0,  0,  0,  0, 15],
       [34,  0,  0,  0,  0,  0,  0],
       [ 6,  0,  0,  0,  0,  0,  6],
       [39,  0,  0,  0,  0,  0, 13],
       [ 2, 15,  9, 34,  9, 24, 25]])

假设您的图像是灰度图像(2D),而不是3维MxNx4 RGBA数组。在这种情况下,您需要使用 new[1:-1, 1:-1, 1:-1]。 您还可以通过将可调用对象传递给np.pad()来执行此操作,但有一个注意事项(请参见下文):
from functools import partial

def _pad_random(vector, pad_width, iaxis, kwargs, low, high):
    a, b = np.random.randint(low, high, size=2)
    vector[:pad_width[0]] = a
    vector[-pad_width[1]:] = b
    return vector

pad_random = partial(_pad_random, low=0, high=50)

使用方法:

>>> np.pad(arr, 1, pad_random)
array([[23., 19.,  6., 47., 17.,  7., 26.],
       [26.,  0.,  0.,  0.,  0.,  0., 37.],
       [39.,  0.,  0.,  0.,  0.,  0., 39.],
       [39.,  0.,  0.,  0.,  0.,  0., 42.],
       [28.,  0.,  0.,  0.,  0.,  0., 47.],
       [11., 32., 37.,  2., 38., 30., 44.]])

注意:当你将一个函数传递给np.pad()mode参数时,看起来这个函数会被调用多次。以下是直接从文档中提取的示例,其中包含一些打印调用:
>>> def pad_with(vector, pad_width, iaxis, kwargs):
...     pad_value = kwargs.get('padder', 10)
...     print(vector[:pad_width[0]])
...     print(vector[-pad_width[1]:])
...     vector[:pad_width[0]] = pad_value
...     vector[-pad_width[1]:] = pad_value
...     return vector
...
>>> arr = np.arange(6).reshape(3, 2)

>>> np.pad(arr, 1, pad_with)
[0]
[0]
[0]
[0]
[0]
[0]
[0]
[0]
[10]
[10]
[0]
[0]
[0]
[0]
[0]
[0]
[10]
[10]
array([[10, 10, 10, 10],
       [10,  0,  1, 10],
       [10,  2,  3, 10],
       [10,  4,  5, 10],
       [10, 10, 10, 10]])

因此,只要图像不太大,使用上述第一种方法可能更加时间有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接