如何在指定矩形的 numpy 数组周围创建缓冲区

问题描述 投票:0回答:1

当我有两个 numpy 数组 a 和 b 时,我遇到这个问题,其中 b 与 a 相同,但只进行了一些数据修改。为了便于解释,这里是最小工作简化示例。

我的目标是在矩形周围创建一个缓冲区 - 由 xmin、xmax、ymin、xmax 定义 - 其中值将是权重的结果。所以在这个例子中,矩形周围第一个像素的值是来自数组 b 的 75%,来自数组 a 的 25%,依此类推..

我设法创建了这个最脏的示例,它正在工作,但如果我想使用更宽的缓冲区(例如 5 像素),它真的很难看且不可扩展。


import numpy as np
import matplotlib.pyplot as plt

# create array a filled with number 10
a = np.full((20,20),10)

# create array b filled with number 20
b = np.full((20,20),20)

# central aprt of array b
xmin, ymin, xmax, ymax = 5, 5, 15, 15
b[ymin:ymax, xmin:xmax] = 10
fig, (ax1, ax2) = plt.subplots(1,2)
ax1.imshow(b)

def blend_edges(data_background, data_forwground, weights, xmin, xmax, ymin, ymax):

    a = data_background
    b = data_forwground

    for distance, w in enumerate(weights, start=1):
        # on edges
        b[ymin:ymax, xmin-distance,] = (b[ymin:ymax, xmin-distance,] * (1.-w)) + (a[ymin:ymax, xmin-distance,] * (w))
        b[ymin:ymax, xmax-1+distance,] = (b[ymin:ymax, xmax-1+distance] * (1.-w)) + (a[ymin:ymax, xmax-1+distance] * (w))
        b[ymin-distance, xmin:xmax,] = (b[ymin-distance, xmin:xmax,] * (1.-w)) + (a[ymin-distance, xmin:xmax,] * (w))
        b[ymax-1+distance, xmin:xmax,] = (b[ymax-1+distance, xmin:xmax,] * (1.-w)) + (a[ymax-1+distance, xmin:xmax,] * (w))

        # diagonal
        b[ymin-distance:ymin+1-distance, xmin-distance:xmin+1-distance,] = (b[ymin-distance:ymin+1-distance, xmin-distance:xmin+1-distance] * (1.-w)) + (a[ymin-distance:ymin+1-distance, xmin-distance:xmin+1-distance] * (w))
        b[ymax-1+distance:ymax+distance, xmax-1+distance:xmax+distance] = (b[ymax-1+distance:ymax+distance, xmax-1+distance:xmax+distance] * (1.-w)) + (a[ymax-1+distance:ymax+distance, xmax-1+distance:xmax+distance] * (w))
        b[ymin-distance:ymin+1-distance, xmax-1+distance:xmax+distance] = (b[ymin-1-distance:ymin-distance, xmax-1+distance:xmax+distance] * (1.-w)) + (a[ymin-1-distance:ymin-distance, xmax-1+distance:xmax+distance] * (w))
        b[ymax-1+distance:ymax+distance, xmin-distance:xmin+1-distance] = (b[ymax-1+distance:ymax+distance, xmin-distance:xmin+1-distance] * (1.-w)) + (a[ymax-1+distance:ymax+distance, xmin-distance:xmin+1-distance] * (w))

    for distance, w in enumerate(weights[1:], start=2):
        # ul
        b[ymin+1-distance:ymin+2-distance, xmin-distance:xmin+1-distance,] = (b[ymin+1-distance:ymin+2-distance, xmin-distance:xmin+1-distance] * (1.-w)) + (a[ymin+1-distance:ymin+2-distance, xmin-distance:xmin+1-distance] * (w))
        b[ymin-distance:ymin+1-distance, xmin+1-distance:xmin+2-distance,] = (b[ymin-distance:ymin+1-distance, xmin+1-distance:xmin+2-distance] * (1.-w)) + (a[ymin-distance:ymin+1-distance, xmin+1-distance:xmin+2-distance] * (w))
        # br
        b[ymax-2+distance:ymax-1+distance, xmax-1+distance:xmax+distance] = (b[ymax-2+distance:ymax-1+distance, xmax-1+distance:xmax+distance] * (1.-w)) + (a[ymax-2+distance:ymax-1+distance, xmax-1+distance:xmax+distance] * (w))
        b[ymax-1+distance:ymax+distance, xmax-2+distance:xmax-1+distance] = (b[ymax-1+distance:ymax+distance, xmax-2+distance:xmax-1+distance] * (1.-w)) + (a[ymax-1+distance:ymax+distance, xmax-2+distance:xmax-1+distance] * (w))
        # ur
        b[ymin-distance:ymin+1-distance, xmax-2+distance:xmax-1+distance] = (b[ymin-distance:ymin+1-distance, xmax-2+distance:xmax-1+distance] * (1.-w)) + (a[ymin-distance:ymin+1-distance, xmax-2+distance:xmax-1+distance] * (w))
        b[ymin+1-distance:ymin+2-distance, xmax-1+distance:xmax+distance] = (b[ymin+1-distance:ymin+2-distance, xmax-1+distance:xmax+distance] * (1.-w)) + (a[ymin+1-distance:ymin+2-distance, xmax-1+distance:xmax+distance] * (w))
        # bl
        b[ymax-2+distance:ymax-1+distance, xmin-distance:xmin+1-distance] = (b[ymax-2+distance:ymax-1+distance, xmin-distance:xmin+1-distance] * (1.-w)) + (a[ymax-2+distance:ymax-1+distance, xmin-distance:xmin+1-distance] * (w))
        b[ymax-1+distance:ymax+distance, xmin+1-distance:xmin+2-distance] = (b[ymax-1+distance:ymax+distance, xmin+1-distance:xmin+2-distance] * (1.-w)) + (a[ymax-1+distance:ymax+distance, xmin+1-distance:xmin+2-distance] * (w))

    for distance, w in enumerate(weights[2:], start=3):
        # ul
        b[ymin+2-distance:ymin+3-distance, xmin-distance:xmin+1-distance,] = (b[ymin+2-distance:ymin+3-distance, xmin-distance:xmin+1-distance] * (1.-w)) + (a[ymin+2-distance:ymin+3-distance, xmin-distance:xmin+1-distance] * (w))
        b[ymin-distance:ymin+1-distance, xmin+2-distance:xmin+3-distance,] = (b[ymin-distance:ymin+1-distance, xmin+2-distance:xmin+3-distance] * (1.-w)) + (a[ymin-distance:ymin+1-distance, xmin+2-distance:xmin+3-distance] * (w))
        # br
        b[ymax-3+distance:ymax-2+distance, xmax-1+distance:xmax+distance] = (b[ymax-3+distance:ymax-2+distance, xmax-1+distance:xmax+distance] * (1.-w)) + (a[ymax-3+distance:ymax-2+distance, xmax-1+distance:xmax+distance] * (w))
        b[ymax-1+distance:ymax+distance, xmax-3+distance:xmax-2+distance] = (b[ymax-1+distance:ymax+distance, xmax-3+distance:xmax-2+distance] * (1.-w)) + (a[ymax-1+distance:ymax+distance, xmax-3+distance:xmax-2+distance] * (w))
        # # ur
        b[ymin-distance:ymin+1-distance, xmax-3+distance:xmax-2+distance] = (b[ymin-distance:ymin+1-distance, xmax-3+distance:xmax-2+distance] * (1.-w)) + (a[ymin-distance:ymin+1-distance, xmax-3+distance:xmax-2+distance] * (w))
        b[ymin+2-distance:ymin+3-distance, xmax-1+distance:xmax+distance] = (b[ymin+2-distance:ymin+3-distance, xmax-1+distance:xmax+distance] * (1.-w)) + (a[ymin+2-distance:ymin+3-distance, xmax-1+distance:xmax+distance] * (w))
        # # bl
        b[ymax-3+distance:ymax-2+distance, xmin-distance:xmin+1-distance] = (b[ymax-3+distance:ymax-2+distance, xmin-distance:xmin+1-distance] * (1.-w)) + (a[ymax-3+distance:ymax-2+distance, xmin-distance:xmin+1-distance] * (w))
        b[ymax-1+distance:ymax+distance, xmin+2-distance:xmin+3-distance] = (b[ymax-1+distance:ymax+distance, xmin+2-distance:xmin+3-distance] * (1.-w)) + (a[ymax-1+distance:ymax+distance, xmin+2-distance:xmin+3-distance] * (w))

    return b

