删除视频处理功能,简化图像处理逻辑,更新横向赛道边缘检测相关函数,移除可视化功能,增强错误处理信息。

This commit is contained in:
Havoc 2025-05-14 14:16:50 +08:00
parent f2298f4085
commit ec7acc64ff
2 changed files with 3 additions and 255 deletions

View File

@ -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()

View File

@ -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__":
# 替换为实际图像路径