Python中的线条平滑算法?
我正在研究线条简化,这个技术可以用来从大规模地图生成小规模的道路网络地图。我使用了两种操作和两种算法。这些工作是用Python编程语言完成的,使用了shapefile库,主要处理二维的矢量数据。
操作包括:选择和淘汰。
在选择时,我设定了一些条件,比如选择所有宽度超过7米的道路,这些条件与道路的属性特征有关。
淘汰的方式也是类似,比如淘汰所有宽度小于5米的道路。
到目前为止,这些操作没有遇到太多问题。
在完成选择和淘汰操作后,我们会得到一个形状文件,里面包含符合条件的道路。
我使用了两种算法,分别是线条简化和线条平滑。
在线条简化方面,我使用了Douglas-Peucker算法。这个算法会处理矢量数据(坐标),根据设定的容差来去掉一些点。我也是用Python来实现这个算法。得到简化后的线条后,还需要进行一些编辑,比如线条平滑。
在平滑方面,我使用了高斯算法,但它返回了一些我不理解的错误,因为我在编程方面还是个新手。
import numpy
### This is the Gaussian data smoothing function I wrote ###
def smoothListGaussian(list1,degree):
window=degree*2-1
weight=numpy.array([1.0]*window)
print weight
weightGauss=[]
for i in range(window):
i=i-degree+1
frac=i/float(window)
gauss=1/(numpy.exp((4*(frac))**2))
weightGauss.append(gauss)
print weightGauss
weight=numpy.array(weightGauss)*weight
print weight
print len(list1)-window
smoothed=[0.0]*(len(list1)-window)
print smoothed
for i in range(len(smoothed)):
smoothed[i]=sum(numpy.array(list1[i:i+window])*weight)/sum(weight)
return smoothed
a=[[78.03881018900006, 30.315651467000066], [78.044901609000078, 30.31512798600005], [78.04927981700007, 30.312510579000048], [78.050041244000056, 30.301755415000059], [78.072646124000073, 30.281720353000082], [78.07902308000007, 30.273344651000059]]
smoothListGaussian(a,3)
如果有任何想法,请告诉我。
或者如果有其他的Python算法可以用来平滑矢量数据中的线条,利用每个点的坐标,也请分享一下。
非常感谢大家的回答!
2 个回答
16
你可以通过以下代码来平滑路径:
from scipy.ndimage import gaussian_filter1d
import numpy as np
a=np.array([[78.03881018900006, 30.315651467000066],
[78.044901609000078, 30.31512798600005],
[78.04927981700007, 30.312510579000048],
[78.050041244000056, 30.301755415000059],
[78.072646124000073, 30.281720353000082],
[78.07902308000007, 30.273344651000059]])
x, y = a.T
t = np.linspace(0, 1, len(x))
t2 = np.linspace(0, 1, 100)
x2 = np.interp(t2, t, x)
y2 = np.interp(t2, t, y)
sigma = 10
x3 = gaussian_filter1d(x2, sigma)
y3 = gaussian_filter1d(y2, sigma)
x4 = np.interp(t, t2, x3)
y4 = np.interp(t, t2, y3)
plot(x, y, "o-", lw=2)
plot(x3, y3, "r", lw=2)
plot(x4, y4, "o", lw=2)
这里是结果:蓝色的点是原始数据,红色的曲线是经过平滑处理后的曲线,它包含了很多点。如果你想让点的数量和原始数据一样,可以从红色曲线中取样,得到绿色的点。
你可以设置 sigma
来改变 gaussian_filter1d()
的平滑程度。
1
我猜你是从这里拿的代码。你应该注意到,这段代码是针对一维数据点的,而不是多维数据点。
我对高斯平滑算法了解不多,但在简单看了一下你的代码后,我觉得你可能想要做的是这个(我不确定这样做是否能得到你想要的结果)。把你代码的最后部分替换成以下代码:
smoothed=[0.0,0.0]*(len(list1)-window)
print smoothed
for i in range(len(smoothed)):
smoothing=[0.0,0.0]
for e,w in zip(list1[i:i+window],weight):
smoothing=smoothing+numpy.multiply(e,w)
smoothed[i]=smoothing/sum(weight)