From ec7acc64ff0febb1a791e2972798a01ca681a716 Mon Sep 17 00:00:00 2001 From: Havoc <2993167370@qq.com> Date: Wed, 14 May 2025 14:16:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=A7=86=E9=A2=91=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=8A=9F=E8=83=BD=EF=BC=8C=E7=AE=80=E5=8C=96=E5=9B=BE?= =?UTF-8?q?=E5=83=8F=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=A8=AA=E5=90=91=E8=B5=9B=E9=81=93=E8=BE=B9=E7=BC=98?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E7=9B=B8=E5=85=B3=E5=87=BD=E6=95=B0=EF=BC=8C?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=8F=AF=E8=A7=86=E5=8C=96=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=BC=BA=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/task-path-track/yellow_track_demo.py | 105 +-------------- utils/detect_track.py | 153 ---------------------- 2 files changed, 3 insertions(+), 255 deletions(-) diff --git a/test/task-path-track/yellow_track_demo.py b/test/task-path-track/yellow_track_demo.py index 6e27a57..82c30dc 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_yellow_track, visualize_track_detection, detect_horizontal_track_edge, visualize_horizontal_track_edge +from utils.detect_track import detect_horizontal_track_edge def process_image(image_path, save_dir=None, show_steps=False): """处理单张图像""" @@ -37,110 +37,11 @@ def process_image(image_path, save_dir=None, show_steps=False): if save_dir: if not os.path.exists(save_dir): os.makedirs(save_dir) - - base_name = os.path.basename(image_path) - save_path = os.path.join(save_dir, f"result_{base_name}") - - # 可视化并保存 - visualize_horizontal_track_edge(image_path, save_path=save_path, observe=show_steps) - print(f"结果已保存到: {save_path}") else: print("未能检测到黄色赛道") return edge_point, edge_info -def process_video(video_path, save_path=None, show_output=True): - """处理视频""" - print(f"处理视频: {video_path}") - - # 打开视频文件 - cap = cv2.VideoCapture(video_path) - if not cap.isOpened(): - print("无法打开视频文件") - return - - # 获取视频基本信息 - fps = cap.get(cv2.CAP_PROP_FPS) - width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) - height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) - total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) - - print(f"视频信息: {width}x{height}, {fps} FPS, 总帧数: {total_frames}") - - # 如果需要保存,创建VideoWriter - if save_path: - fourcc = cv2.VideoWriter_fourcc(*'XVID') - out = cv2.VideoWriter(save_path, fourcc, fps, (width, height)) - - # 处理计数器 - frame_count = 0 - processed_count = 0 - start_time = time.time() - - while True: - ret, frame = cap.read() - if not ret: - break - - frame_count += 1 - - # 每5帧处理一次以提高性能 - if frame_count % 5 == 0: - processed_count += 1 - - # 检测赛道 - edge_point, edge_info = detect_horizontal_track_edge(frame, observe=False) - - # 创建结果图像(使用visualize_horizontal_track_edge函数) - if edge_point is not None and edge_info is not None: - result_frame = visualize_horizontal_track_edge(frame, observe=False) - else: - # 如果未检测到赛道,显示原始帧并添加警告 - result_frame = frame.copy() - cv2.putText(result_frame, "未检测到横向赛道", (width//4, height//2), - cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 2) - - # 添加帧计数 - cv2.putText(result_frame, f"帧: {frame_count}/{total_frames}", - (width - 200, height - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1) - - # 保存或显示结果 - if save_path: - out.write(result_frame) - - if show_output: - # 将交点信息显示在窗口标题上 - if edge_point is not None and edge_info is not None: - intersection_point = edge_info['intersection_point'] - distance_to_bottom = edge_info['distance_to_bottom'] - title = f'赛道检测 - 交点:({intersection_point[0]},{intersection_point[1]}) 底距:{distance_to_bottom:.1f}px' - else: - title = '赛道检测 - 未检测到交点' - - cv2.imshow(title, result_frame) - key = cv2.waitKey(1) & 0xFF - if key == 27: # ESC键退出 - break - - # 每秒更新一次处理进度 - if frame_count % int(fps) == 0: - elapsed = time.time() - start_time - percent = frame_count / total_frames * 100 - print(f"进度: {percent:.1f}% ({frame_count}/{total_frames}), 已用时间: {elapsed:.1f}秒") - - # 清理 - cap.release() - if save_path: - out.release() - cv2.destroyAllWindows() - - # 输出统计信息 - total_time = time.time() - start_time - print(f"视频处理完成,总时间: {total_time:.2f}秒") - print(f"实际处理帧数: {processed_count}/{frame_count}") - if processed_count > 0: - print(f"平均每帧处理时间: {total_time/processed_count:.3f}秒") - def main(): parser = argparse.ArgumentParser(description='黄色赛道检测演示程序') parser.add_argument('--input', type=str, default='res/path/image_20250513_162556.png', help='输入图像或视频的路径') @@ -171,8 +72,8 @@ def main(): # 获取输出目录 output_dir = os.path.dirname(args.output) process_image(args.input, output_dir, args.show) - else: # video - process_video(args.input, args.output, args.show) + else: + print("错误:不支持的视频类型") if __name__ == "__main__": main() \ No newline at end of file diff --git a/utils/detect_track.py b/utils/detect_track.py index 5ae4456..6e280ac 100644 --- a/utils/detect_track.py +++ b/utils/detect_track.py @@ -999,159 +999,6 @@ def detect_horizontal_track_edge(image, observe=False, delay=1000): return bottom_edge_point, edge_info -def visualize_horizontal_track_edge(image, save_path=None, observe=False, delay=500): - """ - 可视化横向赛道边缘检测过程,显示中间结果和最终分析 - - 参数: - image: 输入图像,可以是文件路径或者已加载的图像数组 - save_path: 保存结果图像的路径(可选) - observe: 是否输出中间状态信息和可视化结果,默认为False - delay: 展示每个步骤的等待时间(毫秒),默认为500ms - """ - # 如果输入是字符串(文件路径),则加载图像 - if isinstance(image, str): - img = cv2.imread(image) - else: - img = image.copy() - - if img is None: - print("无法加载图像") - return - - # 获取图像尺寸 - height, width = img.shape[:2] - - # 创建输出图像 - output = img.copy() - - # 执行横向赛道检测 - edge_point, edge_info = detect_horizontal_track_edge(img, observe=False) - - # 如果成功检测到边缘 - if edge_point is not None and edge_info is not None: - # 获取信息 - center_x = width // 2 - - # 绘制中线 - cv2.line(output, (center_x, 0), (center_x, height), (0, 0, 255), 2) - - # 获取关键信息 - selected_slope = edge_info['slope'] - distance_to_center = edge_info['distance_to_center'] - intersection_point = edge_info['intersection_point'] - distance_to_bottom = edge_info['distance_to_bottom'] - is_horizontal = edge_info['is_horizontal'] - - # 绘制检测到的点,兼容旧版本的edge_info字典 - if 'points' in edge_info and edge_info['points']: - for point in edge_info['points']: - cv2.circle(output, point, 3, (0, 255, 0), -1) - - # 标记边缘点 - cv2.circle(output, edge_point, 10, (0, 0, 255), -1) - - # 使用斜率画一条线来表示边缘方向 - line_length = 200 - end_x = edge_point[0] + line_length - end_y = int(edge_point[1] + selected_slope * line_length) - start_x = edge_point[0] - line_length - start_y = int(edge_point[1] - selected_slope * line_length) - cv2.line(output, (start_x, start_y), (end_x, end_y), (0, 255, 0), 2) - - # 标记中线与横向线的交点 (高亮显示) - cv2.circle(output, intersection_point, 12, (255, 0, 255), -1) - cv2.circle(output, intersection_point, 5, (255, 255, 255), -1) - - # 画出交点到底部的距离线 - cv2.line(output, intersection_point, (intersection_point[0], height), (255, 255, 0), 2) - - # 添加信息文本 - cv2.putText(output, f"边缘点: ({edge_point[0]}, {edge_point[1]})", (10, 30), - cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) - cv2.putText(output, f"到中线距离: {distance_to_center}像素", (10, 60), - cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) - cv2.putText(output, f"斜率: {selected_slope:.4f}", (10, 90), - cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) - cv2.putText(output, f"是否水平: {is_horizontal}", (10, 120), - cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) - cv2.putText(output, f"点数量: {edge_info['points_count']}", (10, 150), - cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) - cv2.putText(output, f"到底部距离: {distance_to_bottom:.1f}像素", (10, 180), - 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), - cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 2) - - # 如果提供了保存路径,保存结果图像 - if save_path: - cv2.imwrite(save_path, output) - if observe: - print(f"结果已保存到: {save_path}") - - # 显示结果 - if observe: - # 转换到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((5, 5), np.uint8) - mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) - mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) - - # 应用掩码,只保留黄色部分 - yellow_only = cv2.bitwise_and(img, img, mask=mask) - - # 创建包含所有处理步骤的结果图像 - result = np.hstack((img, yellow_only, output)) - - # 调整大小以便查看 - scale_percent = 50 # 缩放到原来的50% - width = int(result.shape[1] * scale_percent / 100) - height = int(result.shape[0] * scale_percent / 100) - dim = (width, height) - resized = cv2.resize(result, dim, interpolation=cv2.INTER_AREA) - - # 显示结果 - cv2.imshow('横向赛道边缘检测', resized) - cv2.waitKey(delay) - if save_path is None: # 如果没有保存,则等待按键 - cv2.waitKey(0) - cv2.destroyAllWindows() - - return output - # 用法示例 if __name__ == "__main__": # 替换为实际图像路径