weights = [0.75,0.5,0.25]

blend_edges(a,b,weights,xmin, xmax, ymin, ymax )


ax2.imshow(b)
plt.show()


上面代码的结果:

python numpy
1个回答
0
投票

我认为这最接近您想要实现的目标:

import numpy as np

a = np.full((20, 20), 10)

b = np.full((20, 20), 20)

xmin, ymin, xmax, ymax = 5, 5, 15, 15
b[ymin:ymax, xmin:xmax] = 10


def blend_edges_general(a, b, weights, xmin, xmax, ymin, ymax):
    """Blend edges of two arrays."""
    w = np.ones((ymax - ymin, xmax - xmin))

    for value in weights:
        w = np.pad(w, 1, mode="constant", constant_values=value)

    width = len(weights)

    weights = np.zeros(a.shape)
    weights[ymin - width: ymax + width, xmin - width: xmax + width] = w
    
    return (weights * a) + (1 - weights) * b

result = blend_edges_general(a, b, [0.75, 0.5, 0.25], xmin, xmax, ymin, ymax)
    

fig, axes = plt.subplots(1, 2)

axes[0].imshow(b)
axes[1].imshow(result)

这给出了:

这里的关键思想是依靠

np.pad
迭代地创建具有所请求权重的矩形周围的边界。这应该推广到任意权重。但是我注意到我的代码没有给出与您的完全相同的结果。最外层和最内层“矩形环”的值相差 0.5,因此您可能需要仔细检查这两个实现。

© www.soinside.com 2019 - 2024. All rights reserved.