我需要将一个包含离散步长高程的2D numpy数组进行平滑处理。这里我在位置 (0, 0)
的值为z-value = 1(高程)
,但它可以是0到1之间的任何值。我的数组看起来像这样:
['1.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
我尝试使用scipy
应用余弦核函数,然后使用convolve2d
。像这样:
import numpy as np
from scipy import signal
peak_array = np.array([
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
def elevation_grid():
"""Creates a smooth elevation-grid, from an array of peaks."""
def gkern():
"""Returns a 2D Triangle kernel array."""
# Decay is a cosine.
# It is centered, so multiply by two, and add one
# This way, we cover the entire grid, and assert
# equal smoothing (due to an odd width)
gkern1d_c = signal.cosine(peak_array.shape[0]*2 + 1)
gkern1d_r = signal.cosine(peak_array.shape[1]*2 + 1)
gkern2d = np.outer(gkern1d_c, gkern1d_r)
return gkern2d
kernel = gkern()
grad = signal.convolve2d(peak_array, kernel, mode='same')
# Normalize the grid
grad -= np.amin(grad)
grad /= np.amax(grad)
return grad
def print_readable(array):
"""Prints the map to a human-readable format."""
for row in range(0, array.shape[0]):
# Round to two decimals
r = ["%.2f" % array[col][row] for col in range(0, array.shape[1])]
print(r)
smooth_array = elevation_grid()
print_readable(smooth_array)
这将导致数组看起来像这样:
['1.00', '0.99', '0.95', '0.90', '0.82', '0.72', '0.60', '0.47', '0.33', '0.18']
['0.99', '0.98', '0.94', '0.89', '0.81', '0.71', '0.60', '0.47', '0.33', '0.18']
['0.95', '0.94', '0.91', '0.85', '0.78', '0.68', '0.57', '0.45', '0.32', '0.17']
['0.90', '0.89', '0.85', '0.80', '0.73', '0.64', '0.54', '0.42', '0.29', '0.16']
['0.82', '0.81', '0.78', '0.73', '0.67', '0.59', '0.49', '0.38', '0.27', '0.14']
['0.72', '0.71', '0.68', '0.64', '0.59', '0.51', '0.43', '0.33', '0.23', '0.12']
['0.60', '0.60', '0.57', '0.54', '0.49', '0.43', '0.36', '0.28', '0.19', '0.09']
['0.47', '0.47', '0.45', '0.42', '0.38', '0.33', '0.28', '0.21', '0.14', '0.06']
['0.33', '0.33', '0.32', '0.29', '0.27', '0.23', '0.19', '0.14', '0.09', '0.03']
['0.18', '0.18', '0.17', '0.16', '0.14', '0.12', '0.09', '0.06', '0.03', '0.00']
预期结果是这样的。然而,如果我在每个角落放置峰值:
['1.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '1.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00']
['1.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '1.00']
它们在中间相加,导致中心有一个更大的峰值,我希望在中间得到最低的值...
['0.00', '0.17', '0.30', '0.39', '0.44', '0.44', '0.39', '0.30', '0.17', '0.00']
['0.17', '0.36', '0.51', '0.61', '0.66', '0.66', '0.61', '0.51', '0.36', '0.17']
['0.30', '0.51', '0.67', '0.77', '0.83', '0.83', '0.77', '0.67', '0.51', '0.30']
['0.39', '0.61', '0.77', '0.89', '0.94', '0.94', '0.89', '0.77', '0.61', '0.39']
['0.44', '0.66', '0.83', '0.94', '1.00', '1.00', '0.94', '0.83', '0.66', '0.44']
['0.44', '0.66', '0.83', '0.94', '1.00', '1.00', '0.94', '0.83', '0.66', '0.44']
['0.39', '0.61', '0.77', '0.89', '0.94', '0.94', '0.89', '0.77', '0.61', '0.39']
['0.30', '0.51', '0.67', '0.77', '0.83', '0.83', '0.77', '0.67', '0.51', '0.30']
['0.17', '0.36', '0.51', '0.61', '0.66', '0.66', '0.61', '0.51', '0.36', '0.17']
['0.00', '0.17', '0.30', '0.39', '0.44', '0.44', '0.39', '0.30', '0.17', '0.00']
如何平滑我的峰值? 需要效率高,因为我有很大的数组(最多达到1000x1000)。
kern_width
、kern_height
、peak_array
... - Nils Werner