From 968471471f457efbff53539321fe7a8080ae8d1f Mon Sep 17 00:00:00 2001 From: Havoc <2993167370@qq.com> Date: Thu, 22 May 2025 12:35:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=B5=8B=E8=AF=95=E5=9B=BE?= =?UTF-8?q?=E5=83=8F=E7=BB=93=E6=9E=9C=E6=96=87=E4=BB=B6=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E5=9C=A8=E9=BB=84=E8=89=B2=E8=B5=9B=E9=81=93=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E6=BC=94=E7=A4=BA=E7=A8=8B=E5=BA=8F=E4=B8=AD=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E5=92=8C=E8=BE=93=E5=87=BA=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=97=B6=E5=9C=A8=E8=BE=B9=E7=BC=98=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=E7=AE=97=E6=B3=95=E4=B8=AD=E5=BC=95=E5=85=A5=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E6=A3=80=E6=B5=8B=E5=87=BD=E6=95=B0=E4=BB=A5=E6=8F=90?= =?UTF-8?q?=E5=8D=87=E6=A3=80=E6=B5=8B=E5=87=86=E7=A1=AE=E6=80=A7=E5=92=8C?= =?UTF-8?q?=E7=A8=B3=E5=AE=9A=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logs/robot_2025-05-22.log | 90 ++++ res/path/test-3.jpg | Bin 0 -> 74782 bytes .../test/result_image_20250514_024347.png | Bin 60479 -> 0 bytes test/task-path-track/yellow_track_demo.py | 8 +- utils/detect_track.py | 405 +++++++++++++++++- 5 files changed, 483 insertions(+), 20 deletions(-) create mode 100644 logs/robot_2025-05-22.log create mode 100644 res/path/test-3.jpg delete mode 100644 res/path/test/result_image_20250514_024347.png diff --git a/logs/robot_2025-05-22.log b/logs/robot_2025-05-22.log new file mode 100644 index 0000000..87f4a92 --- /dev/null +++ b/logs/robot_2025-05-22.log @@ -0,0 +1,90 @@ +2025-05-22 12:20:16 | DEBUG | utils.log_helper - 🐞 步骤1: 原始图像已加载 +2025-05-22 12:20:18 | DEBUG | utils.log_helper - 🐞 步骤2: 创建黄色掩码 +2025-05-22 12:20:19 | DEBUG | utils.log_helper - 🐞 步骤3: 提取黄色部分 +2025-05-22 12:20:20 | DEBUG | utils.log_helper - 🐞 检测底部和顶部边缘点 +2025-05-22 12:20:21 | DEBUG | utils.log_helper - 🐞 步骤4: 边缘检测 +2025-05-22 12:20:22 | DEBUG | utils.log_helper - 🐞 步骤5: 检测到 8 条直线 +2025-05-22 12:20:23 | DEBUG | utils.log_helper - 🐞 步骤6: 找到 5 条水平线 (下方: 5, 上方: 0) +2025-05-22 12:20:24 | DEBUG | utils.log_helper - 🐞 选择下方水平线 +2025-05-22 12:20:24 | DEBUG | utils.log_helper - 🐞 显示边缘斜率和中线交点 +2025-05-22 12:20:25 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_122025_111891.jpg +2025-05-22 12:20:25 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_122025_111891', 'edge_point': (1919, 862), 'distance_to_center': 959, 'slope': 0.03486394557823129, 'distance_to_bottom': 251.43452380952385, 'intersection_point': (960, 828), 'score': 0.6679311933106575, 'valid': True, 'reason': '', 'is_lower_line': array([ True, True, True, True])} +2025-05-22 12:20:38 | DEBUG | utils.log_helper - 🐞 步骤1: 原始图像已加载 +2025-05-22 12:20:39 | DEBUG | utils.log_helper - 🐞 步骤2: 创建黄色掩码 +2025-05-22 12:20:40 | DEBUG | utils.log_helper - 🐞 步骤3: 提取黄色部分 +2025-05-22 12:20:41 | DEBUG | utils.log_helper - 🐞 检测底部和顶部边缘点 +2025-05-22 12:20:42 | DEBUG | utils.log_helper - 🐞 步骤4: 边缘检测 +2025-05-22 12:20:43 | DEBUG | utils.log_helper - 🐞 步骤5: 检测到 8 条直线 +2025-05-22 12:20:44 | DEBUG | utils.log_helper - 🐞 步骤6: 找到 5 条水平线 (下方: 5, 上方: 0) +2025-05-22 12:20:45 | DEBUG | utils.log_helper - 🐞 选择下方水平线 +2025-05-22 12:20:45 | DEBUG | utils.log_helper - 🐞 显示边缘斜率和中线交点 +2025-05-22 12:20:47 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_122046_987809.jpg +2025-05-22 12:20:47 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_122046_987809', 'edge_point': (1919, 862), 'distance_to_center': 959, 'slope': 0.03486394557823129, 'distance_to_bottom': 251.43452380952385, 'intersection_point': (960, 828), 'score': 0.6679311933106575, 'valid': True, 'reason': '', 'is_lower_line': array([ True, True, True, True])} +2025-05-22 12:21:15 | DEBUG | utils.log_helper - 🐞 步骤1: 原始图像已加载 +2025-05-22 12:21:16 | DEBUG | utils.log_helper - 🐞 步骤2: 创建黄色掩码 +2025-05-22 12:21:17 | DEBUG | utils.log_helper - 🐞 步骤3: 提取黄色部分 +2025-05-22 12:21:18 | DEBUG | utils.log_helper - 🐞 检测底部和顶部边缘点 +2025-05-22 12:21:19 | DEBUG | utils.log_helper - 🐞 步骤4: 边缘检测 +2025-05-22 12:21:20 | DEBUG | utils.log_helper - 🐞 步骤5: 检测到 8 条直线 +2025-05-22 12:21:21 | DEBUG | utils.log_helper - 🐞 步骤6: 找到 5 条水平线 (下方: 5, 上方: 0) +2025-05-22 12:21:22 | DEBUG | utils.log_helper - 🐞 选择下方水平线 +2025-05-22 12:21:22 | DEBUG | utils.log_helper - 🐞 显示边缘斜率和中线交点 +2025-05-22 12:21:23 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_122123_802326.jpg +2025-05-22 12:21:23 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_122123_802326', 'edge_point': (1919, 862), 'distance_to_center': 959, 'slope': 0.03486394557823129, 'distance_to_bottom': 251.43452380952385, 'intersection_point': (960, 828), 'score': 0.6679311933106575, 'valid': True, 'reason': '', 'is_lower_line': array([ True, True, True, True])} +2025-05-22 12:22:26 | DEBUG | utils.log_helper - 🐞 步骤1: 原始图像已加载 +2025-05-22 12:22:28 | DEBUG | utils.log_helper - 🐞 步骤2: 创建黄色掩码 +2025-05-22 12:22:29 | DEBUG | utils.log_helper - 🐞 步骤3: 提取黄色部分 +2025-05-22 12:22:30 | DEBUG | utils.log_helper - 🐞 检测底部和顶部边缘点 +2025-05-22 12:22:31 | DEBUG | utils.log_helper - 🐞 步骤4: 边缘检测 +2025-05-22 12:22:32 | DEBUG | utils.log_helper - 🐞 步骤5: 检测到 8 条直线 +2025-05-22 12:22:33 | DEBUG | utils.log_helper - 🐞 步骤6: 找到 5 条水平线 (下方: 5, 上方: 0) +2025-05-22 12:22:34 | DEBUG | utils.log_helper - 🐞 选择下方水平线 +2025-05-22 12:22:34 | DEBUG | utils.log_helper - 🐞 显示边缘斜率和中线交点 +2025-05-22 12:22:35 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_122235_241410.jpg +2025-05-22 12:22:35 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_122235_241410', 'edge_point': (1919, 862), 'distance_to_center': 959, 'slope': 0.03486394557823129, 'distance_to_bottom': 251.43452380952385, 'intersection_point': (960, 828), 'score': 0.6679311933106575, 'valid': True, 'reason': '', 'is_lower_line': array([ True, True, True, True])} +2025-05-22 12:24:10 | DEBUG | utils.log_helper - 🐞 步骤1: 原始图像已加载 +2025-05-22 12:24:11 | DEBUG | utils.log_helper - 🐞 步骤2: 创建黄色掩码 +2025-05-22 12:24:12 | DEBUG | utils.log_helper - 🐞 步骤3: 提取黄色部分 +2025-05-22 12:24:13 | DEBUG | utils.log_helper - 🐞 检测底部和顶部边缘点 +2025-05-22 12:24:14 | DEBUG | utils.log_helper - 🐞 步骤4: 边缘检测 +2025-05-22 12:24:15 | DEBUG | utils.log_helper - 🐞 步骤5: 检测到 28 条直线 +2025-05-22 12:24:16 | DEBUG | utils.log_helper - 🐞 步骤6: 找到 6 条水平线 (下方: 6, 上方: 0) +2025-05-22 12:24:17 | DEBUG | utils.log_helper - 🐞 选择下方水平线 +2025-05-22 12:24:17 | DEBUG | utils.log_helper - 🐞 显示边缘斜率和中线交点 +2025-05-22 12:24:18 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_122418_738782.jpg +2025-05-22 12:24:18 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_122418_738782', 'edge_point': (91, 1078), 'distance_to_center': -869, 'slope': -0.07092198581560284, 'distance_to_bottom': 63.631205673758814, 'intersection_point': (960, 1016), 'score': 0.8014868667518458, 'valid': True, 'reason': '', 'is_lower_line': array([ True, True, True, True])} +2025-05-22 12:24:54 | DEBUG | utils.log_helper - 🐞 步骤1: 原始图像已加载 +2025-05-22 12:24:55 | DEBUG | utils.log_helper - 🐞 步骤2: 创建黄色掩码 +2025-05-22 12:24:56 | DEBUG | utils.log_helper - 🐞 步骤3: 提取黄色部分 +2025-05-22 12:24:57 | DEBUG | utils.log_helper - 🐞 检测底部和顶部边缘点 +2025-05-22 12:24:58 | DEBUG | utils.log_helper - 🐞 步骤4: 边缘检测 +2025-05-22 12:24:59 | DEBUG | utils.log_helper - 🐞 步骤5: 检测到 11 条直线 +2025-05-22 12:25:00 | DEBUG | utils.log_helper - 🐞 步骤6: 找到 1 条水平线 (下方: 1, 上方: 0) +2025-05-22 12:25:01 | DEBUG | utils.log_helper - 🐞 选择下方水平线 +2025-05-22 12:25:01 | DEBUG | utils.log_helper - 🐞 显示边缘斜率和中线交点 +2025-05-22 12:25:02 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_122502_339369.jpg +2025-05-22 12:25:02 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_122502_339369', 'edge_point': (1439, 899), 'distance_to_center': 479, 'slope': -0.07083333333333333, 'distance_to_bottom': 147.07083333333333, 'intersection_point': (960, 932), 'score': 0.5594172208352652, 'valid': True, 'reason': '', 'is_lower_line': array([ True, True, True, True])} +2025-05-22 12:33:02 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_123302_872381.jpg +2025-05-22 12:33:02 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_123302_872381', 'edge_point': (320, 1009), 'distance_to_center': -640, 'slope': -0.07331047777324741, 'distance_to_bottom': 117.91870577487839, 'intersection_point': (960, 962)} +2025-05-22 12:33:26 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_123326_235741.jpg +2025-05-22 12:33:26 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_123326_235741', 'edge_point': (320, 1009), 'distance_to_center': -640, 'slope': -0.07331047777324741, 'distance_to_bottom': 117.91870577487839, 'intersection_point': (960, 962)} +2025-05-22 12:34:09 | DEBUG | utils.log_helper - 🐞 步骤1: 原始图像已加载 +2025-05-22 12:34:10 | DEBUG | utils.log_helper - 🐞 步骤2: 创建黄色掩码 +2025-05-22 12:34:10 | DEBUG | utils.log_helper - 🐞 步骤3: 提取黄色部分 +2025-05-22 12:34:11 | DEBUG | utils.log_helper - 🐞 正在处理底部边缘点 +2025-05-22 12:34:12 | DEBUG | utils.log_helper - 🐞 显示拟合线段 +2025-05-22 12:34:13 | DEBUG | utils.log_helper - 👁️ 步骤5: 找到边缘点 (320, 1009) +2025-05-22 12:34:14 | DEBUG | utils.log_helper - 🐞 显示边缘斜率和中线交点 +2025-05-22 12:34:14 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_123414_979258.jpg +2025-05-22 12:34:14 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_123414_979258', 'edge_point': (320, 1009), 'distance_to_center': -640, 'slope': -0.07331047777324741, 'distance_to_bottom': 117.91870577487839, 'intersection_point': (960, 962)} +2025-05-22 12:34:34 | DEBUG | utils.log_helper - 🐞 步骤1: 原始图像已加载 +2025-05-22 12:34:35 | DEBUG | utils.log_helper - 🐞 步骤2: 创建黄色掩码 +2025-05-22 12:34:36 | DEBUG | utils.log_helper - 🐞 步骤3: 提取黄色部分 +2025-05-22 12:34:36 | DEBUG | utils.log_helper - 🐞 检测底部和顶部边缘点 +2025-05-22 12:34:37 | DEBUG | utils.log_helper - 🐞 步骤4: 边缘检测 +2025-05-22 12:34:38 | DEBUG | utils.log_helper - 🐞 步骤5: 检测到 11 条直线 +2025-05-22 12:34:39 | DEBUG | utils.log_helper - 🐞 步骤6: 找到 1 条水平线 (下方: 1, 上方: 0) +2025-05-22 12:34:40 | DEBUG | utils.log_helper - 🐞 选择下方水平线 +2025-05-22 12:34:40 | DEBUG | utils.log_helper - 🐞 显示边缘斜率和中线交点 +2025-05-22 12:34:41 | INFO | utils.log_helper - ℹ️ 保存横向边缘检测结果图像到: logs/image/horizontal_edge_20250522_123441_043307.jpg +2025-05-22 12:34:41 | INFO | utils.log_helper - ℹ️ 横向边缘检测结果: {'timestamp': '20250522_123441_043307', 'edge_point': (1439, 899), 'distance_to_center': 479, 'slope': -0.07083333333333333, 'distance_to_bottom': 147.07083333333333, 'intersection_point': (960, 932), 'score': 0.5594172208352652, 'valid': True, 'reason': '', 'is_lower_line': array([ True, True, True, True])} diff --git a/res/path/test-3.jpg b/res/path/test-3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2f55eb2605231f1e157cdacd94b97fd9a6a0ac11 GIT binary patch literal 74782 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 diff --git a/test/task-path-track/yellow_track_demo.py b/test/task-path-track/yellow_track_demo.py index dcc8b2e..88cf740 100644 --- a/test/task-path-track/yellow_track_demo.py +++ b/test/task-path-track/yellow_track_demo.py @@ -9,7 +9,7 @@ current_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(os.path.dirname(current_dir)) sys.path.append(project_root) -from utils.detect_track import detect_horizontal_track_edge +from utils.detect_track import detect_horizontal_track_edge, detect_horizontal_track_edge_v2 def process_image(image_path, save_dir=None, show_steps=False): """处理单张图像""" @@ -17,7 +17,7 @@ def process_image(image_path, save_dir=None, show_steps=False): # 检测赛道并估算距离 start_time = time.time() - edge_point, edge_info = detect_horizontal_track_edge(image_path, observe=show_steps, save_log=True) + edge_point, edge_info = detect_horizontal_track_edge(image_path, observe=show_steps, save_log=True, delay=800) processing_time = time.time() - start_time # 输出结果 @@ -44,8 +44,8 @@ def process_image(image_path, save_dir=None, show_steps=False): def main(): parser = argparse.ArgumentParser(description='黄色赛道检测演示程序') - parser.add_argument('--input', type=str, default='res/path/test-2.jpg', help='输入图像或视频的路径') - parser.add_argument('--output', type=str, default='res/path/test/result_image_20250514_024313.png', help='输出结果的保存路径') + parser.add_argument('--input', type=str, default='res/path/image_20250513_162556.png', help='输入图像或视频的路径') + parser.add_argument('--output', type=str, default='res/path/test/image_20250513_162556.png', help='输出结果的保存路径') parser.add_argument('--type', type=str, choices=['image', 'video'], help='输入类型,不指定会自动检测') parser.add_argument('--show', default=True, action='store_true', help='显示处理步骤') diff --git a/utils/detect_track.py b/utils/detect_track.py index 8ad3bf3..6716732 100644 --- a/utils/detect_track.py +++ b/utils/detect_track.py @@ -6,9 +6,346 @@ from sklearn import linear_model from utils.log_helper import get_logger, debug, info, warning, error, success def detect_horizontal_track_edge(image, observe=False, delay=1000, save_log=True): + """ + 检测正前方横向黄色赛道的边缘,并返回y值最大的边缘点 + # INFO 原来的版本 + + 参数: + image: 输入图像,可以是文件路径或者已加载的图像数组 + observe: 是否输出中间状态信息和可视化结果,默认为False + delay: 展示每个步骤的等待时间(毫秒) + save_log: 是否保存日志和图像 + 返回: + edge_point: 赛道前方边缘点的坐标 (x, y) + edge_info: 边缘信息字典 + """ + # observe = False # TSET + # 如果输入是字符串(文件路径),则加载图像 + if isinstance(image, str): + img = cv2.imread(image) + else: + img = image.copy() + + if img is None: + error("无法加载图像", "失败") + return None, None + + # 获取图像尺寸 + height, width = img.shape[:2] + + # 计算图像中间区域的范围(用于专注于正前方的赛道) + center_x = width // 2 + search_width = int(width * 2/3) # 搜索区域宽度为图像宽度的2/3 + search_height = height # 搜索区域高度为图像高度的1/1 + left_bound = center_x - search_width // 2 + right_bound = center_x + search_width // 2 + bottom_bound = height + top_bound = height - search_height + + if observe: + debug("步骤1: 原始图像已加载", "加载") + search_region_img = img.copy() + # 绘制搜索区域 + cv2.rectangle(search_region_img, (left_bound, top_bound), (right_bound, bottom_bound), (255, 0, 0), 2) + cv2.line(search_region_img, (center_x, 0), (center_x, height), (0, 0, 255), 2) # 中线 + cv2.imshow("搜索区域", search_region_img) + cv2.waitKey(delay) + + # 转换到HSV颜色空间以便更容易提取黄色 + hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + + # 黄色的HSV范围 + lower_yellow = np.array([20, 100, 100]) + upper_yellow = np.array([30, 255, 255]) + + # 创建黄色的掩码 + mask = cv2.inRange(hsv, lower_yellow, upper_yellow) + + # 添加形态学操作以改善掩码 + kernel = np.ones((3, 3), np.uint8) + mask = cv2.dilate(mask, kernel, iterations=1) + + if observe: + debug("步骤2: 创建黄色掩码", "处理") + cv2.imshow("黄色掩码", mask) + cv2.waitKey(delay) + + # 应用掩码,只保留黄色部分 + yellow_only = cv2.bitwise_and(img, img, mask=mask) + + if observe: + debug("步骤3: 提取黄色部分", "处理") + cv2.imshow("只保留黄色", yellow_only) + cv2.waitKey(delay) + + # 裁剪掩码到搜索区域 + search_mask = mask[top_bound:bottom_bound, left_bound:right_bound] + + # 找到掩码在搜索区域中最底部的非零点位置 + bottom_points = [] + non_zero_cols = np.where(np.any(search_mask, axis=0))[0] + + # 寻找每列的最底部点 + for col in non_zero_cols: + col_points = np.where(search_mask[:, col] > 0)[0] + if len(col_points) > 0: + bottom_row = np.max(col_points) + bottom_points.append((left_bound + col, top_bound + bottom_row)) + + if len(bottom_points) < 3: + # 如果找不到足够的底部点,使用canny+霍夫变换 + edges = cv2.Canny(mask, 50, 150, apertureSize=3) + + if observe: + debug("步骤3.1: 边缘检测", "处理") + cv2.imshow("边缘检测", edges) + cv2.waitKey(delay) + + # 使用霍夫变换检测直线 - 调低阈值以检测短线段 + lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=30, + minLineLength=width*0.1, maxLineGap=30) + + if lines is None or len(lines) == 0: + if observe: + error("未检测到直线", "失败") + return None, None + + if observe: + debug(f"步骤4: 检测到 {len(lines)} 条直线", "处理") + lines_img = img.copy() + for line in lines: + x1, y1, x2, y2 = line[0] + cv2.line(lines_img, (x1, y1), (x2, y2), (0, 255, 0), 2) + cv2.imshow("检测到的直线", lines_img) + cv2.waitKey(delay) + + # 筛选水平线,但放宽斜率条件 + horizontal_lines = [] + for line in lines: + x1, y1, x2, y2 = line[0] + + # 计算斜率 (避免除零错误) + if abs(x2 - x1) < 5: # 几乎垂直的线 + continue + + slope = (y2 - y1) / (x2 - x1) + + # 筛选接近水平的线 (斜率接近0),但容许更大的倾斜度 + if abs(slope) < 0.3: + # 确保线在搜索区域内 + if ((left_bound <= x1 <= right_bound and top_bound <= y1 <= bottom_bound) or + (left_bound <= x2 <= right_bound and top_bound <= y2 <= bottom_bound)): + # 计算线的中点y坐标 + mid_y = (y1 + y2) / 2 + line_length = np.sqrt((x2-x1)**2 + (y2-y1)**2) + # 保存线段、其y坐标和长度 + horizontal_lines.append((line[0], mid_y, slope, line_length)) + + if not horizontal_lines: + if observe: + error("未检测到水平线", "失败") + return None, None + + if observe: + debug(f"步骤4.1: 找到 {len(horizontal_lines)} 条水平线", "处理") + h_lines_img = img.copy() + for line_info in horizontal_lines: + line, _, slope, _ = line_info + x1, y1, x2, y2 = line + cv2.line(h_lines_img, (x1, y1), (x2, y2), (0, 255, 255), 2) + # 显示斜率 + cv2.putText(h_lines_img, f"{slope:.2f}", ((x1+x2)//2, (y1+y2)//2), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1) + cv2.imshow("水平线", h_lines_img) + cv2.waitKey(delay) + + # 按y坐标排序 (从大到小,底部的线排在前面) + horizontal_lines.sort(key=lambda x: x[1], reverse=True) + + # 取最靠近底部且足够长的线作为横向赛道线 + selected_line = None + selected_slope = 0 + for line_info in horizontal_lines: + line, _, slope, length = line_info + if length > width * 0.1: # 确保线足够长 + selected_line = line + selected_slope = slope + break + + if selected_line is None and horizontal_lines: + # 如果没有足够长的线,就取最靠近底部的线 + selected_line = horizontal_lines[0][0] + selected_slope = horizontal_lines[0][2] + + if selected_line is None: + if observe: + error("无法选择合适的线段", "失败") + return None, None + + x1, y1, x2, y2 = selected_line + else: + # 使用底部点拟合直线 + if observe: + debug("正在处理底部边缘点", "处理") + bottom_points_img = img.copy() + for point in bottom_points: + cv2.circle(bottom_points_img, point, 3, (0, 255, 0), -1) + cv2.imshow("底部边缘点", bottom_points_img) + cv2.waitKey(delay) + + # 使用RANSAC拟合直线以去除异常值 + x_points = np.array([p[0] for p in bottom_points]).reshape(-1, 1) + y_points = np.array([p[1] for p in bottom_points]) + + # 如果点过少或分布不够宽,返回None + if len(bottom_points) < 3 or np.max(x_points) - np.min(x_points) < width * 0.1: + if observe: + warning("底部点太少或分布不够宽", "警告") + return None, None + + ransac = linear_model.RANSACRegressor(residual_threshold=5.0) + ransac.fit(x_points, y_points) + + # 获取拟合参数 + selected_slope = ransac.estimator_.coef_[0] + intercept = ransac.estimator_.intercept_ + + # 检查斜率是否在合理范围内 + if abs(selected_slope) > 0.3: + if observe: + warning(f"拟合斜率过大: {selected_slope:.4f}", "警告") + return None, None + + # 使用拟合的直线参数计算线段端点 + x1 = left_bound + y1 = int(selected_slope * x1 + intercept) + x2 = right_bound + y2 = int(selected_slope * x2 + intercept) + + if observe: + debug("显示拟合线段", "处理") + fitted_line_img = img.copy() + cv2.line(fitted_line_img, (x1, y1), (x2, y2), (0, 255, 255), 2) + cv2.imshow("拟合线段", fitted_line_img) + cv2.waitKey(delay) + + # 确保x1 < x2 + if x1 > x2: + x1, x2 = x2, x1 + y1, y2 = y2, y1 + + # 找到线上y值最大的点作为边缘点(最靠近相机的点) + if y1 > y2: + bottom_edge_point = (x1, y1) + else: + bottom_edge_point = (x2, y2) + + # 获取线上的更多点 + selected_points = [] + step = 5 # 每5个像素取一个点 + for x in range(max(left_bound, int(min(x1, x2))), min(right_bound, int(max(x1, x2)) + 1), step): + y = int(selected_slope * (x - x1) + y1) + if top_bound <= y <= bottom_bound: + selected_points.append((x, y)) + + if observe: + debug(f"步骤5: 找到边缘点 {bottom_edge_point}", "检测") + edge_img = img.copy() + # 画线 + cv2.line(edge_img, (x1, y1), (x2, y2), (0, 255, 0), 2) + # 绘制所有点 + for point in selected_points: + cv2.circle(edge_img, point, 3, (255, 0, 0), -1) + # 标记边缘点 + cv2.circle(edge_img, bottom_edge_point, 10, (0, 0, 255), -1) + cv2.imshow("选定的横向线和边缘点", edge_img) + cv2.waitKey(delay) + + # 计算这个点到中线的距离 + distance_to_center = bottom_edge_point[0] - center_x + + # 计算中线与检测到的横向线的交点 + # 横向线方程: y = slope * (x - x1) + y1 + # 中线方程: x = center_x + # 解这个方程组得到交点坐标 + intersection_x = center_x + intersection_y = selected_slope * (center_x - x1) + y1 + intersection_point = (int(intersection_x), int(intersection_y)) + + # 计算交点到图像底部的距离(以像素为单位) + distance_to_bottom = height - intersection_y + + result_img = None + if observe or save_log: + slope_img = img.copy() + # 画出检测到的线 + cv2.line(slope_img, (x1, y1), (x2, y2), (0, 255, 0), 2) + # 标记边缘点 + cv2.circle(slope_img, bottom_edge_point, 10, (0, 0, 255), -1) + # 画出中线 + cv2.line(slope_img, (center_x, 0), (center_x, height), (0, 0, 255), 2) + # 标记中线与横向线的交点 + cv2.circle(slope_img, intersection_point, 12, (255, 0, 255), -1) + cv2.circle(slope_img, intersection_point, 5, (255, 255, 255), -1) + # 画出交点到底部的距离线 + cv2.line(slope_img, intersection_point, (intersection_x, height), (255, 255, 0), 2) + + cv2.putText(slope_img, f"Slope: {selected_slope:.4f}", (10, 30), + cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) + cv2.putText(slope_img, f"Distance to center: {distance_to_center}px", (10, 70), + cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) + cv2.putText(slope_img, f"Distance to bottom: {distance_to_bottom:.1f}px", (10, 110), + cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) + cv2.putText(slope_img, f"中线交点: ({intersection_point[0]}, {intersection_point[1]})", (10, 150), + cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) + + if observe: + debug("显示边缘斜率和中线交点", "显示") + cv2.imshow("边缘斜率和中线交点", slope_img) + cv2.waitKey(delay) + + result_img = slope_img + + # 保存日志图像 + if save_log and result_img is not None: + timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S_%f") + log_dir = "logs/image" + os.makedirs(log_dir, exist_ok=True) + img_path = os.path.join(log_dir, f"horizontal_edge_{timestamp}.jpg") + cv2.imwrite(img_path, result_img) + info(f"保存横向边缘检测结果图像到: {img_path}", "日志") + + # 保存文本日志信息 + log_info = { + "timestamp": timestamp, + "edge_point": bottom_edge_point, + "distance_to_center": distance_to_center, + "slope": selected_slope, + "distance_to_bottom": distance_to_bottom, + "intersection_point": intersection_point + } + info(f"横向边缘检测结果: {log_info}", "日志") + + # 创建边缘信息字典 + edge_info = { + "x": bottom_edge_point[0], + "y": bottom_edge_point[1], + "distance_to_center": distance_to_center, + "slope": selected_slope, + "is_horizontal": abs(selected_slope) < 0.05, # 判断边缘是否接近水平 + "points_count": len(selected_points), # 该组中点的数量 + "intersection_point": intersection_point, # 中线与横向线的交点 + "distance_to_bottom": distance_to_bottom, # 交点到图像底部的距离 + # "points": selected_points # 添加选定的点组 + } + + return bottom_edge_point, edge_info + +def detect_horizontal_track_edge_v2(image, observe=False, delay=1000, save_log=True): """ 检测正前方横向黄色赛道的边缘,并返回y值最大的边缘点 优先检测下方横线,但在遇到下方线截断的情况时会考虑上边缘 + 但容易识别到上面的线。 参数: image: 输入图像,可以是文件路径或者已加载的图像数组 @@ -143,6 +480,13 @@ def detect_horizontal_track_edge(image, observe=False, delay=1000, save_log=True # 筛选水平线,但放宽斜率条件 horizontal_lines = [] + # 分别存储上方和下方的水平线 + lower_horizontal_lines = [] + upper_horizontal_lines = [] + + # 定义上下分界线位置 (以图像中部再下移一点作为分界) + lower_upper_boundary = height * 0.65 + for line in lines: x1, y1, x2, y2 = line[0] @@ -176,20 +520,35 @@ def detect_horizontal_track_edge(image, observe=False, delay=1000, save_log=True mid_x = (x1 + x2) / 2 center_score = max(0.0, 1.0 - abs(mid_x - center_x) / (width * 0.3)) - # 计算综合得分 - quality_score = position_score * 0.4 + length_score * 0.3 + slope_score * 0.2 + center_score * 0.1 + # 计算综合得分,增加位置得分的权重,更强调下方线 + quality_score = position_score * 0.6 + length_score * 0.2 + slope_score * 0.15 + center_score * 0.05 # 保存线段、其y坐标、斜率、长度和质量得分 - horizontal_lines.append((line[0], mid_y, slope, line_length, quality_score)) + line_info = (line[0], mid_y, slope, line_length, quality_score) + + # 区分上方和下方的线 + if mid_y >= lower_upper_boundary: + lower_horizontal_lines.append(line_info) + else: + upper_horizontal_lines.append(line_info) + + # 同时保存到总列表中 + horizontal_lines.append(line_info) if not horizontal_lines: if observe: error("未检测到合格的水平线", "失败") return None, None + # 根据质量得分排序上方和下方的水平线 + lower_horizontal_lines.sort(key=lambda x: x[4], reverse=True) + upper_horizontal_lines.sort(key=lambda x: x[4], reverse=True) + if observe: - debug(f"步骤6: 找到 {len(horizontal_lines)} 条水平线", "处理") + debug(f"步骤6: 找到 {len(horizontal_lines)} 条水平线 (下方: {len(lower_horizontal_lines)}, 上方: {len(upper_horizontal_lines)})", "处理") h_lines_img = img.copy() + + # 绘制所有水平线 for line_info in horizontal_lines: line, _, slope, _, score = line_info x1, y1, x2, y2 = line @@ -199,16 +558,30 @@ def detect_horizontal_track_edge(image, observe=False, delay=1000, save_log=True # 显示斜率和得分 cv2.putText(h_lines_img, f"{slope:.2f}|{score:.2f}", ((x1+x2)//2, (y1+y2)//2), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1) + + # 绘制上下分界线 + cv2.line(h_lines_img, (0, int(lower_upper_boundary)), (width, int(lower_upper_boundary)), (255, 0, 255), 1) cv2.imshow("水平线", h_lines_img) cv2.waitKey(delay) - # 根据质量得分排序水平线 - horizontal_lines.sort(key=lambda x: x[4], reverse=True) - - # 取质量最高的线段作为最终选择 - selected_line = horizontal_lines[0][0] - selected_slope = horizontal_lines[0][2] - selected_score = horizontal_lines[0][4] + # 优先选择下方的线,如果没有下方的线才考虑上方的线 + if lower_horizontal_lines: + selected_line = lower_horizontal_lines[0][0] + selected_slope = lower_horizontal_lines[0][2] + selected_score = lower_horizontal_lines[0][4] + if observe: + debug("选择下方水平线", "处理") + elif upper_horizontal_lines: + selected_line = upper_horizontal_lines[0][0] + selected_slope = upper_horizontal_lines[0][2] + selected_score = upper_horizontal_lines[0][4] + if observe: + debug("没有合适的下方线,选择上方水平线", "处理") + else: + # 理论上不会进入这个分支,因为前面已经检查过horizontal_lines非空 + if observe: + error("未检测到合格的水平线", "失败") + return None, None # 提取线段端点 x1, y1, x2, y2 = selected_line @@ -348,6 +721,8 @@ def detect_horizontal_track_edge(image, observe=False, delay=1000, save_log=True cv2.circle(slope_img, intersection_point, 5, (255, 255, 255), -1) # 画出交点到底部的距离线 cv2.line(slope_img, intersection_point, (intersection_x, height), (255, 255, 0), 2) + # 画出上下分界线 + cv2.line(slope_img, (0, int(lower_upper_boundary)), (width, int(lower_upper_boundary)), (255, 0, 255), 1) cv2.putText(slope_img, f"Slope: {selected_slope:.4f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, line_color, 2) @@ -390,7 +765,8 @@ def detect_horizontal_track_edge(image, observe=False, delay=1000, save_log=True "intersection_point": intersection_point, "score": selected_score, "valid": valid_result, - "reason": reason if not valid_result else "" + "reason": reason if not valid_result else "", + "is_lower_line": len(lower_horizontal_lines) > 0 and selected_line == lower_horizontal_lines[0][0] } info(f"横向边缘检测结果: {log_info}", "日志") @@ -409,15 +785,12 @@ def detect_horizontal_track_edge(image, observe=False, delay=1000, save_log=True "intersection_point": intersection_point, # 中线与横向线的交点 "distance_to_bottom": distance_to_bottom, # 交点到图像底部的距离 "score": selected_score, # 线段质量得分 + "is_lower_line": len(lower_horizontal_lines) > 0 and selected_line == lower_horizontal_lines[0][0] # 是否为下方线 # "points": selected_points # 添加选定的点组 } return bottom_edge_point, edge_info -# 用法示例 -if __name__ == "__main__": - pass - def detect_dual_track_lines(image, observe=False, delay=1000, save_log=True): """ 检测左右两条平行的黄色轨道线