删除临时代码运行文件,更新横向赛道边缘检测功能,改进斜率计算方法,增强可视化效果,添加交点计算的可视化内容。
This commit is contained in:
parent
16a7ccd101
commit
04613d685d
BIN
res/path/test/edge_img.png
Normal file
BIN
res/path/test/edge_img.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
@ -1 +0,0 @@
|
||||
True
|
@ -2,6 +2,7 @@ import cv2
|
||||
import numpy as np
|
||||
from sklearn.cluster import KMeans
|
||||
from sklearn.metrics import silhouette_score
|
||||
from sklearn import linear_model
|
||||
|
||||
def preprocess_image(image):
|
||||
"""
|
||||
@ -558,14 +559,14 @@ def estimate_distance_to_track(image):
|
||||
|
||||
return distance, path_info["track_angle"], target_line_info
|
||||
|
||||
def detect_horizontal_track_edge(image, observe=False, delay=1500):
|
||||
def detect_horizontal_track_edge(image, observe=False, delay=1000):
|
||||
"""
|
||||
检测正前方横向黄色赛道的边缘,并返回y值最大的边缘点
|
||||
|
||||
参数:
|
||||
image: 输入图像,可以是文件路径或者已加载的图像数组
|
||||
observe: 是否输出中间状态信息和可视化结果,默认为False
|
||||
delay: 展示每个步骤的等待时间(毫秒),默认为1500ms
|
||||
delay: 展示每个步骤的等待时间(毫秒)
|
||||
|
||||
返回:
|
||||
edge_point: 赛道前方边缘点的坐标 (x, y)
|
||||
@ -828,8 +829,111 @@ def detect_horizontal_track_edge(image, observe=False, delay=1500):
|
||||
# 计算这个点到中线的距离
|
||||
distance_to_center = bottom_edge_point[0] - center_x
|
||||
|
||||
# 使用选定组的斜率
|
||||
slope = selected_slope
|
||||
# 改进斜率计算,使用BFS找到同一条边缘线上的更多点
|
||||
def get_better_slope(start_point, points, max_distance=20):
|
||||
"""使用BFS算法寻找同一条边缘线上的点,并计算更准确的斜率"""
|
||||
queue = [start_point]
|
||||
visited = {start_point}
|
||||
line_points = [start_point]
|
||||
|
||||
# BFS搜索相连的点
|
||||
while queue and len(line_points) < 200: # 增加最大点数
|
||||
current = queue.pop(0)
|
||||
cx, cy = current
|
||||
|
||||
# 对所有未访问点计算距离
|
||||
for point in points:
|
||||
if point in visited:
|
||||
continue
|
||||
|
||||
px, py = point
|
||||
# 计算欧氏距离
|
||||
dist = np.sqrt((px - cx) ** 2 + (py - cy) ** 2)
|
||||
|
||||
# 如果距离在阈值内,认为是同一条线上的点
|
||||
# 降低距离阈值,使连接更精确
|
||||
if dist < max_distance:
|
||||
queue.append(point)
|
||||
visited.add(point)
|
||||
line_points.append(point)
|
||||
|
||||
# 如果找到足够多的点,计算斜率
|
||||
if len(line_points) >= 5: # 至少需要更多点来拟合
|
||||
x_coords = np.array([p[0] for p in line_points])
|
||||
y_coords = np.array([p[1] for p in line_points])
|
||||
|
||||
# 使用RANSAC算法拟合直线,更加鲁棒
|
||||
# 尝试使用RANSAC进行更鲁棒的拟合
|
||||
try:
|
||||
# 创建RANSAC对象
|
||||
ransac = linear_model.RANSACRegressor()
|
||||
X = x_coords.reshape(-1, 1)
|
||||
|
||||
# 拟合模型
|
||||
ransac.fit(X, y_coords)
|
||||
new_slope = ransac.estimator_.coef_[0]
|
||||
|
||||
# 获取内点(符合模型的点)
|
||||
inlier_mask = ransac.inlier_mask_
|
||||
inlier_points = [line_points[i] for i in range(len(line_points)) if inlier_mask[i]]
|
||||
|
||||
# 至少需要3个内点
|
||||
if len(inlier_points) >= 3:
|
||||
return new_slope, inlier_points
|
||||
except:
|
||||
# 如果RANSAC失败,回退到普通拟合
|
||||
pass
|
||||
|
||||
# 标准拟合方法作为后备
|
||||
if np.std(x_coords) > 0:
|
||||
new_slope, _ = np.polyfit(x_coords, y_coords, 1)
|
||||
return new_slope, line_points
|
||||
|
||||
return selected_slope, line_points
|
||||
|
||||
# 尝试获取更准确的斜率
|
||||
improved_slope, better_line_points = get_better_slope(bottom_edge_point, selected_group)
|
||||
|
||||
# 使用改进后的斜率
|
||||
slope = improved_slope
|
||||
|
||||
if observe:
|
||||
improved_slope_img = img.copy()
|
||||
# 画出底部边缘点
|
||||
cv2.circle(improved_slope_img, bottom_edge_point, 10, (0, 0, 255), -1)
|
||||
# 画出改进后找到的所有点
|
||||
for point in better_line_points:
|
||||
cv2.circle(improved_slope_img, point, 3, (255, 255, 0), -1)
|
||||
# 使用改进后的斜率画线
|
||||
line_length = 300
|
||||
|
||||
# 确保线条经过边缘点
|
||||
mid_x = bottom_edge_point[0]
|
||||
mid_y = bottom_edge_point[1]
|
||||
|
||||
# 计算线条起点和终点
|
||||
end_x = mid_x + line_length
|
||||
end_y = int(mid_y + improved_slope * line_length)
|
||||
start_x = mid_x - line_length
|
||||
start_y = int(mid_y - improved_slope * line_length)
|
||||
|
||||
# 绘制线条
|
||||
cv2.line(improved_slope_img, (start_x, start_y), (end_x, end_y), (0, 255, 0), 2)
|
||||
|
||||
# 添加文本显示信息
|
||||
cv2.putText(improved_slope_img, f"原始斜率: {selected_slope:.4f}", (10, 150),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
|
||||
cv2.putText(improved_slope_img, f"改进斜率: {improved_slope:.4f}", (10, 190),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)
|
||||
cv2.putText(improved_slope_img, f"找到点数: {len(better_line_points)}", (10, 230),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)
|
||||
|
||||
# 显示所有原始点和改进算法选择的点之间的比较
|
||||
cv2.putText(improved_slope_img, f"原始点数: {len(selected_group)}", (10, 270),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
|
||||
|
||||
cv2.imshow("改进的斜率计算", improved_slope_img)
|
||||
cv2.waitKey(delay)
|
||||
|
||||
# 计算中线与检测到的横向线的交点
|
||||
# 横向线方程: y = slope * (x - edge_x) + edge_y
|
||||
@ -877,6 +981,7 @@ def detect_horizontal_track_edge(image, observe=False, delay=1500):
|
||||
cv2.putText(slope_img, f"中线交点: ({intersection_point[0]}, {intersection_point[1]})", (10, 150),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
|
||||
cv2.imshow("边缘斜率和中线交点", slope_img)
|
||||
cv2.imwrite("res/path/test/edge_img.png", slope_img)
|
||||
cv2.waitKey(delay)
|
||||
|
||||
# 创建边缘信息字典
|
||||
@ -976,6 +1081,27 @@ def visualize_horizontal_track_edge(image, save_path=None, observe=False, delay=
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
|
||||
cv2.putText(output, f"中线交点: ({intersection_point[0]}, {intersection_point[1]})", (10, 210),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
|
||||
|
||||
# 绘制交点计算的可视化内容
|
||||
# 用线条显示边缘点到中线的连接(交点计算的辅助线)
|
||||
cv2.line(output, edge_point, (center_x, edge_point[1]), (255, 153, 51), 2)
|
||||
|
||||
# 在边缘点处标注其y值
|
||||
cv2.putText(output, f"y={edge_point[1]}", (edge_point[0] + 10, edge_point[1] - 10),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 153, 51), 2)
|
||||
|
||||
# 在交点处标注其坐标
|
||||
cv2.putText(output, f"({intersection_point[0]}, {intersection_point[1]})",
|
||||
(intersection_point[0] + 10, intersection_point[1] - 10),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 255), 2)
|
||||
|
||||
# 用箭头显示从边缘点到交点的路径(表示计算过程)
|
||||
cv2.arrowedLine(output, edge_point, intersection_point, (102, 204, 255), 2)
|
||||
|
||||
# 添加交点计算的方程说明
|
||||
equation_text = f"y = {selected_slope:.2f} * (x - {edge_point[0]}) + {edge_point[1]}"
|
||||
cv2.putText(output, equation_text, (10, 240),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (102, 204, 255), 2)
|
||||
else:
|
||||
# 如果没有检测到,添加提示
|
||||
cv2.putText(output, "未检测到横向赛道", (width//4, height//2),
|
||||
|
Loading…
x
Reference in New Issue
Block a user