当我有两个 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()
我认为这最接近您想要实现的目标:
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,因此您可能需要仔细检查这两个实现。