txt文件只保留前两列
时间: 2024-02-18 11:06:23 浏览: 21
好的,如果txt文件只保留前两列,即只有x和y坐标,可以对代码进行一些修改,具体如下:
```python
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import splprep, splev
# 读取路面点云txt文件
data = np.loadtxt('road_surface.txt', usecols=(0, 1))
# 抽稀
def simplify(points, tolerance=0.1):
"""
Douglas-Peucker抽稀算法
"""
if len(points) <= 2:
return points
dmax = 0
index = 0
end = len(points) - 1
for i in range(1, end):
d = point_to_line_distance(points[i], points[0], points[end])
if d > dmax:
index = i
dmax = d
if dmax > tolerance:
left = simplify(points[:index+1], tolerance)
right = simplify(points[index:], tolerance)
return np.vstack((left[:-1], right))
else:
return np.vstack((points[0], points[-1]))
def point_to_line_distance(point, start, end):
"""
计算点到线段的距离
"""
x, y = point
x1, y1 = start
x2, y2 = end
A = x - x1
B = y - y1
C = x2 - x1
D = y2 - y1
dot = A * C + B * D
length_squared = C * C + D * D
if length_squared == 0:
return np.sqrt((x - x1) ** 2 + (y - y1) ** 2)
t = dot / length_squared
if t < 0:
return np.sqrt((x - x1) ** 2 + (y - y1) ** 2)
elif t > 1:
return np.sqrt((x - x2) ** 2 + (y - y2) ** 2)
else:
px = x1 + t * C
py = y1 + t * D
return np.sqrt((x - px) ** 2 + (y - py) ** 2)
# 边界提取
def concave_hull(points, k):
"""
凹包算法
"""
if len(points) < 3:
return points
hull = []
points = sorted(points, key=lambda x: x[0])
left = points[0]
right = points[-1]
upper = []
lower = []
for p in points:
if is_above(left, right, p):
upper.append(p)
else:
lower.append(p)
build_hull(left, right, upper, hull)
build_hull(right, left, lower, hull)
return np.array(hull)
def build_hull(start, end, points, hull):
if len(points) == 0:
return
idx = -1
dist = 0
for i, p in enumerate(points):
d = point_to_line_distance(p, start, end)
if d > dist:
idx = i
dist = d
if idx != -1:
farthest = points[idx]
hull.append(farthest)
left = []
right = []
for i, p in enumerate(points):
if p is farthest:
continue
if is_above(start, farthest, p):
left.append(p)
elif is_above(farthest, end, p):
right.append(p)
build_hull(start, farthest, left, hull)
build_hull(farthest, end, right, hull)
def is_above(a, b, c):
"""
判断c是否在ab的上方
"""
return (c[1]-a[1])*(b[0]-a[0]) > (b[1]-a[1])*(c[0]-a[0])
# 抽稀并边界提取
simplified = simplify(data, tolerance=0.5)
hull = concave_hull(simplified, k=5)
# 拟合
tck, _ = splprep(hull.T, s=0, k=3)
# 绘图
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 5))
ax1.scatter(data[:, 0], data[:, 1], s=1, c='blue', alpha=0.5)
ax1.plot(simplified[:, 0], simplified[:, 1], c='red')
ax1.plot(hull[:, 0], hull[:, 1], c='green')
ax2.scatter(hull[:, 0], hull[:, 1], s=1, c='green')
xnew, ynew = splev(np.linspace(0, 1, 100), tck)
ax2.plot(xnew, ynew, c='red')
plt.show()
```
代码的修改包括:
1. 在读取txt文件时,使用`usecols`参数指定只读取前两列数据。
```python
data = np.loadtxt('road_surface.txt', usecols=(0, 1))
```
2. 在函数中,将点的坐标从原来的`(x, y)`改为`[x, y]`的形式。
```python
def simplify(points, tolerance=0.1):
"""
Douglas-Peucker抽稀算法
"""
if len(points) <= 2:
return points
dmax = 0
index = 0
end = len(points) - 1
for i in range(1, end):
d = point_to_line_distance(points[i], points[0], points[end])
if d > dmax:
index = i
dmax = d
if dmax > tolerance:
left = simplify(points[:index+1], tolerance)
right = simplify(points[index:], tolerance)
return np.vstack((left[:-1], right))
else:
return np.vstack((points[0], points[-1]))
```
```python
def is_above(a, b, c):
"""
判断c是否在ab的上方
"""
return (c[1]-a[1])*(b[0]-a[0]) > (b[1]-a[1])*(c[0]-a[0])
```
其它部分的代码与前面的代码相同。