删除临时代码运行文件,更新横向赛道边缘检测功能,改进斜率计算方法,增强可视化效果,添加交点计算的可视化内容。
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